1 指针(pointer)的定义
指针是内存空间中的地址。在C语言中,可以通过指针访问变量和函数。
指针相关的运算符有"*"与"&"。"*"与"&"互为逆运算。
・"*":取指针所指向的内存单元的内容
・"&":取内存单元的地址
int i = 1; int* p1; //定义指针变量p1 p1 = &i; //指针p1指向变量i printf("i=%d,*p1=%d",i,*p1); //输出“i=1,*p1=1” i = 2; printf("i=%d,*p1=%d",i,*p1); //输出“i=2,*p1=2”
2 指针与数组的关系
在C语言中,可以通过数组名访问数组首地址。而且,数组名也可使用"*"操作数组中的数据。
int a[] = {5,6,7}; int* p = a; printf("%d",*p); //输出“5” printf("%d",*a); //输出“5”
数组的取下标运算可以实现取所指向的内存单元的内容的功能,与"*"的功能一致。
int a[] = {5,6,7}; int* p = a; printf("%d %d %d",p[0],p[1],p[2]); //输出“5 6 7” printf("%d %d %d",*p,*(p+1),*(p+2)); //输出“5 6 7” printf("%d %d %d",*a,*(a+1),*(a+2)); //输出“5 6 7”
3 const关键字在指针中的使用
定义的指针所指向的地址不能被改变(但可以通过该指针更改所指向的地址的内容)
int i1 = 5; int i2 = 6; int* const p = &i1; p = &i2; //非法,指针所指向的地址不能被改变 *p = 10; //合法,可以通过该指针更改所指向的地址的内容
定义的指针不可以通过该指针更改所指向的地址的内容,但是指针所指向的地址可被改变
int i1 = 5; int i2 = 6; const int* p = &i1; //也可以写成 int const* p = &i1; *p = 10; //非法,不可以通过该指针更改所指向的地址的内容 i1 = 10; //合法。且此时*p的值变为10 p = &i2; //合法,指针所指向的地址能被改变
当然。也可以定义具有以下特性的指针
不能通过该指针更改所指向的地址的内容,指针所指向的地址也不能被改变
int i1 = 5; int i2 = 6; const int* const p = &i1; p = &i2; //非法,指针所指向的地址不能被改变 *p = 10; //非法,不能通过该指针更改所指向的地址的内容
4 函数指针(指向函数的指针)
在C程序中的函数会保存在内存空间中,通过函数名可以得到该函数所在内存空间的地址。
#include <stdio.h> int function(int i){ printf("%d",i); } int main(){ printf("%d",function); //输出函数function的地址 return 0; }
访问目标函数,除了通过函数名直接访问,也可以通过使函数指针指向目标函数的地址间接访问。
#include <stdio.h> int f1(){ printf("this is function f1\n"); return 0; } int f2(){ printf("this is function f2\n"); return 0; } int main() { int (*pFun)(); //定义函数指针,注意与函数声明区分开来 //int *pFun();为声明返回值为整数指针(int*)的函数 pFun = f1; pFun(); //输出"this is function f1" pFun = f2; pFun(); //输出"this is function f2" return 0; }
函数指针与其所指向的目标函数的以下项目必须完全一致
(1)参数列表的变量个数
(2)参数列表的变量类型
(3)返回值的类型
#include <stdio.h> int f3(int i){ return 0; } int f4(int i1,int i2){ return 0; } int f5(double d){ return 0; } double f6(int i){ return 0.0; } int main() { int (*pFun)(int i); //定义函数指针,可以省略参数列表中的变量名,即int (*pFun)(int); pFun = f3; //合法 pFun = f4; //非法,参数列表的变量个数不一致 pFun = f5; //非法,参数列表的变量类型不一致 pFun = f6; //非法,返回值的类型不一致 return 0; }