一些包含指针概念的复杂类型,最基本的还是通过编译器来进行最基本的判断。

很多初学者由于不愿意对一些类型进行系统的认识和学习,导致一进入编程状态便受到了复杂类型的重重阻碍。因此希望看到这篇博客的学习者能坚持看完,并且希望对你以后的编程生涯有所帮助。

那么开始我们的话题吧

编译器是如何进行判断一个我们看起来那么令人头疼的复杂类型的?
答案是:优先级。
和运算的优先级一样,优先级的层层判断,可以使我们和编译器一样,推断出一个具体的类型具体是什么,推断它负责进行什么操作。

那么开始我们的解析吧。我们将从最简单的类型开始,直至你曾害怕了解的一些类型。

  1. 指针
1
int ptr;			//首先ptr是变量名,它与int结合,说明ptr是一个整型变量。
1
2
3
4
5
int *ptr;			//也些程序员习惯写成 int* ptr,这两种表示的其实都一样,看个人习惯而已。
//首先ptr是变量名。
//其次ptr与*结合,说明ptr是个指针变量。
//然后与int结合,说明ptr是一个指向int类型的指针变量。
//所以ptr是一个int* 类型的指针变量。
1
2
3
4
5
6
int **ptr;			//首先ptr是变量名。
//它首先和右边的*结合,说明ptr是一个指针类型。
//再和左边的*结合,说明ptr是一个指针,并且它指向另一个指针,即指向另一个指针的地址。
//接着与int结合,说明ptr是一个指针,并且它指向另一个指针的地址,而另一个指针必须是一个指向int类型的指针。
//所以ptr是一个int** 的指针变量。
//(这也就是大佬们常说的二级指针。同理,更复杂的多级指针也是如此推理,但是实际运用中,并不需要使用到太多级的指针)
  1. 数组
1
2
3
4
5
int ptr[10];		//首先ptr是变量名.
//然后与[ ]运算符结合,说明ptr是一个数组,
//然后与10结合,说明ptr是一个数组,并且包含10个内容。
//紧接着再和int结合。说明ptr是一个数组,并且数组内容都是int类型。
//所以ptr是一个int[10]类型的数组变量。
  1. 指针和数组的混合结构类型
1
2
3
4
5
6
int *ptr[10];		//首先ptr是变量名.
//由于[ ]的优先级比*高,所以ptr先和[ ]进行运算,说明它是一个数组。
//接着与*符号结合,说明ptr是一个数组,并且数组内容都是指针。
//最后和int结合,说明ptr是一个数组,并且数组内容都是int*类型的指针。
//所以ptr是一个int* [10]类型的数组变量。
//(简单的理解就是一组指针,也就是大佬们常说的指针数组)
1
2
3
4
5
6
int (*ptr)[10];		//首先ptr是变量名。
//由于()的优先级别属第二,所以ptr先和*结合,说明ptr是一个指针。
//然后与[ ] 结合说明ptr是一个指针,它指向一个数组,并且指向的数组中必须包含10个内容。
//最后是和int结合,说明ptr是一个指针,它指向一个数组,并且指向的数组中必须包含10个int类型的数据
//所以ptr是一个int(*)[10]类型的指针变量。
//(这个也就是大佬们常说的数组指针。不理解的学习者请和上面的指针数组细细地比较一下,上面的是一个数组,而这里是一个指针)
  1. 函数
1
2
3
4
5
int ptr(char);		//首先ptr是变量名。
//然后和()结合,说明ptr是一个函数。
//再和char结合,说明ptr是一个函数,并且传入参数是一个char类型。
//最后和int结合,说明ptr是一个函数,并且传入参数是一个char类型,返回值类型是int类型。
//所以ptr是一个int(char)类型的函数。

5.指针和函数的混合结构类型

1
2
3
4
5
6
7
int *ptr(char);		//首先ptr是变量名。
//然后和()结合,说明ptr是一个函数。
//再和char结合,说明ptr是一个函数,并且传入参数是一个char类型。
//接着与*结合,说明ptr是一个函数,并且传入参数是一个char类型,返回值类型是一个指针类型。
//最后和int结合,说明ptr是一个函数,并且传入参数是一个char类型,返回值类型是int*类型。
//所以ptr是一个int*(char)类型的函数。
//(这个也就是大佬们所说的指针函数)
1
2
3
4
5
6
7
8
int (*ptr)(char);	//首先ptr是变量名。
//然后和*结合,说明ptr是一个指针。
//接着与()结合,说明ptr是一个指针,它指向一个函数,即指向函数的地址。
//然后与char结合,说明ptr是一个指针,它指向一个函数的地址,并且该函数必须是传入参数为一个char类型的函数。
//最后是和int结合,说明ptr是一个指针,它指向一个函数的地址,并且该函数必须是传入参数为一个char类型的函数,同时该函数的返回值必须为int类型。
//所以ptr是一个int(*)(char)类型的指针。
//(这个也就是大佬们所说的函数指针)
//(对这里有疑惑的学习者,和上面的指针数组/数组指针一样,请慢慢品味指针函数和函数指针的异同)
  1. 指针,数组和函数的混合结构类型
1
2
3
4
5
6
7
8
9
10
11
12
/*
请各位学习者在理解以上例子的解释之后,再来看这个例子。
(由于上面的例子当中已经解释函数参数的结合级别内容,为了减少赘述,防止增添读者的理解难度,以下例子将一笔带过函数参数的结合级别内容)
*/

int *(*ptr(char))[10]; //首先ptr是变量名。
//然后和(char)结合,说明ptr是一个函数。
//接着与右边的*结合,说明ptr是一个函数,并且返回值是一个指针。(此时指针指向的具体类型并不知道,即返回值类型并不知道)
//然后与[10]结合,说明ptr是一个函数,并且返回值是一个指针,这个返回的指针,它指向一个有10个内容的数组。
//然后与左边的*集合,说明ptr是一个函数,并且返回值是一个指针,这个返回的指针,它指向一个数组元素为指针的数组。
//最后和int结合,说明ptr是一个函数,并且返回值是一个指针,这个返回的指针,它指向一个数组元素为int*类型的数组。
//所以ptr是一个int *(*(char))[10]类型的函数。
1
2
3
4
5
6
int (*(*ptr(char)))[10];		//首先ptr是变量名。
//然后和(char)结合,说明ptr是一个函数。
//然后和右边的*结合,说明ptr是一个函数,并且返回值是一个指针。(此时指针指向的具体类型并不知道,即返回值类型并不知道)
//然后和左边的*结合,说明ptr是一个函数,并且返回值是一个指针,该指针指向另一个指针。
//接着与[10]结合,说明ptr是一个函数,并且返回值是一个指针,该指针指向另一个指针的地址,所指向的另一个指针,必须指向包含10个内容的数组。
//最后与int结合,说明ptr是一个函数,并且返回值是一个指针,该指针指向另一个指针的地址,所指向的另一个指针,必须指向类型为int[10]的数组。