TODO: 前言
数据类型与运算符
# 数据类型
# 常量与变量
# 关键字
C 语言共有 32 个关键字
类型 | 关键字 |
---|---|
数据类型 12 个 | char,short,int,long,float,double,unsigned,signed,struct,union,enum,void |
控制语句 12 个 | if,else,switch,case,default,for,do,while,break,continue,goto,return |
存储类 5 个 | auto,extern,register,static,const |
其他 3 个 | sizeof,typedef,volatile |
# 标识符的命名规则
- 由字母、数字、下划线组成
- 不能以数字开头
- 名称意义明确
- 注意标识符的重复问题
- 不能使用 C 语言关键字
- 区分大小写
# 常量
在程序运行过程中值不能改变的量
const 数据类型 常量名
const float PI = 3.14
宏定义
#define PI 3.14
注:const 修饰的常量不安全,可以通过指针修改 (C 语言中)
# 变量
变量在程序运行中值可以改变,在使用变量前需先定义
# 声明和定义的区别
声明变量不需要建立存储空间,例: extern int a
定义变量需要建立存储空间,例: int a
# 进制
# 进制在 C 语言中的表示
十进制
int a = 10 //%d
八进制
int a =010 //%o
十六进制
int a = 0x10ac //%x 输出字母小写 %X 输出字母大写
# 内存中的存储方式
# 原码
原码(原始的二进制码)特点
最高位做为符号位,0 表示正,为 1 表示负
其它数值部分就是数值本身绝对值的二进制数
负数的原码是在其绝对值的基础上,最高位变为 1
十进制数 | 原码 |
---|---|
+15 | 0000 1111 |
-15 | 1000 1111 |
+0 | 0000 0000 |
-0 | 1000 0000 |
原码表示法简单易懂,与带符号数本身转换方便,只要符号还原即可,但当两个正数相减或不同符号数相加时,必须比较两个数哪个绝对值大,才能决定谁减谁,才能确定结果是正还是负,所以原码不便于加减运算
# 反码
- 正数:的反码和原码相同
- 负数:符号位不变,其它部分取反
十进制数 | 反码 |
---|---|
+15 | 0000 1111 |
-15 | 1111 0000 |
+0 | 0000 0000 |
-0 | 1111 1111 |
反码运算也不方便,通常用来作为求补码的中间过渡
# 补码
计算机中,数值使用补码存储
正数的原码、反码、补码相同
负数的补码为它的反码加 1
补码符号位不动,其他位求反,最后整个数加 1,得到原码
十进制数 | 补码 |
---|---|
+15 | 0000 1111 |
-15 | 1111 0001 |
+0 | 0000 0000 |
-0 | 0000 0000 |
使用补码存储的原因是
- 统一了零的编码
- 将符号位和其它位统一处理
- 将减法运算转变为加法运算
- 两个用补码表示的数相加时,如果最高位 (符号位) 有进位,则进位被舍弃
# 基本类型
# 整型 int
# 定义
数据类型 | 占用空间 |
---|---|
short | 2 字节 |
int | 4 字节 |
long | Windows 为 4 字节,Linux 为 4 字节 (32 位),8 字节 (64 位) |
long long | 8 字节 |
# 输入输出
打印格式 | 含义 |
---|---|
%hd | 输入输出 short 类型 |
%d | 输入输出 int 类型 |
%l | 输入输出 long 类型 |
%ll | 输入输出 long long 类型 |
%hu | 输入输出 unsigned short 类型 |
%u | 输入输出 unsigned int 类型 |
%lu | 输入输出 unsigned long 类型 |
%llu | 输入输出 unsigned long long 类型 |
# 取值范围
数据类型 | 占用空间 | 取值范围 |
---|---|---|
short | 2 字节 | -32768 到 32767 (-215 ~ 215-1) |
int | 4 字节 | -2147483648 到 2147483647 (-231 ~ 231-1) |
long | 4 字节 | -2147483648 到 2147483647 (-231 ~ 231-1) |
unsigned short | 2 字节 | 0 到 65535 (0 ~ 216-1) |
unsigned int | 4 字节 | 0 到 4294967295 (0 ~ 232-1) |
unsigned long | 4 字节 | 0 到 4294967295 (0 ~ 232-1) |
# 字符型 char
字符型变量用于存储一个单一字符,在 C 语言中用 char 表示,存储字符的 ASCII 码,占用 1 字节,
赋值时需使用单引号括起来
char ch = 'a'
# 定义
数据类型 | 占用空间 |
---|---|
char | 1 字节 |
# 输入输出
打印格式 | 含义 |
---|---|
%c | 输入输出 char 类型 |
char ch = 'a' | |
scanf("%c", &ch); | |
printf("ch = %c\n", ch); // 输出字符 | |
printf("ch = %d\n", ch); // 输出字符的 ASCII 值 | |
printf("CAP ch = %c\n", ch-32); // 小写转大写 |
# ASCII 码表
ASCII 值 | 控制字符 | ASCII 值 | 字符 | ASCII 值 | 字符 | ASCII 值 | 字符 |
---|---|---|---|---|---|---|---|
0 | NUT | 32 | (space) | 64 | @ | 96 | 、 |
1 | SOH | 33 | ! | 65 | A | 97 | a |
2 | STX | 34 | " | 66 | B | 98 | b |
3 | ETX | 35 | # | 67 | C | 99 | c |
4 | EOT | 36 | $ | 68 | D | 100 | d |
5 | ENQ | 37 | % | 69 | E | 101 | e |
6 | ACK | 38 | & | 70 | F | 102 | f |
7 | BEL | 39 | , | 71 | G | 103 | g |
8 | BS | 40 | ( | 72 | H | 104 | h |
9 | HT | 41 | ) | 73 | I | 105 | i |
10 | LF | 42 | * | 74 | J | 106 | j |
11 | VT | 43 | + | 75 | K | 107 | k |
12 | FF | 44 | , | 76 | L | 108 | l |
13 | CR | 45 | - | 77 | M | 109 | m |
14 | SO | 46 | . | 78 | N | 110 | n |
15 | SI | 47 | / | 79 | O | 111 | o |
16 | DLE | 48 | 0 | 80 | P | 112 | p |
17 | DCI | 49 | 1 | 81 | Q | 113 | q |
18 | DC2 | 50 | 2 | 82 | R | 114 | r |
19 | DC3 | 51 | 3 | 83 | S | 115 | s |
20 | DC4 | 52 | 4 | 84 | T | 116 | t |
21 | NAK | 53 | 5 | 85 | U | 117 | u |
22 | SYN | 54 | 6 | 86 | V | 118 | v |
23 | TB | 55 | 7 | 87 | W | 119 | w |
24 | CAN | 56 | 8 | 88 | X | 120 | x |
25 | EM | 57 | 9 | 89 | Y | 121 | y |
26 | SUB | 58 | : | 90 | Z | 122 | z |
27 | ESC | 59 | ; | 91 | [ | 123 | { |
28 | FS | 60 | < | 92 | / | 124 | | |
29 | GS | 61 | = | 93 | ] | 125 | } |
30 | RS | 62 | > | 94 | ^ | 126 | ` | |
31 | US | 63 | ? | 95 | _ | 127 | DEL |
ASCII 码由非打印控制字符和打印字符组成
- 非打印控制字符:ASCII 表上的数字 0-31 分配给了控制字符,用于控制像打印机等一些外围设备
- 打印字符:数字 32-126 分配给了能在键盘上找到的字符,当查看或打印文档时就会出现。数字 127 代表 Del 命令
# 转义字符
转义字符 | 含义 | ASCII 码值(十进制) |
---|---|---|
\a | 警报 | 007 |
\b | 退格 (BS) ,将当前位置移到前一列 | 008 |
\f | 换页 (FF),将当前位置移到下页开头 | 012 |
\n | 换行 (LF) ,将当前位置移到下一行开头 | 010 |
\r | 回车 (CR) ,将当前位置移到本行开头 | 013 |
\t | 水平制表 (HT) (跳到下一个 TAB 位置) | 009 |
\v | 垂直制表 (VT) | 011 |
\\ | 代表一个反斜线字符 "" | 092 |
\' | 代表一个单引号(撇号)字符 | 039 |
\" | 代表一个双引号字符 | 034 |
? | 代表一个问号 | 063 |
\0 | 数字 0 | 000 |
\ddd | 8 进制转义字符,d 范围 0~7 | 3 位 8 进制 |
\xhh | 16 进制转义字符,h 范围 09,af,A~F | 3 位 16 进制 |
printf("%d\n", '\123'); // '\123' 为 8 进制转义字符,0123 对应 10 进制数为 83 | |
printf("%d\n", '\x23'); // '\x23' 为 16 进制转义字符,0x23 对应 10 进制数为 35 |
注:加粗标注的为不可打印字符
# 数值溢出
当超过一个数据类型能够存放最大的范围时,数值会溢出。有符号位最高位溢出的区别:符号位溢出会导致数的正负发生改变,但最高位的溢出会导致最高位丢失
数据类型 | 占用空间 | 取值范围 |
---|---|---|
char | 1 字节 | -128 到 127 (-27 ~ 27-1) |
unsigned char | 1 字节 | 0 到 255 (0 ~ 28-1) |
#include <stdio.h> | |
int main() | |
{ | |
char ch; | |
// 符号位溢出会导致数的正负发生改变 | |
ch = 0x7f + 2; //127+2 | |
printf("%d\n", ch); | |
// 0111 1111 | |
//+2 后 1000 0001,这是负数补码,其原码为 1111 1111,结果为 - 127 | |
// 最高位的溢出会导致最高位丢失 | |
unsigned char ch2; | |
ch2 = 0xff+1; //255+1 | |
printf("%u\n", ch2); | |
// 1111 1111 | |
//+1 后 10000 0000, char 只有 8 位最高位的溢出,结果为 0000 0000,十进制为 0 | |
ch2 = 0xff + 2; //255+2 | |
printf("%u\n", ch2); | |
// 1111 1111 | |
//+1 后 10000 0001, char 只有 8 位最高位的溢出,结果为 0000 0001,十进制为 1 | |
return 0; | |
} |
# 实型 float
double
# 定义
浮点型变量是由有限的存储单元组成的,因此只能提供有限的有效数字。在有效位以外的数字将被舍去,这样可能会产生一些误差
数据类型 | 占用空间 | 有效数字范围 |
---|---|---|
float | 4 字节 | 7 位有效数字 |
double | 8 字节 | 15~16 位有效数字 |
通常,不以 f 结尾的常量是 double 类型,以 f 结尾的常量 (如 3.14f) 是 float 类型。
# 输入输出
打印格式 | 含义 |
---|---|
%f | 输入输出 float 类型 |
%lf | 输入输出 double 类型 |
# 类型限定符 extern
const
volatile
register
限定符 | 含义 |
---|---|
extern | 声明一个变量,extern 声明的变量没有建立存储空间 |
const | 定义一个常量,常量的值不能修改 |
volatile | 防止编译器优化代码 |
register | 定义寄存器变量,提高效率。register 是建议型的指令,而不是命令型的指令,如果 CPU 有空闲寄存器,那么 register 就生效,如果没有空闲寄存器,那么 register 无效 |
# 构造类型
TODO
# 指针类型
TODO
# 复合类型
TODO
# 运算符
# 算术运算符
运算符 | 意义 | 示例 | 结果 |
---|---|---|---|
+ | 正号 | +3 | 3 |
- | 负号 | -3 | -3 |
+ | 加 | 10 + 5 | 15 |
- | 减 | 10 - 5 | 5 |
* | 乘 | 10 * 5 | 50 |
/ | 除 | 10 / 5 | 2 |
% | 取模 (取余) | 10 % 3 | 1 |
++ | 前自增 | a=2; b=++a; | a=3; b=3; |
++ | 后自增 | a=2; b=a++; | a=3; b=2; |
-- | 前自减 | a=2; b=--a; | a=1; b=1; |
-- | 后自减 | a=2; b=a--; | a=1; b=2; |
# 赋值运算符
运算符 | 意义 | 示例 | 结果 |
---|---|---|---|
= | 赋值 | a=2; b=3; | a=2; b=3; |
+= | 加等于 | a=0; a+=2; | a=2; |
-= | 减等于 | a=5; a-=3; | a=2; |
*= | 乘等于 | a=2; a*=2; | a=4; |
/= | 除等于 | a=4; a/=2; | a=2; |
%= | 模等于 | a=3; a%=2; | a=1; |
# 比较运算符
运算符 | 意义 | 示例 | 结果 (bool) |
---|---|---|---|
== | 相等于 | 4 == 3 | 0 |
!= | 不等于 | 4 != 3 | 1 |
< | 小于 | 4 < 3 | 0 |
> | 大于 | 4 > 3 | 1 |
<= | 小于等于 | 4 <= 3 | 0 |
>= | 大于等于 | 4 >= 1 | 1 |
# 逻辑运算符
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
! | 非 | !a | 若 a 为假,则!a 为真; 如果 a 为真,则!a 为假。 |
&& | 与 | a && b | 若 a 和 b 都为真,则结果为真,否则为假。 |
|| | 或 | a || b | 若 a 和 b 有一个为真,则结果为真,二者都为假时,结果为假。 |
# 三目运算符
? 前表达式为真择取值 a,为假则取值 b c = ( a > b ? a : b )
# 其他运算符 sizeof
强制类型转换
# sizeof
- 用于求一个数据类型的占用空间的大小,单位为字节
- 返回值类型为
size_t
# 类型转换
分为自动类型转换(隐式转换,由编译系统自动完成)和强制类型转换
类型转换的原则:占用内存字节数少 (值域小) 的类型,向占用内存字节数多 (值域大) 的类型转换,以保证精度不降低
强制类型转换的格式为 (需转换的类型) 表达式 例:
a = (int)b
# 运算符优先级
<table>
<tr>
<td> 优先级 </td>
<td> 运算符 </td>
<td> 名称或含义 </td>
<td> 使用形式 </td>
<td> 结合方向 </td>
<td> 说明 </td>
</tr>
<tr>
<td>1</td>
<td>[]</td>
<td> 数组下标 </td>
<td> 数组名 [常量表达式]</td>
<td> 左到右 </td>
<td>--</td>
</tr>
<tr>
<td></td>
<td>()</td>
<td> 圆括号 </td>
<td>(表达式)/ 函数名 (形参表)</td>
<td></td>
<td>--</td>
</tr>
<tr>
<td></td>
<td>.</td>
<td> 成员选择(对象)</td>
<td> 对象。成员名 </td>
<td></td>
<td>--</td>
</tr>
<tr>
<td></td>
<td>-></td>
<td> 成员选择(指针)</td>
<td> 对象指针 -> 成员名 </td>
<td></td>
<td>--</td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td>2</td>
<td>-</td>
<td> 负号运算符 </td>
<td>- 表达式 </td>
<td> 右到左 </td>
<td> 单目运算符 </td>
</tr>
<tr>
<td></td>
<td>~</td>
<td> 按位取反运算符 </td>
<td>~ 表达式 </td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td>++</td>
<td> 自增运算符 </td>
<td> 变量名 / 变量名 </td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td>--</td>
<td> 自减运算符 </td>
<td>-- 变量名 / 变量名 --</td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td> 取值运算符 </td>
<td> 指针变量 </td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td>&</td>
<td> 取地址运算符 </td>
<td>& 变量名 </td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td>!</td>
<td> 逻辑非运算符 </td>
<td>! 表达式 </td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td>(类型)</td>
<td> 强制类型转换 </td>
<td>(数据类型) 表达式 </td>
<td></td>
<td>--</td>
</tr>
<tr>
<td></td>
<td>sizeof</td>
<td> 长度运算符 </td>
<td>sizeof (表达式)</td>
<td></td>
<td>--</td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td>3</td>
<td>/</td>
<td> 除 </td>
<td> 表达式 / 表达式 </td>
<td> 左到右 </td>
<td> 双目运算符 </td>
</tr>
<tr>
<td></td>
<td></td>
<td> 乘 </td>
<td> 表达式表达式 </td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td>%</td>
<td> 余数(取模)</td>
<td> 整型表达式 % 整型表达式 </td>
<td></td>
<td></td>
</tr>
<tr>
<td>4</td>
<td>+</td>
<td> 加 </td>
<td> 表达式 + 表达式 </td>
<td> 左到右 </td>
<td> 双目运算符 </td>
</tr>
<tr>
<td></td>
<td>-</td>
<td> 减 </td>
<td> 表达式 - 表达式 </td>
<td></td>
<td></td>
</tr>
<tr>
<td>5</td>
<td><<</td>
<td> 左移 </td>
<td> 变量 << 表达式 </td>
<td> 左到右 </td>
<td> 双目运算符 </td>
</tr>
<tr>
<td></td>
<td>>></td>
<td> 右移 </td>
<td> 变量 >> 表达式 </td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td>6</td>
<td>></td>
<td> 大于 </td>
<td> 表达式 > 表达式 </td>
<td> 左到右 </td>
<td> 双目运算符 </td>
</tr>
<tr>
<td></td>
<td>>=</td>
<td> 大于等于 </td>
<td> 表达式 >= 表达式 </td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td><</td>
<td> 小于 </td>
<td> 表达式 < 表达式 </td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td><=</td>
<td> 小于等于 </td>
<td> 表达式 <= 表达式 </td>
<td></td>
<td></td>
</tr>
<tr>
<td>7</td>
<td></td>
<td> 等于 </td>
<td> 表达式表达式 </td>
<td> 左到右 </td>
<td> 双目运算符 </td>
</tr>
<tr>
<td></td>
<td>!=</td>
<td> 不等于 </td>
<td> 表达式!= 表达式 </td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td>8</td>
<td>&</td>
<td> 按位与 </td>
<td> 表达式 & 表达式 </td>
<td> 左到右 </td>
<td> 双目运算符 </td>
</tr>
<tr>
<td>9</td>
<td>^</td>
<td> 按位异或 </td>
<td> 表达式 ^ 表达式 </td>
<td> 左到右 </td>
<td> 双目运算符 </td>
</tr>
<tr>
<td>10</td>
<td>|</td>
<td> 按位或 </td>
<td> 表达式 | 表达式 </td>
<td> 左到右 </td>
<td> 双目运算符 </td>
</tr>
<tr>
<td>11</td>
<td>&&</td>
<td> 逻辑与 </td>
<td> 表达式 && 表达式 </td>
<td> 左到右 </td>
<td> 双目运算符 </td>
</tr>
<tr>
<td>12</td>
<td>||</td>
<td> 逻辑或 </td>
<td> 表达式 || 表达式 </td>
<td> 左到右 </td>
<td> 双目运算符 </td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td>13</td>
<td>?:</td>
<td> 条件运算符 </td>
<td> 表达式 1?</td>
</tr>
<tr>
<td> 表达式 2: 表达式 3</td>
<td> 右到左 </td>
<td> 三目运算符 </td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td>14</td>
<td>=</td>
<td> 赋值运算符 </td>
<td> 变量 = 表达式 </td>
<td> 右到左 </td>
<td>--</td>
</tr>
<tr>
<td></td>
<td>/=</td>
<td> 除后赋值 </td>
<td> 变量 /= 表达式 </td>
<td></td>
<td>--</td>
</tr>
<tr>
<td></td>
<td>=</td>
<td> 乘后赋值 </td>
<td> 变量 = 表达式 </td>
<td></td>
<td>--</td>
</tr>
<tr>
<td></td>
<td>%=</td>
<td> 取模后赋值 </td>
<td> 变量 %= 表达式 </td>
<td></td>
<td>--</td>
</tr>
<tr>
<td></td>
<td>+=</td>
<td> 加后赋值 </td>
<td> 变量 += 表达式 </td>
<td></td>
<td>--</td>
</tr>
<tr>
<td></td>
<td>-=</td>
<td> 减后赋值 </td>
<td> 变量 -= 表达式 </td>
<td></td>
<td>--</td>
</tr>
<tr>
<td></td>
<td><<=</td>
<td> 左移后赋值 </td>
<td> 变量 <<= 表达式 </td>
<td></td>
<td>--</td>
</tr>
<tr>
<td></td>
<td>>>=</td>
<td> 右移后赋值 </td>
<td> 变量 >>= 表达式 </td>
<td></td>
<td>--</td>
</tr>
<tr>
<td></td>
<td>&=</td>
<td> 按位与后赋值 </td>
<td> 变量 &= 表达式 </td>
<td></td>
<td>--</td>
</tr>
<tr>
<td></td>
<td>^=</td>
<td> 按位异或后赋值 </td>
<td> 变量 ^= 表达式 </td>
<td></td>
<td>--</td>
</tr>
<tr>
<td></td>
<td>|=</td>
<td> 按位或后赋值 </td>
<td> 变量 |= 表达式 </td>
<td></td>
<td>--</td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td>15</td>
<td>,</td>
<td> 逗号运算符 </td>
<td> 表达式,表达式,…</td>
<td> 左到右 </td>
<td>--</td>
</tr>
<tr>
<td></td>
</tr>
</table>