鱼C论坛

 找回密码
 立即注册
查看: 2795|回复: 15

[技术交流] 二、指针详解之指针与数组

[复制链接]
发表于 2013-4-3 21:02:43 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
        指针经常和数组搭配在一起用的,但是初学者由于对它们的理解不足,经常出现一些诸如越界、溢出等等的问题。我这篇文章将对指针和数组的关系进行比较深入的讲解,希望看过的朋友能对指针和数组有个新的认识。
   “ 可以把数组名看做一个指针",这句话出现的频率挺高的,不过这句话对初学者的误导也是很严重的。首先,这句话并有错,但是很容易让初学者对数组名产生错误的认识。首先,你要知道,数组名是个常量,既然是个常量,就如上一篇所讲,它不能作为左值,比如定义一个数组int a[10],那么a++或者a = p这样都是错误的写法。所以数组名和真正的指针是两回事,大家要分清。那为什么又说可以把数组名看做指针呢?这是因为数组名的有些特性类似指针。如下面的例子。
   
  1. int main()
  2. {
  3.         int a[3] = {1,2,3};
  4.         int *p = a;
  5.         printf("%d\n",a[0]);
  6.         printf("%d\n",*(p+1));//表示a[1]
  7.         printf("%d\n",*(a+2));//表示a[2]
  8.         return 0;
  9. }
复制代码
       假设这时数组的首地址是1000,那么这时a的值也是1000,p+1的值是多少呢?因为编译器知道p是指针,所以p+1的值并不是1001,而是1000+sizeof(int)。a+2的值是1000+2*sizeof(int)。a在这个时候类似于p的性质,所以说可以看做指针。但是,仅仅是看做,再强调一遍,它不是真正指针,不能作为左值。综上所述,可以把数组名当做一个指针常量,也就是不能做左值的指针。
       另外有两种情况是不能把数组名看做指针常量的。下面说明:
  1. 例一:
  2. int main()
  3. {
  4.   
  5.   int a[10];
  6.   int *p = a;
  7.   printf("%p\n",a);
  8.   printf("%p\n",p);
  9.   printf("%d\n",sizeof(a));
  10.   printf("%d\n",sizeof(p));
  11. }

  12. 输出结果为:
  13. 0012FF58
  14. 0012FF58
  15. 40
  16. 4
复制代码
      当然上面输出的地址可能大家各不相同啊。大家可以看到sizeof(a)是等于40的,而sizeof(p)是4。这就说明当数组名作为sizeof的参数时,返回的是数组的总长度。而不是指针的长度。这是其中一种情况。

  1. 例二:
  2. #include <stdio.h>
  3. void SetValue(int **p);
  4. int main()
  5. {
  6.         int i=0;
  7.         int a[5]={1,2,3,4,5};
  8.         SetValue(&a);
  9.        
  10.         for(i=0;i<5;i++)
  11.         {
  12.                 printf("%d ",a[i]);
  13.         }
  14.         return 0;
  15. }

  16. void SetValue(int **p)
  17. {
  18.         (*p)[0] = -1;
  19. }
复制代码
    这是个错误的示范,可能乍一眼看上去,没啥问题,a可以看做指针,那么&a就是二级指针了,那么作为SetValue的参数顺利成章啊,怎么执行纠错错了呢?
呵呵,不要忘了,a并不是指针,&a当然也不是二级指针。这时&a是一个指向数组的指针,是一个一级指针,字面值与相同。

  
游客,如果您要查看本帖隐藏内容请回复


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-4-4 00:29:06 | 显示全部楼层
还有什么隐藏的内容,学习.半夜睡不着觉,看帖真是享受.
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-4-4 09:55:58 | 显示全部楼层
学习了,{:1_1:}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-5-6 11:07:01 | 显示全部楼层
真是难得给力的帖子啊。3q啊   来学习啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-5-6 11:28:51 | 显示全部楼层
真是难得给力的帖子啊。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-5-6 11:43:28 | 显示全部楼层
再强调一遍,它不是真正指针,不能作为左值

这句话说得有问题

它不是真正指针,不能作为左值
似乎是在说 指针能作为左值
实际上 int i; &i;这个指针就不能作为左值

PS: 别告诉我 你不知道&运算符真正的作用是什么
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-5-6 12:17:32 | 显示全部楼层
强烈支持楼主ing……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2013-5-6 16:26:15 | 显示全部楼层

我这里所说的指针是通常我们说的指针变量,&i是地址,是常量,当然不能做左值了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-5-14 15:46:18 | 显示全部楼层
我只是路过打酱油的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-5-14 17:04:02 | 显示全部楼层
楼主加油,鱼C加油!我们都看好你哦!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-5-14 17:24:35 | 显示全部楼层
真是难得给力的帖子啊。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-5-14 17:49:33 | 显示全部楼层
我只是路过打酱油的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-5-14 18:47:09 | 显示全部楼层
我只是路过打酱油的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2014-6-12 13:24:37 | 显示全部楼层
指针这玩意儿确实比较灵活,搞清楚是必要的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-12 21:25:11 | 显示全部楼层
学习了,支持楼主ing……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-10-7 09:09:13 | 显示全部楼层
淘金
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-24 04:55

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表