C 学习笔记

float(**def)[10];  def为二维指针,这个二维指针指向一个一维指针,这个一维指针指向一个数组,数组类型为float[10]
解析:从标示符开始(**def),def的右边无类型,左边是一个*,所以p是一个指针,然后*p的左边是*,说明p是一个指向指针的指针,接着(**def)的右边是[10],说明p指向的指针指向一个含10个元素的数组,(**def)的左边是float,说明该数组的元素都是float类型的。

double*(*gh)[10];  gh是一个指针,这个指针指向一个数组,数组的类型为double*[10],即数组大小为10,元素类型为double*
解析:先从标示符开始(*gh),gh是一个指针,(*gh)的右边是[10],说明p指向的是一个含10个元素的数组,(*gh)的左边是double*,说明gh指向的数组的数组元素的类型都是double*。

double(*f[10])();  f是一个数组,这个数组的大小为10,每个元素是一个函数指针即double(*)()
 
int*((*b)[10]);    左右法则,b代表一个指针,指向一个数组,数组大小为10,数组元素为int*

long(**fun)(int(*a)[10]); fun是一个二级指针,指向一个函数指针,这个函数指针指向的函数返回值为long参数为一个指针,指向一个大小为10的整型数组。
解析:从标示符开始(**fun),说明fun是一个二维指针,(**fun)的右边是(int(*a)[10]),从(int(*a)[10])的右往左分析,a是一个指针,指向一个含10个int类型的元素。
抛开long(*)(int(*a)[10]) 则*fun是个函数指针。返回值是long,参数是 int(*a)[10]

实际的工程中都会用typedef来提高可读性的。

1、int **p; //p指向一个int*的变量,它是指向指针的指针。

2、void (*p)(void); //p指向一个函数,该函数不接收参数,也不返回值。
解析:这是函数指针的用法,*p两边的括号不能少,例如void *p(void);p是一个函数,这个函数不接收参数,返回一个void*指针,并且这是个函数的声明。*p加上括号后,使得编译器先看到了*p(即()能改变申明及定义时的优先级规则,否则编译器就从右往左来识别变量的类型)这样p即使一个指针,然后往右发现(void),这就可以表示p是一个函数指针,因为遇到一对括号,并且这个括号里有东西,括号里面是void,则说明指向的这个函数不接收参数,最后在左边发现void说明指向的这个函数不返回值。

3、int (*p)(int,int);//p指向一个函数,该函数接收两个int参数,并且返回一个int。
解析:在声明和定义时,编译器是从标示符开始的,先看标示符的右边,然后左边,然后上次右边的右边,然后上次左边的左边。。。。所以这里你,*p被括号包起来了,所以先与*结合,p就成了一个指针,然后往右发现(int,int)说明p是一个函数指针,指向的这个函数接收两个int参数,最后看左边,说明函数返回一个int。

4、void (**p)(void);//p是指向一个函数的指针,它指向的指针指向的函数不接收参数也不返回值,它是指向指针的指针。
解析:先从标示符开始(**p),则p是一个指针并且指向另一个指针(二维指针),往右,发现了(void),说明p指向的指针是一个函数指针,这个函数不接收参数,最后最左边发现void,说明p指向的指针指向的函数不返回值,所以,p是一个指向函数指针的指针。

5、void (*p[10])(void);//p是一个数组,每个元素都是一个指针,并且每个元素都指向一个函数,这个函数不接收参数也不返回参数。
解析:先从标示符开始(*p[10]),然后从右往左,p的右边是[10],说明p是一个数组有10个元素,然后左边是*,说明这个数组的而每个元素都是指针;然后在从右往左,(*p[10])的右边是(void),所以这个数组的每个元素都是一个函数指针并且该函数不接收参数,最后(*p[10])的左边是void,说明这个函数不返回值,所以p实际上是一个函数指针的数组。

