C语言进阶剖析 27 数组的本质分析

数组的概念

  • 数组是相同类型变量的有序
    在这里插入图片描述

数组的大小

  • 数组在一片连续的内存空间中存储数据
  • 数组元素的个数可以显示或隐式指定
    int a[5] = {1, 2};
    int b[] = {1, 2};

问题:

a[2], a[3], a[4] 的值是多少呢?
b 包含了多少个元素?

编程实验: 数组的初始化

#include <stdio.h>

int main()
{
    int a[5] = {1, 2};
    int b[] = {1, 2};
    
    printf("a[2] = %d\n", a[2]);
    printf("a[2] = %d\n", a[3]);
    printf("a[2] = %d\n", a[4]);
    
    printf("sizeof(a) = %d\n", sizeof(a));
    printf("sizeof(b) = %d\n", sizeof(b));
    printf("count for a: %d\n", sizeof(a)/sizeof(*a));  // sizeof(*a) ==> sizeof(a[0]) ==> sizeof(int)
    printf("count for b: %d\n", sizeof(b)/sizeof(*b));  // sizeof(*b) ==> sizeof(b[0]) ==> sizeof(int)
    
    return 0;
}
输出:
a[2] = 0
a[2] = 0
a[2] = 0
sizeof(a) = 20
sizeof(b) = 8
count for a: 5
count for b: 2

数组地址与数组名

  • 数组名代表数组首元素的地址
  • 数组的地址需要用取地址符 & 才能得到
  • 数组首元素的地址与数组的地址值相同
  • 数组首元素的地址与数组的地址是两个不同的概念

编程实验: 数组名和数组地址

#include <stdio.h>

int main()
{
    int a[5] = { 0 };
    
    printf("a = %p\n", a);
    printf("&a = %p\n", &a);
    printf("&a[0] = %p\n", &a[0]);
    
    printf("\n");
    
    printf("sizeof(a) = %d\n", sizeof(a));
    printf("sizeof(a[0]) = %d\n", sizeof(a[0]));
	return 0;
}
输出:
a = 0xbf8bb66c
&a = 0xbf8bb66c
&a[0] = 0xbf8bb66c

sizeof(a) = 20
sizeof(a[0]) = 4

■ 地址实质有两个含义: 起始地址, 所占长度

数组a起始地址地址: &a 数组a长度: sizeof(a) = 20
数组a[0]起始地址地址: &a[0] 数组a[0]长度: sizeof(a[0]) = 4

数组名的盲点

  • 数组名可以看作一个常量指针
  • 数组名”指向“的是内存中数组首元素的起始地址
  • 数组名不包含数组的长度信息
  • 在表达式中数组名只能作为右值使用
  • 只有在下列场合中数组名不能看作常量指针
        ○ 数组名作为 sizeof 操作符的参数
        ○ 数组名作为 & 运算符的参数

实例分析: 数组和指针并不相同

#include <stdio.h>

int main()
{
    int a[5] = {0};
    int b[2];
    int* p = NULL;
    
    p = a;
    
    printf("a = %p\n", a);
    printf("p = %p\n", p);
    printf("&p = %p\n", &p);
    printf("sizeof(a) = %d\n", sizeof(a));
    printf("sizeof(p) = %d\n", sizeof(p));
    
    p = b;
    
    printf("b = %p\n", b);
    printf("p = %p\n", p);
    printf("&p = %p\n", &p);
    printf("sizeof(b) = %d\n", sizeof(b));
    printf("sizeof(p) = %d\n", sizeof(p));
}
输出:
a = 0xbf8aebe0
p = 0xbf8aebe0
&p = 0xbf8aebfc
sizeof(a) = 20
sizeof(p) = 4
b = 0xbf8aebf4
p = 0xbf8aebf4
&p = 0xbf8aebfc
sizeof(b) = 8
sizeof(p) = 4


小结

  • 数组是一片连续的内存空间
  • 数组的地址和数组首元素的地址值相等,但意义不同
  • 数组名在大多数情况下被当成常量指针处理
  • 数组名其实不是指针,不能将其等同于指针
发布了334 篇原创文章 · 获赞 661 · 访问量 130万+

猜你喜欢

转载自blog.csdn.net/czg13548930186/article/details/87024445
今日推荐