C 编程/语言参考
非常旧的编译器可能无法识别一些或所有 C89 关键字 const
, enum
, signed
, void
, volatile
,以及任何更高版本的关键字。
|
|
|
|
这些在大多数新的编译器中都受支持。
|
|
这些仅在一些较新的编译器中受支持。
|
|
|
虽然从技术上讲不是关键字,但支持 C99 的预处理器/编译器还识别特殊预处理器运算符 _Pragma
,它充当 #pragma
指令的替代形式,可以从宏展开中使用。例如,以下代码将导致一些编译器(包括 GCC、Clang)发出诊断消息。
#define EMIT_MESSAGE(str) EMIT_PRAGMA(message(str))
#define EMIT_PRAGMA(content) _Pragma(#content)
EMIT_MESSAGE("Hello, world!")
一些编译器使用略微不同的语法;特别是,MSVC 支持 __pragma
而不是 _Pragma
。
特定编译器也可以(在非标准兼容模式下,或使用额外的语法标记,如 __extension__
)将其他一些词视为关键字,包括 asm
, cdecl
, far
, fortran
, huge
, interrupt
, near
, pascal
, 或 typeof
。但是,它们通常允许在标准兼容模式下通过声明覆盖这些关键字(例如,通过定义一个名为 typeof
的变量),以避免与现有程序产生不兼容性。为了确保编译器可以维护对扩展功能的访问,这些编译器通常有一组以两个下划线 (__
) 开头的专用关键字。例如,GCC 对 asm
, __asm
和 __asm__
的处理方式大致相同,但后两者始终保证具有预期的含义,因为它们不能被覆盖。
许多新引入的关键字(即那些以下划线和大写字母开头的关键字,如 _Noreturn
或 _Imaginary
)在大多数情况下仅用于间接使用。相反,程序员应该更倾向于使用标准头文件,如 <stdbool.h>
或 <stdalign.h>
,这些头文件通常使用预处理器来建立关键字的全小写变体(例如,
或 complex
)。这些头文件的作用是使 C 和 C++ 代码以及针对不同编译器或语言版本的代码能够更干净地互操作。例如,通过包含 noreturn
<stdbool.h>
,
、bool
和 true
标记可以在 C99 或 C++ 中以相同的方式使用,而无需在 C99 中显式使用 false
_Bool
或在 C++ 中显式使用 bool
。
另请参阅保留标识符列表[1]。
此表中同一行的运算符具有相同的优先级,而求值的顺序由结合性决定(从左到右或从右到左)。表中越靠前的运算符优先级越高,表中越靠后的运算符优先级越低。
运算符 | 描述 | 示例用法 | 结合性 |
---|---|---|---|
后缀运算符 | 从左到右 | ||
() |
函数调用运算符 | swap (x, y)
| |
[] |
数组索引运算符 | arr [i]
| |
. |
成员访问运算符 对于结构体/联合类型 或对它的引用 |
obj.member
| |
-> |
成员访问运算符 对于指向结构体/联合类型 对象的指针 |
ptr->member
| |
一元运算符 | 从右到左 | ||
! |
逻辑非运算符 | !eof_reached
| |
~ |
按位非运算符 | ~mask
| |
+ - [2]
|
一元加/减运算符 | -num
| |
++ -- |
后置递增/递减运算符 | num++
| |
++ -- |
前置递增/递减运算符 | ++num
| |
& |
取地址运算符 | &data
| |
* |
间接寻址运算符 | *ptr
| |
sizeof |
sizeof 运算符 用于表达式 | sizeof 123
| |
sizeof() |
sizeof 运算符 用于类型 | sizeof (int)
| |
(类型) |
类型转换运算符 | (float)i
| |
乘法运算符 | 从左到右 | ||
* / % |
乘法、除法和 模运算符 |
celsius_diff * 9.0 / 5.0
| |
加法运算符 | 从左到右 | ||
+ - |
加法和减法运算符 | end - start + 1
| |
按位移位运算符 | 从左到右 | ||
<< |
左移运算符 | bits << shift_len
| |
>> |
右移运算符 | bits >> shift_len
| |
关系不等式运算符 | 从左到右 | ||
< > <= >= |
小于、大于、小于或 等于、大于或等于 运算符 |
i < num_elements
| |
关系等式运算符 | 从左到右 | ||
== != |
等于、不等于 | choice != 'n'
| |
按位与运算符 | 从左到右 | ||
& |
bits & clear_mask_complement
| ||
按位异或运算符 | 从左到右 | ||
^ |
bits ^ invert_mask
| ||
按位或运算符 | 从左到右 | ||
| |
bits | set_mask
| ||
逻辑与运算符 | 从左到右 | ||
&& |
arr != 0 && arr->len != 0
| ||
逻辑或运算符 | 从左到右 | ||
|| |
arr == 0 || arr->len == 0
| ||
条件运算符 | 从右到左 | ||
?: |
size != 0 ? size : 0
| ||
赋值运算符 | 从右到左 | ||
= |
赋值运算符 | i = 0
| |
+= -= *= /=
|
简写赋值运算符 ( foo op= bar 代表foo = foo op bar ) |
num /= 10
| |
逗号运算符 | 从左到右 | ||
, |
i = 0, j = i + 1, k = 0
|
类型 | 大小(以位计) | 注释 | 备用名称 |
---|---|---|---|
ANSI C (C89)/ISO C (C90) 中的原始类型 | |||
char |
≥ 8 |
|
— |
signed char |
与 char 相同 |
|
— |
unsigned char |
与 char 相同 |
|
— |
short |
≥ 16, ≥ char 的大小 |
|
short int , signed short , signed short int |
unsigned short |
与 short 相同 |
|
unsigned short int
|
int |
≥ 16,≥ short 的大小 |
|
signed ,signed int |
unsigned int |
与 int 相同 |
|
unsigned
|
long |
≥ 32,≥ int 的大小 |
|
long int ,signed long ,signed long int |
unsigned long |
与 long 相同 |
|
unsigned long int
|
float |
≥ char 的大小 |
|
— |
double |
≥ float 的大小 |
|
— |
long double |
≥ double 的大小 |
|
— |
添加到 ISO C(C99)的原始类型 | |||
long long |
≥ 64,≥ long 的大小 |
|
long long int ,signed long long ,signed long long int |
unsigned long long |
与 long long 相同 |
|
unsigned long long int
|
intmax_t |
平台支持的最大宽度 |
|
— |
uintmax_t |
与 intmax_t 相同 |
|
— |
用户定义类型 | |||
struct |
≥ 每个成员大小的总和 |
|
— |
union |
≥ 最大成员的大小 |
|
— |
enum |
≥ char 的大小 |
|
— |
typedef |
与正在命名的类型相同 |
|
— |
派生类型[7] | |||
类型* (指针) |
≥ char 的大小 |
|
— |
类型 [整数[8]] (数组) |
≥ 整数 × 类型 的大小 |
|
— |
类型 (逗号分隔的类型/声明列表) (函数) |
— |
|
— |
用 C 编写的程序可以读取和写入任何字符集,前提是包含/使用了支持它们的库。
但是,C 程序的源代码通常限于 ASCII 字符集。
在包含源代码的文件中,行的结尾有时取决于它创建所在的系统,而不是换行符,但编译器将每行的结尾视为单个换行符。
几乎所有编译器都允许字符串常量中使用 $、@ 和 ` 字符。许多编译器也允许文字多字节 Unicode 字符,但它们不可移植。
某些字符必须用反斜杠转义才能在字符串或字符常量中表示自身。这些是
|
|
|
此外,一些编译器允许以下字符
\r
回车\a
警报(可听见的铃声)\b
退格
\xhh,其中 'h' 字符是十六进制数字,用于表示任意字节(包括 \x00,即零字节)。
\uhhhh 或 \Uhhhhhhhh,其中 'h' 字符是十六进制数字,用于可移植地表示 Unicode 字符。
- ↑ http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/topic/com.ibm.vacpp7a.doc/language/ref/clrc02reserved_identifiers.htm 保留标识符列表
- ↑ 非常旧的编译器可能无法识别一元
+
运算符。 - ↑ -128 可以存储在二进制补码机器(即大多数现有的机器)中。非常旧的编译器可能无法识别
signed
关键字 - ↑ a b -32768 可以存储在二进制补码机器(即大多数现有的机器)中。非常旧的编译器可能无法识别
signed
关键字 - ↑ -2147483648 可以存储在二进制补码机器(即大多数现有的机器)中。非常旧的编译器可能无法识别
signed
关键字 - ↑ -9223372036854775808 可以存储在二进制补码机器(即大多数现有的机器)中
- ↑ 标准没有对整数的大小/类型有任何限制,它是由实现定义的。标准中唯一提到的内容是,实现可能有内存块最大大小的限制,因此整数的限制将为 size_of_max_block/sizeof(type)
- ↑ 标准没有对整数的大小/类型有任何限制,它是由实现定义的。标准中唯一提到的内容是,实现可能有内存块最大大小的限制,因此整数的限制将为 size_of_max_block/sizeof(type)