在我初学C语言指针和数组时踩过的那些坑
指针和地址的区别
我c语言的启蒙书是谭浩强先生的《c语言程序设计》(对,你没听错),在书中有这么一句话
指针就是地址
这句话当时让我摸不着头脑,指针是个变量,地址是个常量,它们两怎么能够相等呢?
在我在网上查询相关关于指针的回答后,就发现这是个坑
指针和地址不是打等号的! 指针是个变量,存储的是地址。
也就是说指针是个存储地址的变量,指针不是地址。
指针和数组名
在学习指针和数组这一章时,我又遇到了一些问题,老师说数组名就是指向数组首元素的指针,当时我信以为然。但是我在看tcpl的时候,书上明确指出数组名和指针是有不同的
1 | 指针是一个变量,因此在c语言中,语句pa=a和pa++都是合法的。 |
也就是说数组名不是左值,不能对其进行赋值操作。
而在《c陷阱与缺陷》中也有这么一句话
如果calendar不是用于sizeof的操作数,而是用于其他场合,那么calendar总是被转换成一个指向calendar数组的起始元素的指针。
这句话中的转换 两字格外显眼,更加说明了数组名不是指针,只是在大多时候隐式转换为指向数组首元素的指针。于是我写了代码来验证了一下
1 |
|
运行结果如下
可见在对其使用&和sizeof运算时,数组名并不是指向首元素的指针。
在对其使用sizeof运算时,数组名是代表的是整个数组,并不是指针,因为指针的大小为8个字节,而数组名却是12个字节。
在对其使用&运算符时,&数组名 是整个数组的地址,也说明在这里数组名代表的是整个数组。
即在这两种情况下,arr是单独的类型,即「长度为3的int数组」类型,而不是「指向int的指针」类型。
总结
指针和地址是不一样的,指针是变量,地址是常量,指针中存储的是地址。
数组名和指针也是不一样的,指针是变量,但是数组名不是;数组名在大多时候都转换为指向数组首元素的指针,而在对其使用&和sizeof的时候不会转换。
用a[i]的方式访问数组都会被转换为*(a+i)的形式
指针始终是指针,不可当作数组来访问,否则会发生错误(除了明确知道指针指代的是数组的情况)
当数组当作函数的参数时,一个数组的声明可以看作指针
函数的参数(即形参)为数组时,数组在函数内部实际上都转换为了指针!可以对数组名进行赋值,但在其他地方不可对数组名进行赋值(但是指针一直可以)
数组的定义和声明必须匹配,如果在一个文件中定义为数组,在其他文件中必须声明为数组形式,不可声明为指针