指针案列详解

要领

1.sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小
2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
3. 除此之外所有的数组名都表示首元素的地址。

目录

1、一维数组

2、二维数组

3、字符数组

4、字符串数组

5、指针数组

1、一维数组

指出下列具体含义
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));

这里a是代表整个数组,计算数组总大小,int类型,所以是16个字节


printf("%d\n",sizeof(a+0));

a并非单独放在sizeof内部,也没有&,所以数组名a就是数组首元素的地址,这里a+0是表示首元素地址,地址就是4/8个字节(X86是4个字节,X64是8个字节)


printf("%d\n",sizeof(*a));

a是首元素的地址,*a就是首元素,sizeof(*a)就算的就是首元素的大小  ——  4


printf("%d\n",sizeof(a+1));

a是首元素的地址,a+1是第二个元素的地址,sizeof(a+1)计算的是指针的大小—— 4/8


printf("%d\n",sizeof(a[1]));

a[1]  相当于 *(a+1) ,就是数组的第二个元素,sizeof(a[1])的大小 -—— 4个字节


printf("%d\n",sizeof(&a));

正是特例之一,&a取出的数组的地址,数组的地址,也是地址,sizeof(&a)就是   4/8 个字节


printf("%d\n",sizeof(*&a));

*解引用与&取地址相互抵消,就是访问整个数组, sizeof(*&a) ==> sizeof(a)  =16

只能*&抵消不能&*抵消


printf("%d\n",sizeof(&a+1));

&a数组的地址,&a+1跳过整个数组,&a+1还是地址,是 4/8 个字节


printf("%d\n",sizeof(&a[0]));

a[0]是数组的第一个元素,&a[0]是第一个元素的地址,是 4/8 个字节


printf("%d\n",sizeof(&a[0]+1));

a[0]是数组的第一个元素,&a[0]+1是第二个元素的地址,是 4/8 个字节

2、二维数组

int a[3][4] = {0};
printf("%d\n",sizeof(a));

a是二维数组的数组名,数组名单独放在sizeof内部,计算的是数组的总大小,单位是字节——48


printf("%d\n",sizeof(a[0][0]));

a[0][0]是一个整型元素,大小是4个字节,  a[0][0]  ==> *(*(a+0)+0)


printf("%d\n",sizeof(a[0]));

这是代表第零行,这一行有四列,所以是16字节


printf("%d\n",sizeof(a[0]+1));

a[0]虽然是第一行的数组名,但是并非单独放在sizeof内部
a[0]作为第一行的数组名并非表示整个第一行这个数组,a[0]就是第一行首元素的地址

a[0]--> &a[0][0] 
a[0]+1,跳过一个int,是a[0][1]的地址  4/8字节


printf("%d\n",sizeof(*(a[0]+1)));

*(*(a+0)+1)==>   a[0][1],第一行的第二个元素,4个字节


printf("%d\n",sizeof(a+1));

a是二维数组的数组名,没单独放在sizeof内部,也没有&,所以a就是数组首元素的地址

二维数组,我们把它想象成一维数组,它的第一个元素就是二维数组的第一行

a就是第一行的地址,a+1 是第二行的地址,是地址,大小就是 4/8 个字节

eg: a ==>  &a[0]        a+1  ==>  &a[1]      a+2  ==>  &a[2]


 printf("%d\n",sizeof(*(a+1)));

a+1就是第二行的地址,*(a + 1)找到的就是第二行, sizeof(*(a + 1))计算的就是第二行的大小16个字节


printf("%d\n",sizeof(&a[0]+1));

&a[0]这是第一行地址,&a[0]+1就是第二行地址,是地址就是4/8字节


printf("%d\n",sizeof  (*(&a[0]+1)));

由上面一个知,里面的是第二行的地址,*(&a[0]+1))则是找到第二行,sizeof(*(a + 1))计算的就是第二行的大小16个字节


printf("%d\n",sizeof(*a));

a是二维数组的数组名,没单独放在sizeof内部,也没有&,所以a就是数组首元素的地址,就是第一行的地址 - &a[0]   ==》  &*(a+0)

*a - > *(a+0) - > a[0]


printf("%d\n",sizeof(a[3]));

任何一个表达式有2个属性
3+5
值属性:8
类型属性:int

a[3]是二维数组的第4行,虽然没有第四行,但是类型能够确定,大小就是确定的。大小就是一行的大小,单位是字节 - 16, 能够分析出 a[3]的类型是:int [4]

3、字符数组

char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));

arr代表整个数组,arr是数组名,并且是单独放在sizeof内部,计算的是数组总大小,单位是字节 - 类型是char 所以共6个字节


printf("%d\n", sizeof(arr+0));

arr是数组名,并非单独放在sizeof内部,这里代表首元素地址,地址大小为4/8字节


printf("%d\n", sizeof(*arr));

arr是首元素的地址,*arr就是首元素,sizeof计算的是首元素的大小,是1字节


printf("%d\n", sizeof(arr[1]));

arr[1]表示第二个元素,所以字节为1


printf("%d\n", sizeof(&arr));

表示整个数组地址,地址就是4/8字节


printf("%d\n", sizeof(&arr+1));

