一、此文产生的背景:
相较其他语言而言,c语言的规则相对不算多,并且c语言偏向底层非常灵活。c语言中的指针被普遍认为是一个难点,不过个人认为:指针本身并不难,无非就是指向某一块存储空间的地址,倒是指针与指针、数组、结构、函数等的组合倒是很容易把初学者绕晕。于是此文主要谈一下我是如何理解这些概念的,借此与各位伙伴沟通交流。
二、关于指针与与指针、数组、结构、函数的组合及其扩展
指针可以与指针、数组、结构、函数进行任意的、有顺序的组合,于是就产生了:指针的指针、指针数组、数组指针、内含指针的结构、结构指针、指针函数(返回指针的函数)、函数指针。
类似的,理论上数组也可以与指针、数组、结构、函数进行任意的、有顺序的组合,但实际应用中我们常常会把数组与指针、数组、结构进行任意的、有顺序的组合,于是就产生了:数组指针、指针数组、二维数组(数组的数组)、内含数组的结构、结构数组。函数数组通常不会有,较为常见的是函数指针数组。通常不会出现数组函数,个人认为主要是因为如果返回值是数组的话,函数头的返回值类型会写成指针。
三、如何理解数组、指针与指针、数组、结构、函数结合后的概念
要想理解上述概念,个人认为主要是*、( )、和[ ]这三个符号组合的时候具有迷惑性,因此最重要的是理解*、( )、和[ ]的优先级和结合性。其中*(解引用运算符)的优先级最低,数组名后面的[ ]和函数名后面的( )具有相同的优先级。并且这3个符号都是从左往右结合的。接下来进行详细说明,进行解释的概念不仅包括:数组的数组(二维数组)、指针的指针、指针数组、数组指针、内含指针的结构、结构指针、指针函数(返回指针的函数)、函数指针、内含数组的结构、结构数组、函数指针数组,同时还列举了:内含指针元素的二维数组、指向二维数组的指针、内含数组指针的一维数组(或指向一维数组的指针数组)。
int arr[3][5]:arr是一个数组,该数组内含3个元素,每个元素都是内含5个int元素的数组。故arr是内含一维数组的二维数组,常简称为二维数组。
int** ptr:ptr是一个指针,该指针指向一个int类型的指针。故ptr是指向指针的指针。
int* parr[10]:因[ ]优先级比*高,所以parr是一个数组,该数组内含10个元素,每个元素都是指向int类型的指针。故parr是内含指针元素的一维数组,常简称为指针数组。
int (* arrp)[10]:因()与[ ]具有相同的优先级,故根据结合性从左向右看,arrp首先是一个指针,该指针指向一个内含10个int类型元素的数组。故arrp是一个指向一维数组的指针,常简称为数组指针。
int* oof[3][4]:因[ ]优先级比*高,所以oof是一个数组,该数组内涵3个元素,每个元素都是内含4个元素的一维数组(或者二维数组比较熟悉的同学可以直接说 oof首先是一个二维数组),该一维数组的每个元素都是指向int类型的指针。故oof是一个内含指针元素的二维数组。
int (* uuf)[3][4]:因()与[ ]具有相同的优先级,故根据结合性从左向右看,uuf首先是一个指针,该指针指向一个数组,被指向的这个数组内含3个元素,这3个元素每个都是内含4个int类型元素的一维数组,(对二维数组比较熟悉的同学可以直接说 uuf这个指针指向一个3X4的二维数组)。故uuf是一个指向二维数组的指针。
int (* uof[3])[4]:根据[ ]、()和*的优先级和结合性,uof首先是一个内含3个元素的数组,每个元素都是一个指针,该指针指向一个内含4个int类型元素的数组。故uof是一个内含数组指针的一维数组或指向一维数组的指针数组。
struct book{char* title; char* author; double value}:book首先是一个结构,该结构的有2个成员都是一个指针,故book是一个内含指针的结构。
struct book* pbook:pbook是一个指针,该指针指向一个结构类型,故pbook是指向结构的指针,常简称为结构指针。
struct book{char title[81]; char author[81]; double value}:book首先是一个结构,该结构的有2个成员都是一个数组,故book是一个内含数组的结构。
struct book books[10]:books是一个一维数组,给数组的每一个元素都是一个struct book结构,故books是内含结构元素的数组,常简称为结构数组。
char* fump(int):因()优先级比*高,所以fump首先是一个函数,该函数的返回值是一个字符指针,故fump是返回值为指针的函数,可简称为指针函数。
char (* frump)(int):frump首先是一个指针,该指针指向一个返回值为char的函数,故frump是指向函数的指针,常简称为函数指针。
char (* flump[3])(int):因[ ]优先级比*高,所以flump首先是一个内含3个元素的数组,每个元素都是一个指针(对指针数组熟悉的伙伴可直接将flump看作是一个指针数组),每个指针元素都指向一个返回值为char的函数,故flump是内含函数指针的一维数组或指向函数的指针数组,可简称为函数指针数组。