# include <stdio.h> int main(void) { int p;//——这个是一个普通的整形变量; int *p;//首先从P处开始,先与*结合,所以说明P是一个指针,然后再与INT结合,说明指针所 //指向的的内容的类型为INT型,所以P是一个返回整形数据的指针; int p[3]; /* 首先从P处开始,先与[]结合,说明P是一个数组,然后与INT结合,说明数组里的元素是整形的, 所以P是一个由整形数据组成的数组; */ int *p[3];// []比*的优先级高; /* 首先从P处开始,先与[]结合,因为其优先级比*高,所以P是一个数组,然后再与*结合,说明 数组里的元素是指针类型,然后再与INT结合,说明指针所指向的内容的类型是整形的,所以 P是一个由返回整形数据的指针所组成的数组。 */ int (*p)[3]; /* 首先从P处开始,先与*结合,说明P是一个指针然后再与[]结合(与“()“这步可以忽略,只是为了改变优先级),说明 指针所指向的内容是一个数组,然后再与INT结合,说明数组里的元素是整形的,所以P是一个指向 由整形数据组成的数组指针; */ int **p; /* 首先从P开始,先与*结合,说是P是一个指针,然后再与*结合,说明指针所指向的元素是指针,然后再与 INT结合,说明指针所指向的元素的元素是指针,然后与INT结合,说明该指针所指向的元素是整形数据,由于二级指针以级更 高级的指针极少用 在复杂的类型中,所以后面更复杂的类型我们就不考虑了多级指针了,最多只考虑一级指针了; */ int p(int); /* 从P处起,先与()结合,说明P是一个函数,然后进入()里分析,说明该函数有一个整形变量的 参数然后再与外面的INT结合,说明函数的返回值是一个整形数据。 */ int(*p)(int); /* 从P处开始,先与指针结合,说明P是一个指针,然后与()结合,说明指针指向的是一个函数,然后再与 ()里的INT结合,说明函数有一个INT型的参数,再与最外层的INT结合,说明函数的返回类型是整形,所以P 是一个指向有一个整形参数且返回类型为整形的函数指针; */ int *(*p(int))[3]; /* 从P开始,先与()结合,说明P是一个函数,然后进入()里面,与INT结合,说明函数有一个整形变量参数, 然后再与外面的*结合,说明函数返回的是一个指针,然后到最外面一层,先与[]结合,说明返回的指针指向的是一个数组, 然后再与*结合,说明数组里的元素是指针,然后再与INT结合,说明指针指向的内容是整形数据,所以P 是一个参数为一个整形据返回一个指向由整形指针变量组成的数组的指针变量函数; */ int *ptr; /* 从先Ptr开始,然后在与*结合,说明ptr是一个指针,并且这个指针针向是是一个整形,所以返回的也是整形; */ char *ptr; /* 从ptr开始,然后与*结合,说明ptr是一个指针,并且这个指针向的是一个字符型,所以返回的也是一个字符类型; */ int **ptr; /* 首先和ptr结合,然后再与*结合,说明ptr是一个指针,然后在于*结合,说明ptr是指向一个元素; */ int (*ptr)[3]; /* ptr首先和*结合说明ptr是一个指针,再与[]结合,说明ptr是一个数组指针; */ 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)[3];//指针所指向的是类型是int()[3]; //指针值——或者叫指针所指向的内在区域事地址; /* 指针的值是指针本身存储的数值,这个值将被编译器当作一个地址,而不是一个一般数值, 在32位程序里,所有类型的指针的值都惠一个32位整数,因为32位程序里内在地址全都是32位长。 指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度为sizeof(指针所指向的类型) 的一片内存区。以后,我们说一个指针的值是XX,就相当于说该指针指向了以xx为首地址的一片内存 区域;我们说一个指针指向了某块内存区域,就相当于说该指针的值是这块内存区域的首地址. 指针所指向的内存区和指针所指向的类型是两个完全不同的概念。在例一中,指针所指向的类型已经有了,但由于指针还未初始化, 所以它所指向的内存区是不存在的,或者说是无意义的. 以后,每遇到一个指针,都应该问问:这个指针的类型是什么?指针指的类型是什么?该指针指向了哪里? */ //四、指针本身所占据的内存区; //指针的运算符; //指针可以加上或减去一个整数,指针的这种运算的意义和通常的数值的加减运算的意义是不一样的; //例: char a[20]; int *ptr = (int *)a; ptr++; /* 对上例说明: 指针ptr的类型是Int*,它指向的类型是Int,它被初始化为指向整形变量a。接下来的第3句中,指针ptr被加了1,编译器就是这样 处理的:它把指针ptr的值加上了sizeof(int) ,在32位程序中,是被加上了4,因为在32位程序中,Int所占的是4个字节; 由于地址是用字节做单位的,在ptr所指向的地址由原来的变量a的地址向高地址方向增了4个字节。 由于char类型的长度是一个字节,所以,原来ptr是指向了数组a的第0号单元开始的四个字节,此时 指向了数组a中从第4号单元开始的四个字节。 */ }