根据C89规定
指针是一个保存对象地址的变量,首先是变量,其次变量里的值是地址,所以输出的时候用%x输出。
printf("p4=%x\n",p4);
首先推翻数组名是指针的说法,这个说法出自国内某牛人的书,祸害了多少代学生
数组名不是指针
我们先来推翻"数组名就是指针"的说法,用反证法。
代码如下
char p5[10]="hello";
char *p6="hello";
printf("p5=%d\n",sizeof(p5));
printf("p6=%d\n",sizeof(p6));
证明数组名不是指针。
假设:数组名是指针;
则:p5和p6都是指针;
因为:在WIN32平台下,指针长度为4;
所以:输出都应该为4;
实际情况是:第p5输出10,第p6行输出4;
所以:假设不成立,数组名不是指针。
数组名是什么?身份不确定!
1常地址,指向数组第一个元素
你可以写成p5+1如此类推遍历数组内所有元素,但你写成p5++就会出错,因为它是常量。
2数组名指代一种数据结构:数组
现在可以解释为什么程序中p5输出为10的问题,数组名p5的内涵为一种数据结构,即一个长度为10的char型数组,所以sizeof(p5)的结果为这个数据结构占据的内存大小:10字节。
3数据名可能失去其数据结构内涵
到这里似乎数组名魔幻问题已经宣告圆满解决,但是平静的湖面上却再次掀起波浪。请看下面一段程序:
void arrayTest(char str[])
{
printf("str=%d\n",sizeof(str));
}
char p5[10]="hello";
arrayTest(p5);
程序的输出结果为4。不可能吧?
一个可怕的数字,前面已经提到其为指针的长度!
结论2指出,数据名内涵为数组这种数据结构,在arrayTest函数体内,str是数组名,那为什么sizeof的结果却是指针的长度?这是因为:
数组名作为函数形参时,在函数体内,其失去了本身的内涵,仅仅只是一个指针;很遗憾,在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。所以,数据名作为函数形参时,其全面沦落为一个普通指针!它的贵族身份被剥夺,成了一个地地道道的只拥有4个字节的平民。
以上就是结论3。
PS sizeof与strlen
1 Sizeof是操作符,而strlen是函数
2 sizeof会区分数据类型,而strlen不会区分是什么数据它只会很正常的找\0结尾。
所以sizeof和strlen对于同一个数组结果会差一个。
void arrayTest(char str[])
{
printf("str in sizeof=%d\n",sizeof(str));
printf("str in strlen=%d\n",strlen(str));
}
char *p1="hello";
printf("p1的地址为:%x\n",p1);
printf("p1的sizeof为:%d\n",sizeof(p1));
printf("p1的strlen为:%d\n",strlen(p1));
char *p2;
p2="hello";
printf("p2的地址为:%x\n",p2);
printf("p2的sizeof为:%d\n",sizeof(p2));
printf("p2的strlen为:%d\n",strlen(p2));
char p3[]="hello";
printf("p3的地址为:%x\n",p3);
printf("p3的sizeof为:%d\n",sizeof(p3));
printf("p3的strlen为:%d\n",strlen(p3));
arrayTest(p3);
char p4[10]="hello";
printf("p4的地址为:%x\n",p1);
printf("p4的sizeof为:%d\n",sizeof(p4));//空间大小是10后面没有赋值。
printf("p4的strlen为:%d\n",strlen(p4));//只有5个字符。
arrayTest(p4);