扑朔迷离的C语言指针,一篇就能搞懂

目录

 

前言

一、一维数组

 二、字符数组

1.以下运行结果是

什么呢?

2.在看一个孪生姐妹,猜一猜运行结果是多少 

3.还有一个,再对比分析一下

二、二维数组

总结


前言

这里是参考b站鹏哥C语言讲解,要是我写的不明白,大家可以去看看视频


一、一维数组

1.先自己算下以下结果

int a[] = {1,2,3,4};

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

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

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

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

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

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

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

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

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

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

 详细解答如下图所示:

tips:

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

 二、字符数组

1.以下运行结果是

  简单说一下:

char arr[] = { 'a','b','c','d','e','f' }以这种形式表示,说明里面是什么就是什么,没看见\0就没有\0,
所以,sizeof(arr) 数组大小是6
sizeof(arr + 0)       +0,首元素地址大小4/8,32位平台下为4
sizeof(*arr)           地址解引用表示首元素,所以为1
sizeof(arr[1])         表示b的大小,1
sizeof(&arr)           & arr表示地址的大小,为4/8,sizeof(&arr+1)& arr + 1也是地址,4/8
sizeof(&arr[0] + 1)),  & arr[0] + 1相当于int*,表示b的地址,为4/8

strlen(arr)要见到\0才会停下来,这里面没有\0,所以是一个随机值
strlen(arr + 0),从首地址开始计算字符串长度,还是随机值
strlen()函数里是int strlen(const char* str),也就是传的是地址,strlen(*arr)中 * arr进行了解引用,出错,error,算不出来
同理,strlen(arr[1])也出错,error,算不出来

先看下一个理解最后3个的辅助图


strlen(&arr), & arr==char(*)[6],随机值
strlen(&arr + 1), 随机值-6
strlen(&arr[0] + 1) 随机值 - 1

2.在看一个孪生姐妹,猜一猜运行结果是多少 

解释以下:
/*  char arr[] = "abcdef",这样写,里面是含有\0的,
    即是[a b c d e f \0],
    sizeof(arr)  为7
    sizeof(arr + 0)  4/8  表示首元素地址,地址大小不就是4/8
    sizeof(*arr)    1   首元素地址解引用,是a
    sizeof(arr[1])  1    是b
    sizeof(&arr)  4/8   相当于char(*)[7],到底是个放地址的指针
    sizeof(&arr + 1)  4/8  
    sizeof(&arr[0] + 1)  4/8  
   */

   /*
    strlen(arr)  6
    strlen(arr + 0) 6
    strlen(*arr)  error
    strlen(arr[1]) error,传的参数出错
    strlen(&arr)   6
    strlen(&arr + 1)  随机值,与上一个关系应该是-6,下一个我不知道会在哪遇到\0
    strlen(&arr[0] + 1)  5
    */  

3.还有一个,再对比分析一下

解惑大师来了:

/*
    在内存中是这么存储的a b c d e f \0
    sizeof(p)  p是指针呀,指针大小4/8
    sizeof(p + 1)  指向的是b,还是指针,4/8
    sizeof(*p)   对指针首元素进行解引用,1
    sizeof(p[0])  p[0]  -->*(p+0),不还是个1
    sizeof(&p)   4/8 二级指针
    sizeof(&p + 1)  4/8
    sizeof(&p[0] + 1)  4/8
    */

/*
    strlen(p)  6
    strlen(p + 1)  元素首地址+1,在计算strlen,5
    strlen(*p)     出错,
    strlen(p[0])   出错
    strlen(&p)   随机值
    strlen(&p + 1)  随机值,这个跟上面没有关系,主要是不知道哪里见到\0
    strlen(&p[0] + 1)) 5
    */

辅助图:

二、二维数组

以下结果为什么呢?

答案及分析:

     sizeof(a)  48
     sizeof(a[0][0])  4
     sizeof(a[0]) a[0]作为数组名并没有单独放在sizeof内部,
     也没取地址,所以a[0]就是第一行第一个开始算的地址,16
     sizeof(a[0] + 1)是第一行第二个元素的地址 4
     sizeof(*(a[0] + 1)) *(a[0] + 1)第一行第二个元素的解引用,4
     sizeof(a + 1)  4,a是二维数组的数组名,并没有取地址,也没有放在sizeof()
     内部,所以a表示二维数组首元素的地址,即第一行的地址,a + 1就是二维数组第二行的地址
     sizeof(*(a + 1))  16 对第二行地址进行解引用,计算的是第2行的大小
     sizeof(&a[0] + 1) a[0]是第一行的数组名,&a[0]取出的是第一行的地址,
     &a[0] + 1就是第二行的地址,所以结果为4
     sizeof(*(&a[0] + 1))  16
     sizeof(*a)    16, *(a+0)-->a[0],对首行地址进行解引用
     sizeof(a[3])   16,因为sizeof()内部的表达式是不计算的
     a[3]其实是第4行的数组名(如果有的话),所以其实不存在,也能通过类型计算大小
 


总结

重在理解,关键是知道指针所指向的谁,在内存中是怎么分布的~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值