首先看几种常见的指针类型:
1. int *p;// p是 int * 的类型,p指向的是int 类型;
2. int **p;// p是 int** 的类型,p指向的是int* 类型;
3. char *p[ ];//p是 char*[ ] 的类型, p指向的是char* 类型;指针数组又被称为字符串数组,由此可知它主要处理字符char类型;
4. int (*p)[ ] ;//p 是 int(*)[ ] 的类型,p指向的是int [ ] 类型;它主要是指向数组,它也被称为行指针;
在看数组类型:
1.int a[ ] ;它是int[ ] 的类型;a是数组名,它不能被赋予地址,它是固定的;a可以看作指向int 的类型;
2. int a[1] [2] ;它是int [1] [2]的类型;a也是数组名,a 和 a[1] 它们都是地址且相同,但是它们的类型不同;a[1]指向的是int 类型;
3. char str[ ]; 它是char [ ] 的类型;str 是数组名;str 指向 char类型;
通过上面的简单的例子,可知指针和数组都是有变量名和类型定义的;它们有着相同点,不同点就是数组地址是固定的;
//指针赋值解析 #include <stdio.h> int main() { int arr[2][3] = { 1, 2, 3, 4, 5, 6 }; printf("%p\n", (arr));// 00F8FAF0 printf("%p\n", (arr + 1));//00F8FAFC printf("%d\n", sizeof(arr)); // 24 printf("%d\n", sizeof(arr + 1));// 4 printf("%d\n", sizeof(int[3]));// 12 //【arr 是数组地址,不可以赋值】 arr 是一个int [2][3]的类型,arr的操作范围是2,指向的是 int[3] 的类型 //a+1 移动位置 a+sizeof(int[3])*1 //数组不是指针,因为它带有限定范围 //int **p = arr; //p 是指向int* 类型的,p+1 操作是p+sizeof(int *)*1 //arr+1的操作不想等 int* ptr[1]; ptr[0] = arr[0]; //arr[0]是 int[]的类型,arr[0]的操作范围在3,最终指向的是int //ptr[0]是 int*的类型,ptr[0]是指针,指向的是int int **pp = NULL; int(*p)[3] = arr; //【p 是数组地址,是不可以赋值】p 是一个 int[3]* 的指针,p 指向的是int[3]类型的, //p+1的操作是:p+sizeof(int[3])*1;这与数组 arr操作是的相同; int *_p = (int *)(arr); //_p = arr[0]; // 与上操作相同,此时arr[0] 它指向int //此时(arr)是一个指针,指向 int型的数据,_p 也是一个指向int 的指针; //_p+1 操作:_p+sizeof(int); printf("%d\n", *(_p + 1));// 2 return 0; }
函数指针
定义
函数指针,其本质是一个指针变量,该指针指向这个函数。总结来说,函数指针就是指向函数的指针。
声明格式:类型说明符 (*函数名) (参数)int (*P) (int x , int y);
p 是指向有两个 int x , int y 参数的函数,函数的类型是 int
int (*p) (int x , int y); int Function(int c, int d); p = Function;//正确的
简单点来说,p 存的地址是函数Function 的地址, 所以 p 是int * 的函数指针,p 指向 int 型的函数;多定义在结构体中;
指针函数
定义
指针函数,其本质是一个函数,只是返回 的是地址。
声明格式:类型说明符 * 函数名(参数)int *P (int x , int y);
p 是有两个 int x , int y 参数的函数,函数的类型是 int *
int * p(int x, int y) { int date = 1; int * _P = &date; return _P; }