复杂的指针声明示例:
声明 | 注释 |
---|---|
int board[8][8]; | 声明一个内含 int 数组的数组 |
int ** ptr ; | 声明一个指向指针的指针,被指向的指针指向 int |
int * risks[10] ; | 声明一个内含10个元素的数组,每个元素都是一个指向 int 的指针 |
int (*rusks) [10] ; | 声明一个指向数组的指针,该数组内含10个 int 类型的值 |
int * oof [3] [4] ; | 声明一个3*4的二维数组,每个元素都是指向 int 的指针 |
int (* uuf) [3] [4] ; | 声明一个指向3*4二维数组的指针,该数组中内含 int 类型值 |
int (* uof [3]) [4] ; | 声明一个内含3个指针元素的数组,其中每个指针都指向一个内含4个int类型的数组 |
看懂以上声明,关键要理解 *
、( )
和 [ ]
的优先级。记住下面几条规则:
- 数组名后面的
[ ]
和函数名后面的( )
具有相同的优先级。它们比*
(解引用运算符)的优先级高。因此下面声明的risk
是一个指针数组,不是指向数组的指针:int * risks[10] ;
[ ]
和( )
的优先级相同,由于都是从左往右结合,所以下面的声明中,在应用方括号之前,*
先与rusks
结合。因此rusks
是一个指向数组的指针,该数组内含10个int
类型的元素:int (* rusks ) [10] ;
[ ]
和( )
都是从左往右结合。因此下面声明的goods
是一个由12个内含50个int
类型值的数组组成的二维数组,不是一个有50个内含12个int
类型值的数组组成的二维数组:int goods[12][50];
把以上声明应用于下面的声明:int * oof [3] [4] ;
[3]
比 *
的优先级高,由于从左往右结合,所以 [3]
先与 oof
结合。因此, oof
首先是一个内含3个元素的数组。然后再与 [4]
结合,所以 oof
的每个元素都是内含4个元素的数组。其中 *
说明这些元素都是指针。最后,int
表明了这四个元素都是指向 int
的指针。因此这条声明要表达的是: oof
是一个内含3个元素的数组,其中每个元素是由4个指向 int
的指针组成的数组。简而言之,oof
是一个3*4的二维数组,每个元素都是指向 int
的指针。编译器要为12个指针预留存储空间。
下面来看下一个声明: int (* uuf) [3] [4] ;
圆括号使得 *
先与 uuf
结合,说明 uuf
是一个指针,所以 uuf
是一个指向 3*4 的 int
类型二维数组的指针。编译器要为一个指针预留存储空间。
根据这些规则还可以声明:
声明 | 注释 |
---|---|
char * fump ( int ) ; | 返回字符指针的函数 |
char ( * frump ) ( int ) ; | 指向函数的指针,该函数的返回类型为 char |
char (* flump [3] ) ( int ); | 内含3个指针的数组,每个指针都指向返回类型为 char 的函数 |
这3个函数都接受 int
类型的参数。
typedef
建立一系列相关类型:
typedef int arr5[5] ;
typedef arr5 * p_arr5 ;
typedef p_arr5 arrp10[10] ;
声明 | 注释 |
---|---|
arr5 togs ; | togs 是一个内含5个 int 类型的数组 |
p_arr5 p2 ; | p2 是一个指向数组的指针,该数组内含5个 int 类型的值 |
arrp10 ap ; | ap 是一个内含10个指针的数组,每个指针都指向一个内含5个 int 类型值的数组 |