开始之前
指针是C语言的特色,是重点也是难点.C语言中的数组与指针有很多重叠的功能和用法.再加上国内某著名号称发布万册的C程序设计教材的误导.提到这本教材,忍不住多说几句,或许从C语言语法上,这本书的错误很少,当然很少不代表没有,比如这个:比语法错误更引人误入歧途的是整本书毫无工程思想和编码规范,我觉得这种书还是不要出版这么多了吧.今天讨论的是数组名和指针,先从书中摘出来最容易引人误入歧途的这句话:你不能说这句话错,但是这句话实在没有把数组名和指针的关系讲清楚,甚至这句话根本没有给人一点要继续细究原理的启发,以为就是这样了,其实差之毫厘,谬之千里.真心希望国内的这些有影响力的计算机图书编写者们,能够多一些精益求精的精神,别总把心思放在一本书的内容劈成上下册,售价几乎翻倍的挣钱伎俩上.吐槽告一段落,言归正传,"数组名就是指向数组首地址的指针"这个说法,实在是不妥,让我们来剖析一下吧.打个比喻
打个比喻,数组名和指针,相当于董事长和总经理的区别,同样都是那种看起来挺像官都挺大但实际上有本质差别的角色.这段代码体现了数组和指针以上三个特性(为简化篇幅,省略掉main函数和头文件)://长度charstrTest1[10];char*pTest1;printf("sieof(strTest):%ld",sizeof(strTest));//输出结果为10printf("sieof(pTest):%d",sizeof(pTest));//输出结果为4//类型charstrTest2[10];charstrTest3[10];char*pTest2;strTest2=strTest3;//编译错误,strTest2为常量,不能作为左值.pTest2=strTest2;//pTest2被设置为指向strTest2数组的首地址pTest2=strTest3;//pTest2被设置为指向strTest3数组的首地址//指向charstrTest4[10];charpTest4;pTest4=strTest4;//pTest4被设置为指向strTest4数组的首地址pTest4+=2;//pTest4被设置为指向数组strTest4的第3个数组元素(数组下标2)strTest4+=2;//编译错误,strTest4作为常量,不能被改变//操作charstrTest5[10]="China";charstrTest6[10];charpTest6=strTest6;strcpy(strTest6,strTest5);//strcpy的函数原型中,两个形参都是char*类型,此时两个数组名作为指针strcpy(pTest6,strTest5);//完成与上句同样的功能
总结
数组名的本质:1)数组名的内涵在于其指代实体是一种数据结构,这种数据结构就是数组2)数组名的外延在于其可以转换为指向其指代实体的指针,而且是一个指针常量3)指向数组的指针则是另外一种变量类型,仅仅意味着数组的存放地址最后的意外情况
当数组名作为函数形参时,情况变了,看如下代码voidFunTest1(charstr[]){printf("%d",sizeof(str));//结果为4,而不是10str++;//合法,str指向了main函数中strTest数组的第二个元素}voidFunTest2(charstr[10]){printf("%d",sizeof(str));//结果为4,而不是10}voidFunTest3(char*str){printf("%d",sizeof(str));//结果为4,而不是10}main(){charstrTest[10]="Thinking";FunTest1(strTest);FunTest2(strTest);FunTest3(strTest);}这段代码说明了这样一个问题:(1)数组名作为函数形参时,在函数体内,其失去了本身的内涵,仅仅只是一个指针;(2)失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。(3)函数在将数组名作为形参时,只是作为一个指针,根本不管原数组的大小,所以在以上三个子函数中,形参怎么写都是一样的,charstr[],charstr[10],char*str完全一样,甚至你写个charstr[]都无所谓,子函数根本不关心原数组的大小.这就像是在国内风光无限的董事长,出国的时候带不走家财万贯,只能靠打工糊口了,当然带来的好处是也可以随便跳槽了.预览时标签不可点收录于合集#个上一篇下一篇