今天在csdn的c版看到了这样的一个帖子:http://community.csdn.net/Expert/topic/4264/4264741.xml?temp=.8964502 问的是数组和指针的区别.但最后引出的却是"数组名是指针吗?"这样一个问题.
其中megaboy(飞天御剑流之杀神一刀斩) 的回答与众不同,按他对数组名的理解:数组名是一个符号地址常量,这个解释确实可以解释一些现象,但还有很多不能用这个来解释的问题.
比如我在那个帖子里提到的两个程序:
1,include<stdio.h>
main()
{
int a[]={1,2,3};
int *p;
p=a;
printf("%d/n",p);
return 0;
}一个符号地址常量怎么可以对一个指针赋值呢?
2,又比如,printf的参数要求是一个指针,按megaboy的说法下面的程序肯定不成立.
#include<stdio.h>
main()
{
char a[]="wayne";
printf(a);
return 0;
}但结果是打印出wayne
晚上迎接新生回来以后,查了一下<<c++ primer 第三版>>和<<c++程序设计语言 特别版>>.前一本书上没有提太多这方面的东西,在7.9.2节只有一句话提到:"不带下标操作符的数组名会被解释成指向首元素的指针".后一本讲的多一点,在5.3节:"到数组的指针"中把这个问题大致讲了一下:"一个数组的名字能够被用作到它的开始元素的指针.
如 int v[]={1,2,3,4};
int *p1=v;//指向开始元素(隐式转换) 隐式地从int [ ] 转换到int *
从数组名到这个数组的开始元素的指针的隐式转换,在c风格代码的函数调用中广泛使用."
至于到底是怎么转换地,我想没有必要了解的那么多.
所以我还是认为"不带下标操作符的数组名会被解释成指向首元素的指针".这样好理解.但是数组名是不能被修改的,它是一个常量,不能进行任何赋值或加减的运算.
2005.11.26 更正:
今天又认真地看了一遍K&C中关于指针和数组的章节,感到自己以前的理解是有偏差的。
我现在的理解是:
1。数组名所代表的是该数组最开始的一个元素的地址。
2。指针是一种保存变量地址的变量。
3。数组名和指针之间有一个不同之处。指针是一个变量,因此,在C语言中,语句pa=a和pa++都是合法的。但数组名不是变量,因此,类似于a=pa和a++形式的语句是非法的。
以上均抄自K&C。以前看书太不仔细了。如果从汇编的角度看的话应该更容易理解一些。
至于<<c++程序设计语言 特别版>>中提到的隐式转换,应该是把数组第一个元素的地址送到指针所在的内存空间中,即指针的值为这个地址。
同时我觉得简单地理解为"不带下标操作符的数组名会被解释成指向首元素的指针"也没有什么错误。但要注意,数组名绝对不是指针。
2005.12.10 补充:
在一个blog上看到一篇文章,也是讨论数组名的(http://blog.csdn.net/soloist/archive/2004/11/03/164625.aspx),
觉得写得不错,所以写一下自己现在对这篇文章的一些认识,就算是对自己写的东西的一个补充吧。现在看自己前面写的,觉得以前的理解确实比较浅薄。学无止境啊,学习ing!
下面引用一下soloist的文章(加粗的是我自己的一些试验和理解):
C/C++中的数组名是个很奇怪的东西,它到底代表什么呢?
对于char array[n](n是一个常数),大概有这么几种语义:
<1> char* const(注意不是const char*) <2> char [n]
举例如下(WIN2000 PRO平台,VC.NET 7.1下编译):
<1> char p = array; //array表示char const,p得到的是数组的首地址
size_t size = sizeof(char [n]); // size等于n
/**********sizeof(char [n])就相当于sizeof(array)*********/
<2> char (*p)[n] = &array; // array表示char [n],
// p得到的仍然是数组的首地址
char (*q)[n] = array; // 编译错误
/**********因为q的类型是char (*)[n],而array的类型是char* ************/
char (*r)[n] = (char (*)[n])array; // r得到的是array数组的首地址
/*********************我的试验和理解********************************
#include<stdio.h>
enum{n=12};
main()
{
char array[n];
char (*p)[n] = &array;//这里,&array[0]等价于&array
printf(“%d/n%d/n”,sizeof(*p),sizeof(p)); //结果为12,4
return 0;
}
语句char (*p)[n] = &array;声明了p一个指向字符数组的指针,这个数组的大小和array一样。所以sizeof(*p)和sizeof(array)的值相等。注意:在这个程序中,数组array和*p都只是被声明,并没有被分配内存。
我又试了一下,发现sizeof(array)和sizeof( *(&array) )相等。这就可以更好地理解上面的程序了。上面的程序和sizeof( *(&array) )相比,只是多了一个变量p罢了。p的地址为&array,那么*p就是array了。所以sizeof(*p)就和sizeof(array)的值相等了。
<3> char (&p)[n] = array; // array表示char [n]
这个语句当时让我有些迷惑,后来在别人的指点下,才明白&在这里原来是c++中的引用(c++学的不多,放在这里就更让我不懂了)。在c中编译不能通过。这个语句声明p是数组array的一个引用。所以sizeof(p)=n.
那篇文章还讨论了不少,但基本上都是以前面的为基础。