说起指针,学过C语言的人,都会说指针是C语言灵魂,也就是说没了指针C语言就会没了灵魂,听起来很怪,不过确实是这样的,话糙理不糙。那毋庸置疑指针也是C语言的难点以及重点,不过在我看来,关键还是大家没有把指针看透彻,其实只要理解不同指针变量的定义之间的区别,就能完全玩转指针。
现在开始玩转指针吧,看下表中不同指针变量的定义。
指针变量
定义 指针变量
含义 内存
分配 指针变量
加1偏移量
char *char_p 指向字符型的指针变量 4 1
int *int_p 指向整型的指针变量 4 4
char (*char_array_p)[10] 指向字符型一维数组(维数10)的指针变量 4 1*10
int (*int_array_p)[10] 指向整型一维数组(维数10)的指针变量 4 4*10
int (*function_p)(int a,int b) 指向函数int plus(inta,int b)的指针变量 4 无意义
下面是具体的例子程序。
int plus(int a, int b)
{
returna+b;
}
int main(void)
{
char*char_p;
int*int_p;
char(*char_array_p)[10];
int(*int_array_p)[10];
int(*function_p)(int a, int b);
charchar_a;
intint_b;
charchar_c[2][10];
intint_d[2][10];
char_p= &char_a;
int_p= &int_b;
char_array_p= char_c;
int_array_p= int_d;
function_p= plus;
return0;
}
总结前先说说类型匹配,对于C语言,一个重要的概念就是类型匹配,对于赋值语句,要求左值和右值必须类型一致,有人可能想不是必须的吧,字符型数据可以赋值给整型变量,表面上看是矛盾的,其实不然,这里涉及到隐式的强制类型转换,编译器会把右值的数据类型隐式的强制转换为左值的数据类型,所以前面说的必须类型一致是正确的。对于函数传参也是一样的实参数据类型必须和形参数据类型一样。
大家首先应该总结到的相同点是这些定义都是在定义一个指针变量,对于指针变量分配的内存空间都是4个字节,不同点是指向的东西不一样,这样加1偏移量也就不一样,char_p指向字符,所以加1偏移量为1,int_p指向整型,偏移量为4,char_array_p指向字符一维数组,同时这个数组必须只能有10个元素,偏移量为整个数组所占字节数1*10,int_array_p指向整型一维数组,同时这个数组必须只能有10个元素,偏移量为整个数组所占字节数4*10,function_p指向一个函数的入口地址,只能指向形参为(int a,int b),返回值为int的函数,比如两个整数相加函数int plus(inta,int b),plus就是函数的入口地址。
总结前说明类型匹配很重要,对于一个变量来说,他会经历算数运算和函数参数传递等操作,那么我们说过他们必须类型匹配,也就是说各回各家各找各妈,比如我要把函数名存到一个指针变量那么我就必须先定义一个类似int(*function_p)(int a,int b)的指针变量,同时必须保证形参为(int a,int b),返回值为int,要指向其他类型的函数,可以照此方法类推,同样我想把二维数组名存到指针变量,我们知道二维数组名是一个数组指针,所以我们要定义一个类似char(*char_array_p)[10]的指针变量,必须保证二维数组的第二维必须为10,且数组类型为char,同样的道理我想要把整型的地址存到指针变量,对于这个我们都知道怎么定义,我们也应该能很好的理解,难点是上面的函数指针和数组指针,但如果我们对比前面的例子会发现其实它们都是一样的,都是指针变量,都占4个字节,只是指向的东西不一样,这样导致运算加1的偏移量不一样。
透过现象看本质,不要去孤立的学习知识点,把知识点都联系起来理解,会产生奇妙的火花,不需要死记硬背也能很好的理解比较难的问题。
|