分享

在C 中数组和指针的区别

 fisher60 2013-01-22

在C++中数组和指针的区别

之前,比如一个数组int a[10],我一直把a理解成一个指针,就是int*,那么,int a[10][10]中的a自然就是int**,但是,这段程序却无法编译:
int mm[5][5];
int **gg(int k)
{
return mm;
}
却无法编译,必须改成
typedef int(*dt)[5];
dt gg(int k)
{
return mm;
}
或者
int (*gg(int k))[5] {
int (*p)[5] = NULL;
return p;
}
这点很令人不解,其实我一直的理解都错了。
来看百度知道上的一个问答:

问:
问题补充:int a[5]={1,2,3,4,5};这里的a不是说代表一个常量吗,怎么可以&a这样操作呢,
搞得我以为是等同于&a[0]。


答:

在一般上下文中,对数组的引用会退化为指针,例如:
int a[5];
int *p = a + 1;
在这代码中,第二行对a的引用退化为一个指针,指针类型为int。
在&a这样的表达式中数组退化为指针的规则则不再使用。作为一个整体,&a也表示一个指
针,它与a不同的就是:a的指针类型为int,而&a的指针类型为int[5]。
用这段理解来解释楼主的问题就不难了
即 int *ptr=(int *)(&a+1); 这句话
&a+1是对于int[5]类型的加1,然后再转成(int*)时,其实ptr指向了a[5]!
接着再减1,自然输出了a[4]。
-------------------------------------------------
补充知识:
1)在c语言中,并没有真正的数组类型,大部分对数组的引用会退化为指针
2)多位数组的情况:
例如int a[x][y];
则a退化为指针类型是int[y],&a的类型则是int[x][y]
3)数组退化为指针的规则不能递归应用。数组的数组退化为数组的指针,而不是指针的指针。
如果你向函数传递一个二维数组,例:
int a[x][y];
f(a);
则f必须声明成
int f(int a[][y]);

int f(int (*a)[y]);
而不能是
int f(int **a);

-----------------------------------
楼主,你所听说的a称作常量指针,这都是骗小孩子玩意,要想真正理解数组,必须明白在
表达式中出现a,a退化为指针

“数组名“之所以为常量是因为它不能被赋值,但!!数组不是指针!!。数组只是在表达
式中出现时退化为指针,而指针&p与数组&a则是截然不同的行为,这正说明数组不是指针。
例如 int *p = (int *) 111;
那么p是111,而&p则是p的地址(可能为0x00122222),
但对于数组 int a[6];
若a是0x00123333,则&a也是0x00123333,只是这两者的指针类型不同

-----------------------------------------------

另外,在参数传递时数组也经常令人困惑
例如int f(char a[]);这种类型的声明,编译器内部将它当作int f(char *a);
所以可以对它传入指针。若对它传入数组,则数组退化为指针所以参数类型检验才能通过。
所以你即使声明int f(char a[4]);看上去a是个数组,在函数体内写a = 1;则违反了数组
名是常量的规则,其实a = 1;是允许的因为int f(char a[4]);在编译器看来是int f(char *a);
其中的4被忽略了

最后一点要注意的是在一个源文件中定义int a[5];
而在另一个源文件1中写下extern char *a是不合法的
因为数组与指针是两个类型

-----------------------------------------------
最后罗索一句,楼主你所说&a[0]倒是和一般上下文中a等价都是int型指针。而&a则是int[5]型指
针,我一直强调这点你明白了没?

希望楼主好好学习,c中的数组可不好理解

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多