C 语言之 指针 (pointer in C language)
由于前一阵子在学python,对c语言接触的比较少,有些基础内容便有些遗忘,所以特地花些时间回顾一下c语言的基础内容。c语言与其他很多语言最大的不同之一就是指针,这也是初学c语言中遇到的第一个难以理解的语法!书本上有的基础内容就不赘述了,下面的内容主要是一些个人的理解。
指针
1> 指针的定义明确指出指针变量是一种专门用来存放地址的变量。 我们知道所有
的数据都是用特定的编码规则以一串二进制的数的形式存在内存中,比如一个int类型
的数据,占有32个bit。计算机为了方便管理成千上万的数据,把bit都编了号。当程
序中定义了一个变量后, 在编译时计算机会为这个变量分配内存单元,即该变量在内存
中有一个地址段。在c语言中我们可以用一个变量专门来存放另一个变量的地址(通常是
首地址),即指针。
2> 数组其实是一种特殊的指针。举个例子来说,int a[5]; 在这里定义了一个5
个元素的整型的数组,实际上在底层的实现中,是计算机分配了5 x 32 bit的内存给
程序, 数组的名称a, 记录的就是这段内存的首地址( 是不是很眼熟,是的,a就是
一个指针)。而 a [n], 也就是数组的第n+1个元素,这里的n其实是相对于首地址的
偏移量。那么a [n] 也就可以表示为 *(a + n) 。
3> 指针的用途非常广泛,指针可以指向基类型数据,可以指向数组,还可以指向函
数。一个函数在编译时会被分配给一个入口地址,函数指针就指向这个入口地址。
指针辨析
Attention: 我们通常在考试或者程序里判断某一个指针的含义时,困惑最大的来源
就是层出不穷莫名其妙的括号。在这里,我有一个小技巧,所有的括号,我们把它视为
一个变量。比如说:int * p[n] 和 int (*p) [n] ,前者是指针数组,它是一个
元素为整型指针的数组,后者才是数组指针,它(即p)才是指向一个数组的指针。
在分辨时因为后者有一个括号,所以我们 (*p) 这个部分当作一个变量a ,那么int
a[n] 是一个整型数组,而p又是指向数组首地址a的指针,所以int (*p)[n]中这个p
就是指向一个数组首地址的指针。
那么接下来进入重头戏,分辨以下p的含义:
int p; //p是一个整型数据
int *p; //p是一个指向整型数据的指针
int *p[1]; //注意,这里没有括号,所以int *是一部分,p[3]是另一部
//分,现在很明显了,p是一个含有三个元素的数组,元素类型为
//整型指针
int (*p)[1]; //这里有括号,把括号看作一个变量,那么就变成了int a[3],
//*p指向a, 显然p是指向一个有三个整型元素的数组的指针
int p(int); //p是一个参数为整型,返回值也是整型的函数
int *p(int); //没有括号,因此int *是一部分, p(int)是另一部分。显然
//,这是一个参数为整型,返回值为整型指针的函数
int (*p)(int); //有括号,处理方法参上。p是指向一个参数为整型,返回值为整
//型的函数的指针
int (*p[1])(int);//有括号。p是一个函数指针数组,这个数组中每个元素指向有
//一个整数型形参和整数型返回值的函数
int *(*p(int)); //有括号。把(*p(int))看作变量a,int * a是一个整型指
//针,再把p(int)看作变量b, *b指向a,那么b应该是指向一
//个整型指针的指针,p(int)是一个函数,所以显然,p是一个
//返回值为整型指针的指针的函数。简单来说,这是一个函数声
//明。
这一部分就复习到此,以上纯属个人理解,如有错误或者不足,还望各位能够不吝赐教!