指针的定义:它里面存储的数值被解释为内存中的地址。
首先我们学号指针要从四个方面入手:
指针的类型
指针所指向的类型
指针的值或叫指针所指向的内存区
指针本身所占据的内存区
例:
int *ptr;
char *ptr;
int **ptr;
int (*ptr)[3];
int *(*ptr)[4];
一、指针类型
int *ptr; // 指针类型是int*
char *ptr; // 指针类型是char*
int **ptr; // 指针类型是int**
int (*ptr)[3]; // 指针类型是int(*)[3]
int *(*ptr)[4]; // 指针类型是int*(*)[4]
二、指针所指向的类型
当我们通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把计算机那块内存区域里的内容当做什么来看待。从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针的声明符*去掉,剩下的就是指针所指向的类型。
int *ptr; // 指针所指向的类型是int
char *ptr; // 指针所指向的类型是char
int **ptr; // 指针所指向的类型是int *
int (*ptr)[3]; // 指针所指向的类型是int()[3]
int *(*ptr)[4]; // 指针所指向的类型是int*()[4]
三、指针的值
就是内存中的地址
四、指针本身所占据的内存区
在64位的计算机中,指针变量一般占的是八位,而在32位的计算机中则是四位
指针类型刨析
int p; // 普通的整型变量
int *p; // 普通的整型指针变量
int **p; // 说明指针所指向的元素是指针
int p[3]; // 整型数据类型的数组
int *p[5]; 是指针数组,有5个成员,每个成员都是一个指针,共有5个指针,[]的优先级高于*,相当于*(p[5]);优先级表查阅:https://blog.csdn.net/m0_50919743/article/details/115755380?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167765372216800211591059%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167765372216800211591059&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-3-115755380-null-null.142^v73^control_1,201^v4^add_ask,239^v2^insert_chatgpt&utm_term=c%E8%AF%AD%E8%A8%80%E8%BF%90%E7%AE%97%E7%AC%A6%E5%8F%B7%E4%BC%98%E5%85%88%E7%BA%A7&spm=1018.2226.3001.4187
int (*p)[5];小括号优先,所以是1个指针,用来指向5个元素的数组;
int *(*p(int))[5]; // 首先要从p开始,先与()结合,然后进入()里面,与int结合,说明函数有一个整型变量参数;然后再与外面的*结合,说明函数返回的是一个指针;然后到最外面一层,先与[]结合,说明返回的指针指向的是一个数组;然后再与*结合,说明数组的元素是指针;然后再和int结合,说明指针指向的内容是整型数据,所以p是一个参数为一个整型且返回一个指向由整型指针变量组成的数组的指针变量的函数。
指针类型转换
当我们初始化一个指针或指针赋值时候,赋值号左右两边类型不一致的情况下,此时需要进行强制转换。
语法:(TYPE*)p;
函数指针与指针函数
函数指针:首先它是一个指针,只是这个指针指向的是一函数。指针变量可以指向变量的地址、数组、字符串、动态分配地址,同时也可以指向一个函数,每个函数在编译的时候,系统会分配给该函数一个入口地址,函数名表示这个入口,那么指向指针变量称为函数指针变量。
声明格式如下:
类型说明符 (*函数名)(参数)
例如:
void (*fptr)();
赋值:
fptr=&function;
fptr=function;
如果函数调用,还必须包括圆括号的参数表。
两种方式来通过指针调用函数:
x=(*fptr)();
x=fptr();
指针函数:首先它是一个函数,只不过这个函数的返回值是一个地址值。函数返回值必须使用同类型的指针变量来接受,也就是说,指针函数一定有函数返回值,而且,在主调函数中,函数返回值必须给同类型的指针变量。
声明格式:
类型说明符 *函数名(参数)