# 指针&数组、指针&函数

### 指针和数组

#### 区别

```c
int a[5]; //会创建5个 int 空间
int *b; //只会创建一个 int * 空间

*a, *b ; //前者合法，后者不合法
b++ , a++ ; //前者合法，后者不合法
```

#### 比较

在没有对数组进行优化的编译器上，指针 效率 >= 数组下标的方式

```
int array[10], a;
for (a = 0; a < 10; a += 1){
  # 此处需要运行时每次都用a乘以4（因为这里是int）
  array[a] = 0;
}

# 而这个方法中，ap ++ 时需要 1乘以4，但是是编译时执行，运行时只是加4
int *ap;
for(ap = array; ap < array + 10; ap ++){
  *ap = 0;
}
```

只有两个指针都指向同一个数组元素的时候，才允许从一个指针减去另一个指针，结果是下标的差值，是一种有符号整数类型ptrdiff\_t

#### 指针数组

```
int *api[10];
```

首先明确，这是一个定义声明\
根据操作符优先级 \[] > \
*我们先读取了 api\[10] 的定义，这表示一个数组*\
*然后我们读取了 int* 的定义，这表示整形指针类型

类似常规数组 int a\[10]; 常规指针 `int *a`;\
所以这是一个 长度为10的 包含整形指针的 数组

#### 数组指针

```
int matrix[3][10];  
int (*p)[10] = matrix;
```

我们先读取了 `*p`， 这表示一个指针

### 函数和指针

```
# &是可选的，编译器会默认处理  
int （*pf）(int) = &f;

# 使用
int result;
result = f(25);
result = (*pf)(25);
result = pf(25);
```

### 指针、函数、数组

这一块会比较混乱，可以尝试使用unix系统，获取cdecl程序，可以解释一个声明。。

```
cdecl> explain int (*(*f)())[10];
```

源码在comp.sources.unix.newsgroup