6、void (*(*p)[10])(void);//p是一个指针,它指向一个有10个元素的数组,这个数组的每一个元素都是一个指针,并且每个元素都指向一个不接收参数也不返回参数的函数。
解析:先从标识符开始(*(*p)[10]),p是一个指针,然后(*p)的右边是[10],说明p是指向一个有10个元素的数组,然后(*p)的左边是*,说明这个数组的每个元素都是指针;接着看(*(*p)[10])右边是(void),说明这个数组的每个元素都指向一个函数并且函数不接收参数,最后是(*(*p)[10])的左边是void,说明该函数不返回值。所以p是一个有10个函数指针数组的指针。

7、int (*(*p)(void))[10];//p是一个指针,它指向一个函数,这个函数不接收参数,并且返回一个指针,这个指针指向10个int数组。
解析:先从标示符(*(*p)(void))开始,p是一个指针,(*p)的右边是(void),说明p是一个函数指针并且该函数不接收参数,然后(*p)的左边,是*,说明p指向的函数返回一个指针;接着(*(*p)(void))的右边是[10],说明这个函数返回的指针指向一个有10个元素的数组,最后左边,发现int,说明这个数组的每个元素都是int。

8、void (*(*p)(void)(void);//p是一个指针,它指向一个函数,这个函数不接收参数,并且返回一个指针,这个指针也指向一个函数,这个函数不接收参数,也不返回值。
解析:先看标示符(*(*p)(void),p是一个指针,(*p)的右边是(void),说明p是一个函数指针,指向的函数不接收参数,(*p)的左边是*,说明p指向的函数的返回值是一个指针。接着看(*(*p)(void)右边是(void),说明返回的这个指针时一个函数指针并且这个函数不接收参数,最后(*(*p)(void)左边是void,说明返回函数指针指向的函数没有返回值,所以,p是一个函数指针,并且指向的这个函数也返回一个函数指针。

9、int* (*(*(*p)[10])(int))(int,int);//p 是一个指针,这个指针指向大小为 [10] 的数组,并且数组的每个元素都是指针,这些指针指向一个函数,函数接收一个 int 的变量,这个函数返回一个指针,而这个指针又指向一个函数,该函数接收两个 int 变量,并且返回一个指向 int 型变量的指针
解析:先从标示符(*(*(*p)[10])(int))开始,p是一个指针,(*p)的右边是[10],说明p指向的是一个含有10个元素的数组,(*p)的左边*,说明p所指向的这个数组的数组元素都是一个指针,然后(*(*p)[10])的右边是(int),说明数组元素的指针指向的是一个函数,该函数的参数为int,(*(*p)[10])的左边是*,说明指向的函数的返回值是一个指针;接着(*(*(*p)[10])(int))的右边是(int,int),说明p指向的数组的数组元素指向的函数的返回指针指向一个函数,该函数接收两个int参数,并且返回int*指针。所以p是一个数组指针,指向的数组的数组元素是一个函数指针,函数指针指向的函数返回一个函数指针,该函数带2个int参数,返回int*。

const int* p;
解析:从标示符开始,p的右边没有类型,所以看左边发现*,说明p是一个指针,然后继续左边发现int,说明p是一个指向int类型的指针,最后最左边为const,说明p指向的这个int是const只读类型。因此,p是一个指向只读变量或常量的指针。

int const *p;
解析:从标示符开始,p右边没有类型,所以看左边发现*,说明p是一个指针,然后继续左边发现const,说明p指向的数据时只读的,最后最左边是int,说明它指向的这个只读数据的类型是int。因此,p是一个指向只读变量或常量的指针。

const int* const p;
解析:从标示符开始,p右边没有类型,所以看左边发现const,说明p是一个只读变量,然后左边发现*,说明p是一个指针(但是它只能指向一个地方),然后再左边发现int,则它指向的数据类型是int,最后左边发现const,则它指向的是一个只读int或一个int常量。

int const* const p;
解析:从标示符开始,p右边没有类型,所以看左边发现const,说明p是一个只读变量,然后左边发现*,说明p是一个指针(但是它只能指向一个地方),然后再左边发现const,说明p指向的一个不可改变的对象。
const如果在*的左边,则代表这个指针指向一个不可改变的对象,在*号右边则代表这个变量它自己是只读的。

原文地址:https://www.cnblogs.com/zhou2011/p/2919170.html