声明:本文仅为个人学习总结,还请批判性查看,如有不同观点,欢迎交流。另,配图源自互联网…
摘要
总结C语言的部分基础概念,主要包括四部分:关键字、基本数据类型(整型/浮点型/字符型)、基于标准输入/输出流的格式化输入/输出函数、运算符,后面三个部分可以分别归类为:数据的表示、数据的输入/输出、数据的处理。
1、标识符和关键字
1.1 标识符(identifier)
- 定义:在程序中,变量、函数、宏和其他实体的名字;
- 组成:可以含有字母(区分大小写)、数字和下划线;(在C99中,标识符还可以使用某些“通用字符名”)
- 格式:必须以字母或者下划线开头。
1.2 关键字(keyword)
关键字对编译器而言有着特殊的意义,不能作为标识符来使用。
下表根据类别对关键字进行分组,包括 C89/C90 关键字(32个)、C99 新增关键字(5个)、C11 新增关键字(7个)
序号 | 类别 | 关键字 | C版本 | 说明 |
---|---|---|---|---|
1 | 基本数据类型 | int | C89 | 整型数据,通常为编译器指定的机器字长。 |
2 | char | C89 | 指定字母和其他字符,或表示较小的整数,属于整型数据的一种。 | |
3 | float | C89 | 单精度浮点型数据,属于浮点数据的一种。 | |
4 | double | C89 | 双精度浮点型数据,属于浮点数据的一种。 | |
5 | void | C89 | 声明函数无返回值或无参数,声明无类型指针。 | |
6 | _Bool | C99 | 属于无符号整数类型,只能存储0(表示假)或1(表示真)。 | |
7 | _Complex | C99 | 复数浮点型(如 float _Complex 表示实部和虚部都是 float 类型的值)。 | |
8 | _Imaginary | C99 | 虚数类型,只有虚部(如 float _Imaginary 表示虚部是 float 类型的值)。 | |
9 | 基本类型变式 | short | C89 | 提供基本整数类型的变式,短整型数据。 |
10 | long | C89 | 提供基本整数类型或 double 的变式,长整型数据,扩展精度浮点型数据。 | |
11 | unsigned | C89 | 提供基本整数类型的变式,无符号数据类型。 | |
12 | signed | C89 | 提供基本整数类型的变式,有符号数据类型。 | |
13 | 其它数据类型 | struct | C89 | 结构体声明,把多种信息都放在一个单元内。 |
14 | union | C89 | 共用体声明,成员共享相同的存储空间,同一时间内只能有一个成员。 | |
15 | enum | C89 | 枚举声明,声明符号名称来表示整型常量,提高程序的可读性。 | |
16 | 存储类别说明符 | typedef | C89 | 为某一类型自定义名称【与内存存储无关,根据语法归类,不能在声明中使用多个存储类别说明符(_Thread_local 和 static/extern 例外)】 |
17 | 存储类别说明符 | auto | C89 | 指定为自动变量,由编译器自动分配及释放。通常在栈上分配。只能用于块作用域的变量声明。主要是为了明确表达要使用与外部变量同名的局部变量的意图。 |
18 | register | C89 | 指定为寄存器变量,建议编译器将变量存储到寄存器中使用,以最快速度访问。只用于块作用域的变量,保护变量地址不被获取。 | |
19 | static | C89 | 指定为静态变量,分配在静态变量区。载入程序时创建对象,当程序结束时对象消失。修饰函数时,指定函数作用域为文件内部。 | |
20 | extern | C89 | 再次声明在别处已定义过的变量或函数。 | |
21 | _Thread_local | C11 | 对象具有线程存储期,在该线程运行期间一直存在,且在线程开始时被初始化,为线程私有,不能在多线程之间共享。 | |
22 | 类型限定符 | const | C89 | 不能改变初始化以后的 const 变量。 |
23 | volatile | C89 | 变量在程序执行中可能被隐含地改变。优化器在用到这个变量时必须重新读取这个变量的值,而不是保存在寄存器里的备份。 | |
24 | restrict | C99 | restrict 限定的指针是访问它所指向内存的唯一方式(在特定作用域中)。 | |
25 | _Atomic | C11 | 声明原子类型的变量,当一个线程对一个原子类型的对象执行原子操作时,其他线程不能访问该对象。 | |
26 | 对齐指定符 | _Alignas | C11 | 指定一个变量或类型的对齐值,强制执行数据存储区上的对齐要求 ,用作声明的一部分,如 _Alignas(8) char c; 。 |
27 | 运算符 | _Alignof | C11 | 得到指定类型的对齐值,在关键字 _Alignof 后面的圆括号中写上类型名即可,如 _Alignof(float)。 |
28 | sizeof | C89 | 以字节为单位返回运算对象的大小,运算对象可以是具体的数据对象(如,变量名)或类型。 | |
29 | 循环控制 | for | C89 | for 循环结构,入口条件循环,在执行循环之前判断是否需要执行循环。 |
30 | while | C89 | while 循环结构,入口条件循环,在执行循环之前判断是否需要执行循环。 | |
31 | do | C89 | do 循环结构,do while 语句是一种出口条件循环,在执行完循环体后根据测试条件决定是否再次执行循环。 | |
32 | 分支控制 | if | C89 | 使用 if 语句进行分支选择。 |
33 | else | C89 | if 条件语句为假分支。 | |
34 | switch | C89 | 多分支选择语句。 | |
35 | case | C89 | switch 语句分支标记,程序控制根据 expression 的值跳转至相应的 case 标签处。 | |
36 | default | C89 | 如果没有匹配的 case 标签,控制则转至 default 语句(如果有的话)。 | |
37 | _Generic | C11 | 泛型选择语句与 switch 语句类似,只是前者用表达式的类型匹配标签,而后者用表达式的值匹配标签。 | |
38 | 跳转控制 | continue | C89 | 使程序控制跳出循环的剩余部分。对于while或for循环,程序执行到continue语句后会开始进入下一轮迭代。对于do while循环,对出口条件求值后,如有必要会进入下一轮迭代。 |
39 | break | C89 | 使程序控制跳出当前循环或switch语句的剩余部分,并继续执行跟在循环或switch后面的语句。 | |
40 | goto | C89 | 使程序控制跳转至相应标签语句。标签语句可以出现在goto的前面或后面。 | |
41 | return | C89 | 从函数中返回值(如果需要),终止函数并把控制返回给主调函数的下一条语句。 | |
42 | 函数说明符 | inline | C99 | 尽可能快地调用该函数,编译器可能会用内联代码替换函数调用,并(或)执行一些其他的优化,但是也可能不起作用。 |
43 | _Noreturn | C11 | 表明调用完成后函数不返回主调函数(exit() 函数是 _Noreturn 函数的一个示例)。 | |
44 | 断言声明 | _Static_assert | C11 | 可以在编译时检查 assert() 表达式。 |
2、基本数据类型
2.0 常量与变量
常量(constant)
- 数值:在程序运行前,数值已预先设定好;在程序运行过程中,数值不会改变。
- 类型:任何基本数据类型,比如整数常量、浮点常量、字符常量,或字符串字面值,以及枚举常量。
变量(variable)
- 定义:程序可操作的存储区(名称)。
- 数值:在程序运行过程中,数值可能会改变。
- 类型:变量所存储数据的种类,影响变量的存储方式(大小和布局)以及允许对变量进行的操作。
2.1 整数类型(数值类型)
2.1.1 类型及范围
整数类型 | 16位机范围 | 32位机范围 | 64位机范围 |
---|---|---|---|
short int | -215(-32 768)~215-1(32 767) | 同16位 | 同16位 |
unsigned short int | 0~216-1(65 535) | 同16位 | 同16位 |
int | -215(-32 768)~215-1(32 767) | -231(-2 147 483 648)~231-1(2 147 483 647) | 同32位 |
unsigned int | 0~216-1(65 535) | 0~232-1(4 294 967 295) | 同32位 |
long int | -231(-2 147 483 648)~231-1(2 147 483 647) | 同16位 | -263(-9 223 372 036 854 775 808)~263-1(9 223 372 036 854 775 807) |
unsigned long int | 0~232-1(4 294 967 295) | 同16位 | 0~264-1(18 446 744 073 709551 615) |
long long int | -263(-9223 372 036 854 775 808)~263-1(9 223 372 036 854 775 807) | ||
unsigned long long int | 0~264-1(18 446 744 073 709551 615) | ||
signed char | -27(-128)~27-1(127) | 同16位 | 同16位 |
unsigned char | 0~28-1(255) | 同16位 | 同16位 |
_Bool | 0, 1 | 同16位 | 同16位 |
注1:C语言允许通过省略单词 int 来缩写整数类型的名字。例如,unsigned short int 可以缩写为unsigned short,而long int 可以缩写为 long。
注2:取值范围不是C标准强制的,会随着编译器的不同而不同。标准库的 <limits.h> 定义了表示每种整数类型的最大值和最小值的宏。
2.1.2 整型常量
常量书写形式:
书写方式 | 内容 | 开头约束 | 类型判断 | 类型判断 C99 |
---|---|---|---|---|
十进制 | 数字 0~9 | 不能以零开头 | 根据值的大小,使用 int、long 或 unsigned long 类型 | int、long 或 long long 中能表示该值的“最小”类型 |
八进制 | 数字 0~7 | 必须以零开头 | 编译器依次尝试 int、unsigned int、long 和 unsigned long 类型,直至找到能表示该常量的类型。 | 可能的顺序为 int、unsigned int、long、unsigned long、long long 和 unsigned long long。U 或 L 等后缀会改变可能类型的列表。 |
十六进制 | 数字 0~9 和字母 a ~ f | 总是以 0x 开头 | 同八进制 | 同八进制 |
指定常量类型:
指定类型 | 方式 | 示例 |
---|---|---|
长整型常量 | 常量后加 L(或 l) | 15L、0377L、0x7fffL |
无符号常量 | 常量后加 U(或 u) | 15U、0377U、0x7fffUL |
双长整型(C99) | 常量后加 LL(或 ll) | 15LL、0377ll、0x7fffLLU |
2.1.3 整型转换说明符
int 、unsigned int 类型:
转换说明符 | 说明 |
---|---|
%d | 有符号十进制 |
%o | 无符号八进制,显示前缀 0 则使用 %#o |
%x | 无符号十六进制,显示前缀 0x 和 0X 则使用 %#x、%#X |
%u | 无符号十进制 |
%i | 在 printf 格式串中,%i 与 %d 没有区别;在 scanf 格式串中,%d 只能匹配十进制形式的整数,而 %i 则可以匹配用八/十/十六进制表示的整数。如果输入的数有前缀0(如056),%i 匹配为八进制数;如果有前缀0x或0X(如0x56),%i 匹配为十六进制数。【注意不要意外地将0放在输入数的开始处】 |
- 短整数,在 d、o、u 或 x 前面加上字母 h
- 长整数,在 d、o、u 或 x 前面加上字母 l
- 双长整数(C99),在 d、o、u 或 x 前面加上字母 ll
2.2 浮点类型(数值类型)
2.2.1 类型及范围
- 实浮点类型:float、double、long double
- 复数类型(C99):
- float _Complex、double _Complex、long double _Complex
- float _Imaginary、double _Imaginary、long double _Imaginary
浮点型特征(IEEE754 标准)
类型 | 长度 | 最小正值 | 最大值 | 精度(十进制) |
---|---|---|---|---|
float | 32位 | 1.17549×10-38 | 3.40282×1038 | 6~7个数字 |
double | 64位 | 2.22507×10-308 | 1.79769×10308 | 15~16个数字 |
long double | 变化 |
float 型变量所存储的数值往往只是实际数值的一个近似值。
2.2.2 浮点型常量
表示形式:有符号小数 + E (或 e) + 有符号 10 的指数
浮点数 57.0 示例:
57.0、57.、57.0e0、57E0、5.7e1、5.7e+1、.57e2、570.e-1
- 正号可以省略(如 5.7e1);
- 可以没有小数点(如,57E0)或指数部分(如,57.0),但是不能同时省略两者;
- 可以省略小数部分(如,570.e-1)或整数部分(如,.57e2),但是不能同时省略两者。
指定常量类型:
指定类型 | 方式 | 示例 |
---|---|---|
double | (默认) | 57.0 |
float | 常量后加 F(或 f) | 57.0F |
long double | 常量后加 L(或 l) | 57.0L |
十六进制(C99) | 用p和P分别代替e和E,用2的幂代替10的幂 | 0xa.1fp10 |
2.2.3 浮点型转换说明符
转换说明符 | 说明 |
---|---|
%e | 表示指数(科学记数法)形式的浮点数 |
%f | 表示“定点十进制”形式的浮点数,没有指数 |
%g | 根据数的大小选择指数(指数<-4或>=精度)形式或者定点十进制(不显示尾随的零,甚至小数点)形式 |
%a | 对于十六进制格式的浮点数,可用 a 和 A 分别代替 e 和 E |
%F | 在C99中,F 和 f 一样,区别在于书写无穷数和NaN。例如,1.0除以0.0会产生正无穷数(inf 或 infinity),-1.0除以0.0会产生负无穷数(-inf 或 -infinity),而0.0除以0.0会产生非数NaN(nan 或 -nan)。A、E、F 和 G 与 a、e、f 和 g 是等价的,区别仅在于使用大写字母(INF、INFINITY、NAN) |
- 在用于 scanf 函数时,转换说明 %e、%f 和 %g 可以互换
- 读取 double 类型的值时,在 e、f 或 g 前放置字母 l
- 读写 long double 类型的值时,在 e、f 或 g 前放置字母 L
2.3 字符类型
2.3.1 类型及范围
常用字符集 ASCII 码,用7位代码表示128个字符。
扩展 ASCII 码(Latin-1 字符集),包含西欧语言和许多非洲语言中的字符。
C语言把字符当作小整数进行处理。
字符类型 | 范围 |
---|---|
signed char | -27(-128) ~ 27-1(127) |
unsigned char | 0 ~ 28-1(255) |
char | 由编译器决定。不要假设 char 类型默认为 signed 或 unsigned。如果有区别,用 signed char 或 unsigned char 代替 char。 |
2.3.2 字符常量
- 使用单引号(‘’)括起单个字符,如 ‘A’
- 字符转义序列(character escape sequence),包含了最常用的无法打印的 ASCII 字符:
转义序列 \a、\b、\f、\r、\n 、\t 和 \v 表示常用的 ASCII 控制字符,
转义序列 \ 允许字符常量或字符串包含字符 \ ,
转义序列 ’ 允许字符常量包含字符 ’ ,
转义序列 " 则允许字符串包含字符 " ,
转义序列 ? 很少使用。
- 数字转义序列,可以通过“字符的八进制或十六进制值”表示任何字符:
八进制转义序列:\ + 含有1~3位数字的八进制数(如 ‘\33’ 或 ‘\033’)
十六进制转义序列:\x + 十六进制数,(如 ‘\x1b’ 或 ‘\x1B’)
2.3.3 字符转换说明符
转换说明符 | 说明 |
---|---|
%c | 单个字符 |
%s | 字符串 |
%[集合] | %[集合] 匹配集合中的任意字符序列,%[^集合] 匹配不在集合中的任意字符序列。例如,%[abc] 匹配的是只含有字母a、b和c的任何字符串,而 %[^abc] 匹配的是不含有字母a、b或c的任何字符串。 |
3、输入/输出函数(标准输入/输出流)
3.1 格式化输入/输出
在输入时把字符格式的数据转换为数值格式的数据,在输出时把数值格式的数据再转换成字符格式的数据。
3.1.1 printf 函数
/**
* @file <stdio.h>
* @brief 向 stdout(标准输出流)中写入可变数量的数据项
* @param[in] format 包含“普通字符、转换说明”的格式串
* @param[in] ... 可变数量的实际参数
* @return 写入的字符数,若出错则返回一个负值
*/
int printf(const char * restrict format, ...);
格式串
- 普通字符:原样输出;
- 转换说明:描述如何把实参转换为字符格式显示出来
转换说明 = 字符% + ①标志(可选项)+ ②最小栏宽(可选项)+ ③精度(可选项)+ ④长度指定符(可选项)+ ⑤转换指定符
示例:%#012.5Lg
% | ① 标志 | ② 最小栏宽 | ③ 精度 | ④ 长度指定符 | ⑤ 转换指定符 |
---|---|---|---|---|---|
% | #0 | 12 | .5 | L | g |
① 标志(可选项,允许多于一个):“-” 标志导致在栏内左对齐,其他标志则会影响数的显示形式。
标志 | 含义 |
---|---|
- | 在栏内左对齐(默认右对齐) |
+ | 有符号转换得到的数总是以+或-开头(通常,只有负数前面附上-) |
空格 | 有符号转换得到的非负数前面加空格(+标志优先于空格标志) |
# | 以0开头的八进制数,以0x或0X开头的十六进制非零数。浮点数始终有小数点。不能删除由g或G转换输出的数的尾部零 |
0(零) | 用前导零在数的栏宽内进行填充。如果转换是d、i、o、u、x或X,而且指定了精度,那么可以忽略标志0(-标志优先于0标志) |
② 最小栏宽(可选项)
数据类型 | 条件 | 说明 |
---|---|---|
正整数 | 数据项<宽度 | 进行填充(默认在数据项左侧添加空格,使其在栏内右对齐) |
数据项>宽度 | 完整显示数据项 | |
字符 * | 栏宽由下一个实际参数决定(允许使用宏或计算值来指定) | |
负整数 | 会被视为前面带-标志的正数 |
③ 精度(可选项): 小数点(.)+ 整数或字符*
格式 | 转换指定符 | 说明 |
---|---|---|
小数点(.)+ 正整数 | d、i、o、u、x、X | 表示最少位数(如果位数不够,则添加前导零) |
a、A、e、E、f、F | 表示小数点后的位数 | |
g、G | 表示有效数字的最大个数 | |
s | 表示最大字节数 | |
小数点(.)+ 负整数 | 效果与不指定精度一样 | |
小数点(.) | 精度为零 | |
小数点(.)+ 字符* | 精度由下一个实际参数决定(允许使用宏或计算值来指定) |
④ 长度指定符(可选项):配合转换指定符,共同指定传入的实际参数的类型。
长度指定符 | 转换指定符 | 含义 |
---|---|---|
hh(C99) | d、i、o、u、x、X | signed char, unsigned char |
n | signed char * | |
h | d、i、o、u、x、X | short int, unsigned short int |
n | short int * | |
l (ell) | d、i、o、u、x、X | long int, unsigned long int |
n | long int * | |
c | wint_t | |
s | wchar_t * | |
a、A、e、E、f、F、g、G | 无作用 | |
ll (ell-ell) (C99) | d、i、o、u、x、X | long long int, unsigned long long int |
n | long long int * | |
j (C99) | d、i、o、u、x、X | intmax_t, uintmax_t |
n | intmax_t * | |
z (C99) | d、i、o、u、x、X | size_t |
n | size_t * | |
t (C99) | d、i、o、u、x、X | ptrdiff_t |
n | ptrdiff_t * | |
L | a、A、e、E、f、F、g、G | long double |
⑤ 转换指定符
转换指定符 | 含义 |
---|---|
d、i | 把 int 类型值转换为十进制形式 |
o、u、x、X | 把无符号整数转换为八进制(o)、十进制(u)或十六进制(x、X)形式。x 表示用小写字母 a~f 来显示十六进制数,而 X 表示用大写字母 A~F 来显示十六进制数。 |
f、F(C99) | 把 double 类型值转换为十进制形式,并且把小数点放置在正确的位置上。如果没有指定精度,那么在小数点后面显示6个数字。 |
e、E | 把 double 类型值转换为科学记数法形式,需要把字母 e 或 E 放在指数前面。如果没有指定精度,那么在小数点后面显示6个数字。 |
g、G | g 会把 double 类型值转化为 f 形式或者 e 形式。当数值的指数部分小于-4,或者指数部分大于等于精度值时,会选择 e 形式显示。尾部的零不显示(除非使用了#标志),且小数点仅在后边跟有数字时才显示出来。G 会在 F 形式和 E 形式之间进行选择。 |
a(C99)、A(C99) | 使用格式 [-]0xh.hhhhp±d 的格式把 double 类型值转换为十六进制科学记数法形式。其中 [-] 是可选的负号,h 代表十六进制数位,± 是正号或者负号,d 是指数。d 为十进制数,表示2的幂。如果没有指定精度,在小数点后将显示足够的数位来表示准确的数值(如果可能的话)。a 表示用小写形式显示 a~f,A 表示用大写形式显示 A~F。选择 a 还是 A 也会影响到字母 x 和 p 的情况。 |
c | 显示无符号字符的 int 类型值 |
s | 写出由实参指向的字符。当达到精度值(如果存在)或者遇到空字符时,停止写操作。 |
p | 把 void * 类型值转换为可打印形式 |
n | 相应的实参必须是指向 int 型对象的指针。在该对象中存储 …printf 函数调用已经输出的字符数量,不产生输出。 |
% | 写字符% |
注: f、F、e、E、g、G、a 和 A 全部设计用来输出 double 类型的值,但把它们用于 float 类型的值也可以,float 类型实参在传递给带有可变数量实参的函数时会自动转换为 double 类型。类似地,传递给 …printf 函数的字符也会自动转换为 int 类型,所以可以正常使用转换指定符 c。
3.1.2 scanf 函数
/**
* @file <stdio.h>
* @brief 从 stdin(标准输入流)中读入可变数量的数据项
* @param[in] format 包含“转换说明、空白字符、非空白字符”的格式串
* @param[in] ... 可变数量的对象指针
* @retval 读入并且赋值给对象的数据项的数量
* @retval EOF 检测到“文件结尾”时,返回EOF(通常定义为-1)
* @retval 0 失败(没有输入/格式串匹配失败/编码错误)
*/
int scanf(const char * restrict format, ...);
格式串
- 空白字符:格式串中的一个或多个连续的空白字符与输入流中的零个或多个空白字符相匹配;
- 非空白字符:除了%之外的非空白字符和输入流中的相同字符相匹配;
- 转换说明:类似 …printf 函数格式串中的转换说明。大多数转换说明(%[、%c、%n 例外)会跳过输入项开始处的空白字符。转换说明不会跳过尾部的空白字符。
转换说明 = 字符% + ①字符*(可选项)+ ②最大栏宽(可选项)+ ③长度指定符(可选项)+ ④转换指定符
示例:%*6lc
% | ① 字符 * | ② 最大栏宽 | ③ 长度指定符 | ④ 转换指定符 |
---|---|---|---|---|
% | * | 6 | l | c |
① 字符 *(可选项):赋值屏蔽(assignment suppression),读入此数据项,但是不会把它赋值给对象,也不包含在函数返回的计数中。
② 最大栏宽(可选项):限制输入项中的字符数量。如果达到最大值,此数据项的转换将结束。转换开始处跳过的空白字符不进行统计。
③ 长度指定符 (可选项):配合转换指定符,共同指定输入数据的类型。
长度指定符 | 转换指定符 | 含义 |
---|---|---|
hh(C99) | d、i、o、u、x、X、n | signed char *, unsigned char * |
h | d、i、o、u、x、X、n | short int *, unsigned short int * |
l (ell) | d、i、o、u、x、X、n | long int *, unsigned long int * |
a、A、e、E、f、F、g、G | double * | |
c、s、[ | wchar_t * | |
ll (ell-ell) (C99) | d、i、o、u、x、X、n | long long int *, unsigned long long int * |
j (C99) | d、i、o、u、x、X、n | intmax_t *, uintmax_t * |
z (C99) | d、i、o、u、x、X、n | size_t * |
t (C99) | d、i、o、u、x、X、n | ptrdiff_t * |
L | a、A、e、E、f、F、g、G | long double * |
④ 转换指定符
转换指定符 | 含义 |
---|---|
d | 匹配十进制整数,假设相应的实参是 int * 类型 |
i | 匹配整数,假设相应的实参是 int * 类型。如果数以0开头,为八进制形式;以0x或0X开头,为十六进制形式;否则为十进制形式。 |
o | 匹配八进制整数。假设相应的实参是 unsigned int * 类型 |
u | 匹配十进制整数。假设相应的实参是 unsigned int * 类型 |
x、X | 匹配十六进制整数。假设相应的实参是 unsigned int * 类型 |
a(C99)、A(C99)、e、E、f、F(C99)、g、G | 匹配浮点数。假设相应的实参是 float * 类型。在C99中,该数可以是无穷大或 NaN。 |
c | 匹配 n 个字符,n 是最大栏宽,假设相应的实参是指向字符数组的指针,不在未尾添加空字符;如果没有指定栏宽,匹配一个字符,实参是指向字符对象的指针。 |
s | 匹配一串非空白字符,然后在未尾添加空字符。假设相应的实参是指向字符数组的指针 |
[ | 匹配来自扫描集合的非空字符序列,然后在未尾添加空字符。假设相应的实参是指向字符数组的指针 |
p | 以 …printf 函数的输出格式匹配指针值。假设相应的实参是指向 void * 对象的指针 |
n | 相应的实参必须是指向 int 类型对象的指针。把到目前为止读入的字符数量存储到此对象中。不读入任何数据,函数的返回值不会受到影响。 |
% | 匹配字符 % |
3.2 字符的输入/输出(putchar、getchar)
/**
* @file <stdio.h>
* @brief 向 stdout(标准输出流)中写一个字符
* @param[in] c 需要输出的字符
* @return 写入的字符,若出错则返回EOF(并为流设置错误指示器)
*/
int putchar(int c);
/**
* @file <stdio.h>
* @brief 从 stdin(标准输入流)中读入一个字符
* @retval 读入的 unsigned char 类型的字符(返回之前转换成 int 类型)
* @retval EOF 遇到了文件末尾,设置流的文件末尾指示器,通过 feof()判断
* @retval EOF 产生了读错误,设置流的错误指示器,通过 ferror() 判断
*/
int getchar(void);
3.3 行的输入/输出(puts、gets)
/**
* @file <stdio.h>
* @brief 向 stdout(标准输出流)中写入字符串,并自动添加一个换行符
* @param[in] s 需要输出的字符串
* @return 写入的字符,若出错则返回EOF(并为流设置错误指示器)
*/
int puts(const char *s);
/**
* @file <stdio.h>
* @brief 从 stdin(标准输入流)中读取一行(遇到换行符),并把它存储在 str 所指向的字符串中(不存储换行符)
* @param[out] str 指向一个字符数组的指针,该数组用于存储字符串
* @retval str 成功
* @retval NULL 发生错误或者未能读取到任何字符
* @deprecated 出于对安全性的考虑,C11 已将它从新标准中废除,建议替换使用 fgets()
*/
char *gets(char *str);
4、运算符、表达式和语句
- 表达式(expression)
- 简单表达式:变量、常量。
- 复杂表达式:把运算符(operator)用于操作数(变量、常量或者包含其它运算符的表达式)。
- 语句(statement):在表达式后面添加分号。
- 运算符(operator)
- 算术运算符 (7):+、-、*、/、%、++、–
- 关系运算符 (6):<、<=、==、>=、>、!=
- 赋值运算符 (11):=、+=、-=、*=、/=、%=、&=、|=、^=、>>=、<<=
- 逻辑运算符 (3):&&、||、!
- 条件运算符 (1):?:
- 与指针有关的运算符 (2):地址运算符(&)、间接或解引用运算符(*)
- 符号运算符 (2):正号(+)、负号(-)
- 结构和联合运算符(2):成员运算符(.)、间接成员运算符(->)
- 按位运算符 (6):~、&、|、^、<<、>>
- 其它运算符 (7):sizeof、_Alignof、(类型名)、逗号运算符(,)、数组取下标[]、函数调用()、复合字面量{}
运算符列表:(49个)
优先级 | 名称 | 符号 | 结合性 |
---|---|---|---|
1 | 复合字面量 | {} | 从左往右 |
1 | 数组取下标 | [] | 从左往右 |
1 | 函数调用 | () | 从左往右 |
1 | 取结构和联合的成员 (2) | . -> | 从左往右 |
1 | 自增(后缀) | ++ | 从左往右 |
1 | 自减(后缀) | – | 从左往右 |
2 | 自增(前缀) | ++ | 从右往左 |
2 | 自减(前缀) | – | 从右往左 |
2 | 取地址 | & | 从右往左 |
2 | 解引用 | * | 从右往左 |
2 | 一元正号 | + | 从右往左 |
2 | 一元负号 | - | 从右往左 |
2 | 按位取反 | ~ | 从右往左 |
2 | 逻辑非 | ! | 从右往左 |
2 | 计算所需空间 | sizeof | 从右往左 |
2 | 给出对齐要求 | _Alignof | 从右往左 |
3 | 强制类型转换 | () | 从右往左 |
4 | 乘法类运算符 (3) | * / % | 从左往右 |
5 | 加法类运算符 (2) | + - | 从左往右 |
6 | 移位 (2) | << >> | 从左往右 |
7 | 关系 (4) | < > <= >= | 从左往右 |
8 | 判等 (2) | == != | 从左往右 |
9 | 按位与 | & | 从左往右 |
10 | 按位异或 | ^ | 从左往右 |
11 | 按位或 | | | 从左往右 |
12 | 逻辑与 | && | 从左往右 |
13 | 逻辑或 | || | 从左往右 |
14 | 条件 | ?: | 从右往左 |
15 | 赋值 (11) | = *= /= %= += -= <<= >>= &= ^= |= | 从右往左 |
16 | 逗号 | , | 从左往右 |
参考
- [美] K. N. 金(K. N. King)著,吕秀锋,黄倩译.C语言程序设计:现代方法(第2版·修订版).人民邮电出版社.2021:209.
- [美] 史蒂芬·普拉达著.C Primer Plus(第6版 中文版 最新修订版).人民邮电出版社.2019:115.
宁静以致远,感谢 Vico 老师。