注册 登录
编程论坛 C语言论坛

C语言萌新,关于数组的问题想请教一下

zh0u 发布于 2023-04-13 08:45, 225 次点击
定义了一个整型数组arr
int arr[] = {1,2,3,4,5};
sizeof(arr); // 4 * 5B
printf("%p", arr); // 对应第一个元素 1 的内存地址
printf("%p", arr + 1); // 对应第二个元素 2 的内存地址
所以为什么 arr + 1 的地址是第二个元素的内存地址呢?
而在定义arr的这个作用域内使用sizeof是能正常获取arr的长度,假设作为参数传给某个函数形参接收时,sizeof(形参)得到的又是指针的大小,不太能理解
3 回复
#2
rjsp2023-04-13 10:27
你是不是看漏了&号,导致你把 &arr 和 arr 混淆了?

int a;
sizeof(a); // 4bytes (当然不一定是4字节,但这与本话题无关)
printf("%p",&a); // 对应a的地址
printf("%p",&a + 1); // 对应a下一个变量的地址(a下一个变量 可以不存在,但取其地址是良好定义行为,而对 a下一个变量的下一个变量 取值则是未定义行为,即 &a+2 属于未定义行为,当然这与本话题无关)

仿造上面的代码,你应该写出
int arr[] = {1,2,3,4,5};
sizeof(arr); // 4 * 5B
printf("%p", &arr);
printf("%p", &arr + 1);
亦即,你提供的证据 与 你的疑问 不构成联系。

而 printf("%p", arr); printf("%p", arr + 1) 之所以合法则是因为C语言规定「数组可以隐式地转化成指针」
亦即 printf("%p", arr); 等同于 printf("%p", &arr[0] );
printf("%p", arr+1); 等同于 printf("%p", &arr[0] + 1 );

假设作为参数传给某个函数形参接收时,sizeof(形参)得到的又是指针的大小,
因为数组不可拷贝,即
int a[3] = { 0, 1, 2 };
int b[3] = a; 是不合法的!
对于函数 void foo( int a[3] ) 而言,你怎么传参数给它?
所以这是C语言规定「数组可以隐式地转化成指针」的原因,亦即void foo( int a[3] ) 等同于 void foo( int a[4] ) 等同于 void foo( int* a ) 等同于 ……,本质上都是 void foo( int* a )
#3
rjsp2023-04-13 10:35
C语言标准中其实直接规定的是 *(a+i) 等同于 a[i]
#4
zh0u2023-04-13 13:47
回复 2楼 rjsp
明白了,谢谢!
1