&arr是数组的地址,&arr+1跳过整个数组,指向'f'的后边,&arr+1的本质还是地址,是地址就是4/8


printf("%d\n", sizeof(&arr[0]+1));

&arr[0]是‘a’的地址,&arr[0]+1是'b'的地址,是地址就是4/8字节


printf("%d\n", strlen(arr));

取的是随机值,arr是数组名,但是没有放在sizeof内部,也没&,arr就是首元素的地址

strlen得到arr后,从arr数组首元素的地方开始计算字符串的长度,直到直到\0(strlen是要访问到\0才会停止计数)但是arr数组中没有\0,arr内存的后边是否有\0,在什么位置是不确定的,所以\0之前出现了多少个字符是随机的。


printf("%d\n", strlen(arr+0));

arr代表首元素地址,arr+0表示第一个元素的地址,切不可以为这里地址就是4/8字节,这里是strlen不是sizeof,要去访问到\0才停止


printf("%d\n", strlen(*arr));

arr是数组首元素的地址,*arr 是首元素 - ‘a’ - 97,strlen就把‘a’的ASCII码值 97 当成了地址,err 会非法访问内存


printf("%d\n", strlen(arr[1]));

arr[1] - 'b' - 98 - err


printf("%d\n", strlen(&arr));

随机值,&arr是数组的地址,数组的地址也是指向数组起始位置


printf("%d\n", strlen(&arr+1));

随机值


printf("%d\n", strlen(&arr[0]+1));

随机值

4、字符串数组

char arr[] = "abcdef";
printf("%d\n", sizeof(arr));

arr单独放在sizeof里代表整个数组,7个字节(别忘了还有\0)


printf("%d\n", sizeof(arr+0));

arr不是在sizeof里单独存在所以是首元素地址,这里表示'a'的地址,4/8字节


printf("%d\n", sizeof(*arr));

arr不是在sizeof里单独存在所以是首元素地址,取星找到首地址的元素’a‘,所以1字节


printf("%d\n", sizeof(arr[1]));

*(a+1)表示找到第二个元素'b',所以是一字节


printf("%d\n", sizeof(&arr));

&a表示得到整个数组的地址,也是地址,4/8字节


printf("%d\n", sizeof(&arr+1));

得到整个数组地址,&arr+1跳过这个数组,是地址所以是4/8字节


printf("%d\n", sizeof(&arr[0]+1));

表示第二个元素地址,是地址就是4/8字节


printf("%d\n", strlen(arr));

这可不是随机值,有\0,所以是6字节


printf("%d\n", strlen(arr+0));

表示首地址元素,所以从首元素开始访问,6个字节


printf("%d\n", strlen(*arr));

arr是数组首元素的地址,*arr 是首元素 - ‘a’ - 97,strlen就把‘a’的ASCII码值 97 当成了地址,err 会非法访问内存


printf("%d\n", strlen(arr[1]));

arr[1] ==>  *(arr+1)  所以找到第二个元素的值,err


printf("%d\n", strlen(&arr));

&arr表示整个数组的地址,数组的地址也是指向数组起始位置,所以是6字节


printf("%d\n", strlen(&arr+1));

&arr表示整个数组的地址,&arr+1表示跳过整个数组,所以什么时候会遇见\0无从而知,所以是随机值


printf("%d\n", strlen(&arr[0]+1));

从第二个元素开始访问,到\0结束,所以是5个字节

5、指针数组

char *p = "abcdef";
printf("%d\n", sizeof(p));

p是指针变量,用来存放地址,地址在X86下是4个字节,在X64下是8个字节   4/8

 


printf("%d\n", sizeof(p+1));

由第一个知这也是个地址,p+1就是第二个元素的地址,是地址就是4/8字节


printf("%d\n", sizeof(*p));

是char*类型,解引用也只能得到一个字节


printf("%d\n", sizeof(p[0]));

p[0]  ==>  *(p+0)  代表找到第一个元素,char类型下一个元素是1个字节


printf("%d\n", sizeof(&p));

取p变量的地址,是地址,就是4/8字节


printf("%d\n", sizeof(&p+1));

&p+1地址如下,再怎么说也是地址,所以是4/8字节


printf("%d\n", sizeof(&p[0]+1));

表示第二个元素的地址,地址大小为4/8字节


printf("%d\n", strlen(p));

单独放置,没有sizeof,所以代表的是首元素地址,所以是6字节


printf("%d\n", strlen(p+1));

表示第二个元素地址开始访问,所以是5字节


printf("%d\n", strlen(*p));

p是数组第一个元素地址,解引用后就找到了里面的'a',所以得到了97,非法访问err


printf("%d\n", strlen(p[0]));

p[0] ==> *(p+0)  所以其实就是*p,还是err


printf("%d\n", strlen(&p));

变量P是指针变量,取指针变量的地址,这个地址里面不知道什么时候会出现\0,所以是随机值


printf("%d\n", strlen(&p+1));

同上也是随机值,&p+1也不知道什么时候会出现\0

 


printf("%d\n", strlen(&p[0]+1));

从第二个元素开始访问,所以是5字节


总结

1.sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小
2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
3. 除此之外所有的数组名都表示首元素的地址。


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值