第18章 声明
{% markmap %}
第18章 声明
声明的语法
- 声明说明符
- 存储类型
- 存储类型一共有4种:auto、static、extern和register。
- 要放到最前面
- 类型限定符
- C89只有两种类型限定符:const和volatile。C99还有一个限定符restrict。
- 类型说明符
- 关键字void、char、short、int、long、float、double、signed和unsigned都是类型说明符。
- 函数说明符
- 关键字inline
- 存储类型
存储类型
- 3个性质
- 存储期限
- 变量的存储期限决定了为变量预留和内存被释放的时间。
- 作用域
- 块作用域
- 文件作用域
- 链接
- 外部链接
- 内部链接
- 存储期限
- 4种类型
- auto类型
- 自动存储期限、块作用域、无链接
- static类型
- 块内部
- 静态存储期限、块作用域、无链接
- 块外部
- 静态存储期限、文件作用域、内部链接
- 块内部
- extern类型
- 块内部
- 静态存储期限、块作用域
- 块外部
- 静态存储期限、文件作用域
- 新节点
- 静态存储期限、文件作用域
- 如果在文件头部被static修饰,则具有内部链接,否则是外部链接
- 块内部
- register类型
- 自动存储期限、块作用域、无链接
- 指明变量的存储类型是register是一种请求,而不是命令。
- register存储类型只对声明在块内的变量有效。
- 由于寄存器没有地址,所以对register变量使用取地址运算符&是非法的。即使编译器选择把变量存储在内存中,这一限制仍适用。
- 在这4种存储类型之中,最重要的是extern和static。auto没有任何效果,而现代编译器已经使register变得不如以前重要了。
- auto类型
- 变量的存储类型
- 全局变量默认extern,局部变量默认auto
int a;
extern int b;
static int c;
void f(int d, register int e)
{
auto int g;
int h;
static int i;
extern int j;
register int k;
}
- 函数的存储类型
- 只有extern和static两个
- 函数默认是extern
- 函数形参的存储类型
- auto
类型限定符
const
const
和define
volatile
- 见下面底层程序设计
声明符
- 识别声明符的简单规则
- 1、始终从内往外读声明符
- 2、在做选择的时候,始终
[]
和()
优于*
- 例如
int *ap[10];
- 指针数组
float *fp(float);
- 返回值为float指针的函数
void (*pf)(int);
- 函数指针
- 复杂的声明符
int *(*x[10])(void);
- 1、首先,最接近x的是
[]
,所以它是一个数组 - 2、然后是指针数组
- 3、函数指针数组
- 4、返回值为int指针的函数指针数组
- 1、首先,最接近x的是
- 使用类型定义来简化声明
初始化式
内联函数
inline double average(double a, double b)
{
return (a + b) / 2;
}
- “内联”表明编译器把函数的每一次调用都用函数的机器指令来代替。这种方法虽然会使被编译程序的大小增加一些,但是可以避免函数调用的常见额外开销。
- 内联函数要求
- 函数中不能定义可改变的static变量。
- 函数中不能引用具有内部链接的变量。
- 关于GCC最后需要注意的是:仅当通过-O命令行选项请求进行优化时,才会对函数进行“内联”。
- 但是这个关键词只是建议,不是强制