C 参考手册
- C 语言
- C 的历史
- 基本概念
- 表达式
- 声明
- 初始化
- 函数
- 语句
- 静态断言
- 字符常量
- 函数声明
- 函数定义
- 转义序列
- 翻译阶段
- 标识符
- 作用域
- 生存期
- 查找与命名空间
- ASCII 码表
- 类型
- 遵从性
- 算术类型
- restrict 类型限定符
- 类型
- 对象与对齐
- 主函数
- 未定义行为
- 内存模型
- if 语句
- switch 语句
- for 循环
- while 循环
- do-while 循环
- continue语句
- break 语句
- goto语句
- return 语句
- 值类别
- 求值顺序
- 整数常量
- 浮点常量
- 字符串字面量
- 复合字面量
- 常量表达式
- 隐式转换
- 成员访问运算符
- 逻辑运算符
- 比较运算符
- 算术运算符
- 赋值运算符
- 自增/自减运算符
- 其他运算符
- sizeof 运算符
- _Alignof 运算符
- 转型运算符
- C 运算符优先级
- 泛型选择
- 标量初始化
- 数组初始化
- 结构体与联合体初始化
- 指针声明
- 数组声明
- 枚举
- 存储类指定符
- const 类型限定符
- volatile 类型限定符
- 结构体声明
- 联合体声明
- 位域
- _Alignas
- typedef 声明
- 原子类型
- 外部及试探性定义
- inline 函数指定符
- _Noreturn 函数指定符
- 变长参数
- 内联汇编
- 可分析性
- 替用运算符及记号
- C 关键词
- 预处理器
- C 标准库头文件
- 类型支持
- 程序支持工具
- 变参数函数
- 错误处理
- 动态内存管理
- 日期和时间工具
- 字符串库
- 算法
- 数值
- 文件输入/输出
- 本地化支持
- 原子操作库
- 线程支持库
- 实验性 C 标准库
- 有用的资源
- 符号索引
- 注释
const 类型限定符
C 类型系统中每一个独立的类型在都有数个该类型的限定版本,对应 const 、 volatile及对于指向对象指针的 restrict 限定符中的一个、两个或全部三个。此页面描述 const 限定符的效果。
编译器可以把声明带 const 限定类型的对象放到只读内存中,而且若程序决不取该 const 对象的地址,则可能完全不存储它。
const
语义仅应用到左值表达式;只要在不要求左值的语境中使用 const 左值表达式,就会丢失其 const
限定符(注意不丢失 volatile
限定符,若它存在)。
指代 const 限定类型对象的左值表达式,和指代拥有至少一个 const 限定类型成员(包含为聚合体或联合体所递归含有的成员)的结构体或联合体的左值表达式,不是可修改左值。具体而言,它们不可赋值:
const int n = 1; // const 类型对象 n = 2; // 错误: n 的类型为 const 限定 int x = 2; // 无限定类型对下 const int* p = &x; *p = 3; // 错误:左值 *p 的类型为 const 限定 struct {int a; const int b; } s1 = {.b=1}, s2 = {.b=2}; s1 = s2; // 错误: s1 的类型无限定,但它有 const 成员
const 限定的结构体或联合体类型的成员,取得它所属类型的限定版本(在用 .
运算符或 ->
运算符访问时)。
struct s { int i; const int ci; } s; // s.i 的类型为 int , s.ci 的类型为 const int const struct s cs; // cs.i 和 cs.ci 的类型都是 const int
若以 const 类型限定符声明数组类型(通过使用 typedef ),则数组类型无 const 限定,但其元素类型有。若以 const 类型限定符声明函数类型(通过使用 typedef ),则行为未定义。
typedef int A[2][3]; const A a = {{4, 5, 6}, {7, 8, 9}}; // const int 的数组的数组 int* pi = a[0]; // 错误: a[0] 拥有 const int* 类型
const 限定的复合字面量不必指代相异的对象;能与恰好拥有重叠表示的其他复合字面量和字符串字面量一同存储它们。 const int* p1 = (const int[]){1, 2, 3}; const int* p2 = (const int[]){2, 3, 4}; // p2 的值可等于 p1+1 _Bool b = "foobar" + 3 == (const char[]){"bar"}; // b 的值可为 1 |
(C99 起) |
指向非 const 类型的指针能隐式转换成指向同一或兼容类型的 const 限定版本的指针。能用转型表达式进行逆向转换。
int* p = 0; const int* cp = p; // OK :添加限定符( int 到 const int ) p = cp; // 错误:舍弃限定符( const int 到 int ) p = (int*)cp; // OK :转型
注意指向指向 T
指针的指针不可转换为指向指向 const T
指针的指针;对于要兼容的二个类型,其限定必须等同。
char *p = 0; const char **cpp = &p; // 错误: char* 与 const char* 不是兼容类型 char * const *pcp = &p; // OK :添加限定符( char * 到 char *const )
任何修改有 const 限定类型的对象的尝试导致未定义行为。
const int n = 1; // const 限定类型对象 int* p = (int*)&n; *p = 2; // 未定义行为
函数声明中,关键词 下列二个声明声明同一函数: void f(double x[const], const double y[const]); void f(double * const x, const double * const y); |
(C99 起) |
关键词
注意
C 从 C++ 接纳了 const 限定符,但不同于 C++ 中, C 中 const 限定类型的表达式不是常量表达式;它们不可用作 case 标号,或用于初始化静态和线程存储期对象、用作枚举项或位域大小。以之为数组大小是,产生的数组为 VLA 。
引用
- C11 standard (ISO/IEC 9899:2011):
- 6.7.3 Type qualifiers (p: 121-123)
- C99 standard (ISO/IEC 9899:1999):
- 6.7.3 Type qualifiers (p: 108-110)
- C89/C90 standard (ISO/IEC 9899:1990):
- 3.5.3 Type qualifiers