3.1 示例程序
- scanf() 不会读取换行符
3.1.1 程序中的新元素
3.2 变量与常量数据
- 常量 (constant)
- 变量 (variable)
3.3 数据: 数据类型关键字
- 编译器通过书写的形式来判断常量的类型
- long, short, unsigned, signed 用于提供基本整数类型的变式
- unsigned short int
- long long int
- long double
字 (word)
- 计算机存储单位
3.3.1 整数和浮点数
整数和浮点数的存储方式不同.
3.3.2 整数
3.3.3 浮点数
3.4 C 语言基本数据类型
3.4.1 int 类型
- int 要占一个机器字
1. 声明 int 变量
int erns;
int hogs, cows, goats;
2. 初始化变量
int hogs = 21;
int cows = 32, goats = 14;
int dogs, cats = 94; // dogs 没有初始化
3. int 类型常量
整型常量/整型字面量
- 视为 int 类型 (非常大的整数除外)
4. 打印 int 值
5. 八进制和十六进制
- 八进制, 前缀:
0
- 十六进制, 前缀:
0x
或0X
6. 显示八进制和十六进制
- 八进制:
%o
- 十六进制:
%x
- 显示进制前缀:
%#o
,%#x
,%#X
3.4.2 其他整数类型
跳过
3.4.3 使用字符: char 类型
1. 声明 char 类型变量
char response;
char itable, latan;
2. 字符常量和初始化
char grade = 'A';
char grade = 65;
3. 非打印字符
转义序列:
使用八进制转义序列:
beep = '\007';
// 可以省略0
beep = '\7';
4. 打印字符
%c
5. 有符号还是无符号
不同编译器对 char 的解释不同. 可以查看 limits.h 头文件.
- C90 标准允许在 char 前面使用 signed 或 unsigned
3.4.4 _Bool 类型
- true
- false
3.4.5 可移植类型: stdint.h 和 inttypes.h
C99 标准添加这两个头文件确保同一整数类型在不同系统上是相同的.
- 精确宽度整数类型 (exact-width integer type): int32_t. 估计是编译器在编译时选择跟系统相关的具体类型
- 最小宽度类型 (minimum width type): 至少有指定宽度. int_least8_t
- 最快最小宽度类型 (fastst minimum width type): 与运算速度有关. int_fast8_t
- 最大整数类型
- intmax_t
- unitmax_t
打印可移植类型:
- 字符串宏: PRId32, 打印32位有符号值的合适转换说明 (如 d 或 l)
3.4.6 float, double 和 long double
指数记数法是科学记数法在计算机中的表示.
float:
- 指数部分
- 尾数部分 (有效数)
- 最少6位, 十进制
double:
- 最少10位有效数字
long double:
- C 只保证至少有与 double 相同精度
1. 声明浮点型变量
float noah, jonah;
double trouble;
float planck = 6.63e-34;
long double gnp;
2. 浮点型常量
- e/E
- 可省略
- 不能有空格
-1.56E+12
2.87e-3
2E5
19.28
3.E16
.45E-6
.2
100.
浮点型常量是 double 类型.
假设 some 是 float 类型, 下面语句:
some = 4.0 * 2.0;
- 4.0, 2.0是 double 类型, 乘积被截断为 float 类型, 精度高但速度慢
float 类型常量:
2.3f
9.11E9F
long double 类型:
54.3l
4.32L // 推荐 L 写法
用十六进制表示浮点数 (C99 标准):
- 前缀:
0x
或0X
- 指数部分:
p
或P
. 代替e
,E
- 幂: 为2的幂
0xa.1fp10 // 10364.0
- a: 10
- .1f: 1/16 + 15/256
- p10: 2
3. 打印浮点值
- %f: 十进制 float, double
- %e: 指数记数法
- %a/%A: 十六进制浮点数
- %Lf/%Le/%La: long double
- 给那些未在函数原型中显式说明参数类型的函数 (如 printf()) 传递参数时, C 编译器会把 float 转换成 double
4. 浮点值的上溢和下溢
float toobig = 3.4E38 * 100.0f;
printf("%e\n", toobig);
- 上溢 (overflow), 会赋一个无穷大的特定值
- 下溢 (underflow)
- NaN (not a number)
3.4.7 复数和虚数类型
3种复数类型:
- float _Complex
- double _Complex
- long double _Complex
3种虚数类型:
- float _Imaginary
- double _Imaginary
- long double _imaginary
3.4.8 其他类型
- 数组
- 指针
- 结构
- 联合
3.4.9 类型大小
打印类型大小:
- sizeof()
- %zd: 打印 sizeof() 的返回值, 类型为 size_t
3.5 使用数据类型
int apples = 3; /* 正确 */
int oranges = 3.0; /* 不好的形式 */
会导致数据丢失的初始化:
- const 初始化后为12
- pi 初始化后精度减少
int const = 12.99; /* 用 double 初始化 int*/
float pi = 3.1415926536; /* 与 double 初始化 float*/
3.6 参数和陷阱
printf() 等类似不定参数的函数, 其第一个参数中的转换说明的个数用于表示之后的参数的个数.
3.7 转义序列示例
3.7.1 程序运行情况
3.7.2 刷新输出
printf() 何时把输出发送到屏幕上?
- 最初, printf() 把输出发送到缓冲区中, 当缓冲区满/遇到换行字符/需要输入的时候把数据从缓冲区中发送到屏幕/文件 (刷新缓冲区)
fflush() 函数.