我们学习C语言指针,最应该了解的应该是它的本质,它在C语言中很多时候是与地址等价的;
在这里,指针str指向的就是内存中a的地址,如果这是arr数组,那么在使用时,str==arr,原因是arr这个数组名就是数组首元素地址,而str这个指针的具象化就是如图,一个指向arr首元素的箭头,在调用str时,实际上也是调用arr首元素;
值得注意的是,如同上图的情况,在进行打印一类活动时,用*str或*arr是不同于直接调用str和arr的,*的作用是解引用找到这个指针存储的地址所存储的元素,而直接用str和arr会找到数组首元素地址,这样做的差异是,前者打印的是所找到的元素,后者是打印整个数组所有元素(不出意外的话);
——————————————————————————
在了解了指针的本质 即 C语言中 内存单元的编号 == 地址 == 指针后,我们来了解一下它所含的大致类型:
int*p 最基础的整形指针变量,int表示返回类型,*表示p是指针变量
int*p[5] 指针数组的表示,[5]表示p数组里有五个元素,int*表示这五个元素都是整形指针类型,即:p是一个由五个整形指针类型元素组成的数组
int(*p)[5] 数组指针,顾名思义,是指向数组的指针,(*p)让*对p的优先级高于[5],此时p是指针变量,再结合[5],说明这个数组有5个元素,int表示这5个元素是整形类型
int(*p)(int) 函数指针变量,同样的:(*p)表示p是指针变量,(int)则表示这个指针带有参数,即此指针是指向一个有一个int参数的函数,且返回值也是int
int** 二级指针,表示的是一个指向指针的指针,但由于多级指针的使用很少,所以此处不加论
int*(*p(int))[5] 是一个C语言中的复杂指针声明。为了更好地理解这个声明,我们可以将其拆分为几个部分:
p(int)
:这是一个函数声明,表示p
是一个接受一个int
类型参数的函数。*(*p(int))[5]
:这部分表示函数p
返回一个指针,这个指针指向一个包含5个元素的数组,数组的每个元素都是一个指向int
类型的指针。
综合起来,int *(*p(int))[5]
声明了一个函数p
,这个函数接受一个int
类型的参数,并返回一个指针,这个指针指向一个包含5个元素的数组,数组的每个元素都是一个指向int
类型的指针。
以上就是我们常能见到的指针类型,当然不止于int整形类型,char等类型的指针可由上类推
——————————————————————————
在认识指针类型时,我们常常感到吃力,觉得难以判断,那么该如何解决这一困境呢?通过一些自我总结和相关文献的观点,我认为我们应该清晰地去区分指针的类型和指针指向的类型,如下例:
(1)int*ptr; // 面对这个指针,很多人脱口而出的是指针类型int*,是的,但同时我们也应该意识到它的所指向内容的类型是int
(2)char*ptr; //同上,指针类型是char*,指向内容的类型是char
(3)int**ptr; //这是个二级指针,指针类型是int**,指针指向的是什么?是int*类型的内容
(4)int(*ptr)[3]; //指针所指向的的类型是int()[3] //这是个数组指针,指针类型是int(*)[3],指针指向的内容的类型是个int[3],即一个含三个int类型元素的数组
(5)int*(*ptr)[4]; //指针所指向的的类型是int*()[4]&nb