对数组名取地址赋值给数组指针与普通指针的区别
对数组名取地址赋值给数组指针与普通指针的区别:
以下红色字体的说法是错误的:
使用一级指针来接受&arr,只是表示一个普通的一级指针,
它并没有接收到&arr赋来的跨度,而只接收到了地址而已。所以,
p1的跨度只有4个字节。它保存的地址所表示的是arr这个数组的首元素地址
相当于在赋值过程中,&arr退化为了arr,失去了数组本来拥有的跨度。
此时p1[i],就是在对数组中的每一个数组元素做遍历了。
p保存的是数组的地址&arr
*p保存的是数组首元素的地址:*&arr —-> arr
同理,以下红色字体的说法同样不正确:
p2此时的地址已经为arr,*p2就是数组元素的值了。
而二级指针的特点就是在于它保存的是一级指针的地址,即它的内容就是一级指针的地址。
*p2就是这个一级指针的地址。
*(*p2)则为对元素的值取地址,因为数组元素的值是手动赋值的,
那么**p此时就是对野指针的非法操作了。
p为&arr首地址
*p为arr首元素地址
**p为数组元素内容
综上:一维数组名对应一级指针,二维数组名对应二级指针,n维数组名对应n级指针。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char *argv[])
{
int arr[5] = {1, 2, 3, 4, 5};
/*一下的说法是错误的:
数组指针才是将地址连同&arr这个地址的跨度一起赋给了指针变量;
而是用普通的一级指针来接受的&arr,只是表示一个普通的一级指针,
它并没有接收到&arr赋来的跨度,而只接收到了地址而已。所以,
p1的跨度只有4个字节。它保存的地址所表示的是arr这个数组的首元素地址
相当于在赋值过程中,&arr退化为了arr,失去了数组本来拥有的跨度。
此时p1[i],就是在对数组中的每一个数组元素做遍历了。
*/
//p保存的是数组的地址&arr
//*p保存的是数组首元素的地址:*&arr ---> arr
int *p1 = &arr; //其实此处不需要取地址,将二级指针赋值给一级指针会有警告。
for (int i = 0; i < 5; i++)
{
printf("%d\n", p1[i]);
}
printf("------------------------------\n");
//*的优先级为2级,[]、()的优先级为1级
//p2的内容是&arr
//*p2的内容是*&arr ---> arr,即数组的首元素地址
//
int (*p2)[5] = &arr;
for (int i = 0; i < 5; i++)
{
printf("%d\n", (*p2)[i]);
}
printf("------------------------------\n");
/*同理,以下的说法同样不正确:
p2此时的地址已经为arr,*p2就是数组元素的值了。
而二级指针的特点就是在于它保存的是一级指针的地址,即它的内容就是一级指针的地址。
*p2就是这个一级指针的地址。
*(*p2)则为对元素的值取地址,因为数组元素的值是手动赋值的,
那么**p此时就是对野指针的非法操作了。
*/
//p为&arr首地址
//*p为arr首元素地址
//**p为数组元素内容
int **p = &arr;
for (int i = 0; i < 5; i++)
{
printf("%d\n", p[i]);
}
system("pause");
return 0;
}
还没有评论,来说两句吧...