一、指针与数组
1、数组指针(数组的指针)
//数组的指针 (数组指针)
int (*risk)[10]; //一个指针,该指针指向一个元素为10个int类型的数组
2、指针数组(指针的数组)
//指针的数组 (指针数组)
int * risk[10]; //一个内含10个元素的数组,数组的元素是指针
int board[8][8];
//二维数组,声明一个内含int数组的数组
int **ptr;
//一个指向指针的指针,被指向的指针指向int类型数据
int *risk[10]; //指针的数组 (指针数组)
//一个内含10个元素的数组,数组的元素是指针
int (*risk)[10]; //数组的指针 (数组指针)
//一个指针,该指针指向一个元素为10个int类型的数组
int *oof[3][4]; //指针的二维数组
//一个二维数组,该数组的每个元素是一个int类型的指针
int (*oof)[3][4]; //二维数组的指针
//一个指针,该指针指向一个3*4的二维数组
int (*uof[3])[4]; //一维数组的指针的数组
//一个数组,该数组有3个元素,每个元素是指向一个有4个int类型元素的数组的指针
理解以上的声明,关键是理解 *、( )、[ ]的优先级。有以下规则
数组名后面的 [ ] 和函数名后面的()具有相同的优先级,他们比 *(解引用运算符)的优先级高
int * risk[10];
//根据[]的优先级更高,所以首先是有10个元素的数组,然后每个元素是一个int 类型类型的指针
( ) 与 [ ] 的优先级相同,所以都是从左往右结合
int (*risk)[10];
//从左往右,首先是一个指针,该指针指向一个元素为10个int类型的数组
( )与 [ ] 从左往右结合
int board[10][8];
//二维数组,是一个由10个内含8个int类型的值组成的二维数组,
//而不是一个由8个内含10个int类型的值组成的二维数组
二、指针与函数
```c char *fump(int);
//一个函数,返回字符指针的函数
char (*frump)(int);
//一个指向函数的指针,该函数的返回值是char类型,参数是一个 int类型的参数
char (*frump[3])(int); //一个内含3个元素的数组,每个元素是指向函数的指针,函数的返回值是char类型,参数是一个 int类型的参数
char (frump[3])(int); //一个内含3个元素的数组,每个元素是指向函数的指针,函数的返回值是char类型指针,参数是一个 int类型的参数
char ((x(int))[3])(int);
//一个函数,返回的是一个指针,指针指向内含三个元素的一维数组,其数组的元素是指向函数的指针,指针指向的函数返回值是char类型,参数是int类型
char ((x[3])(int))[5];
//一个内含3个元素数组,每个元素是指向函数的指针,函数的返回值是一个指针,指针指向有5个char类型元素的一维数组
<a name="oB4nv"></a>
#### 需要注意一些陷阱:(非法的声明)
<a name="MwO4r"></a>
##### 陷阱1
```c
//非法版本
char fun(int)[N];
//按照运算优先级,fun是一个函数,返回值是一个有N个元素的一维数组;这里的陷阱是函数只能返回标量值,不能返回数组。
//正确版本
char (*fun(int))[N];
//这样就对了,一个函数,返回的是一个指针,该指针指向一个内含N个元素的一维数组;
陷阱2
//非法版本
char fun[N](int);
//按照运算优先级,是一个数组,数组的元素是函数;这显然不对,函数的长度不太可能长度一致;
//正确版本
char (*fun[N])(int);
/一个数组,元素是指针,指向一个返回值是char的函数
三、常量指针与指针常量
const int *p; //常量指针,指向常量的指针。即p指向的内存可以变,p指向的数值内容不可变
int const *p; //同上
int* const p; //指针常量,本质是一个常量,而用指针修饰它。 即p指向的内存不可以变,但是p内
存位置的数值可以变
const int* const p;//指向常量的常量指针。即p指向的内存和数值都不可变
总结
根据运算优先级,确定声明的基础类型(最先开始的“运算”)。