C 备忘清单 === 提供基本语法和方法的 C 快速参考备忘单。 入门 ---- ### hello.c ```c #include int main() { printf("Hello World!"); return 0; } ``` 使用 `gcc` 编译 `hello.c` 文件 ```bash $ gcc -o hello hello.c ``` 运行编译后的二进制文件(`hello`) ```bash $ ./hello # 输出 => Hello World ``` ### 变量 ```c int myNum = 15; int myNum2; // 不赋值,然后再赋值 myNum2 = 15; int myNum3 = 15; // myNum3 值为 15 myNum3 = 10; // 现在 myNum3 值为 10 float myFloatNum = 5.99; // 浮点数 char myLetter = 'D'; // 字符串 int x = 5; int y = 6; int sum = x + y; // 添加变量相加 // 声明多个变量 int x = 5, y = 6, z = 50; ``` ### 常量 Constants ```c const int minutesPerHour = 60; const float PI = 3.14; ``` 最佳实践 ```c const int BIRTHYEAR = 1980; ``` ### 注释 ```c // 这是一个注释 printf("Hello World!"); // 这是一个注释 /* 多行注释,上面的代码将打印出 Hello World! 到屏幕上,真是太棒了 */ ``` ### 打印文本 ```c printf("I am learning C."); int testInteger = 5; printf("Number = %d", testInteger); float f = 5.99; // 浮点数 printf("Value = %f", f); short a = 0b1010110; // 2 进制数字 int b = 02713; // 8 进制数字 long c = 0X1DAB83; // 16 进制数字 // 以 8 进制形似输出 printf("a=%ho, b=%o, c=%lo\n", a, b, c); // 输出 => a=126, b=2713, c=7325603 // 以 10 进制形式输出 printf("a=%hd, b=%d, c=%ld\n", a, b, c); // 输出 => a=86, b=1483, c=1944451 // 以 16 进制形式输出(字母小写) printf("a=%hx, b=%x, c=%lx\n", a, b, c); // 输出 => a=56, b=5cb, c=1dab83 // 以 16 进制形式输出(字母大写) printf("a=%hX, b=%X, c=%lX\n", a, b, c); // 输出 => a=56, b=5CB, c=1DAB83 ``` ### 控制空格数 ```c int a1=20, a2=345, a3=700; int b1=56720, b2=9999, b3=20098; int c1=233, c2=205, c3=1; int d1=34, d2=0, d3=23; printf("%-9d %-9d %-9d\n", a1, a2, a3); printf("%-9d %-9d %-9d\n", b1, b2, b3); printf("%-9d %-9d %-9d\n", c1, c2, c3); printf("%-9d %-9d %-9d\n", d1, d2, d3); ``` 输出结果 ```bash 20 345 700 56720 9999 20098 233 205 1 34 0 23 ``` `%-9d` 中,`d` 表示以 `10` 进制输出,`9` 表示最少占 `9` 个字符的宽度,宽度不足以空格补齐,`-` 表示左对齐 ### 字符串 Strings ```c char greetings[] = "Hello World!"; printf("%s", greetings); ``` 访问字符串 ```c char greetings[] = "Hello World!"; printf("%c", greetings[0]); ``` 修改字符串 ```c char greetings[] = "Hello World!"; greetings[0] = 'J'; printf("%s", greetings); // 输出 "Jello World!" ``` 另一种创建字符串的方法 ```c char greetings[] = {'H','e','l','l','\0'}; printf("%s", greetings); // 输出 "Hell!" ``` `C` **没有** String 类型,使用 `char` 类型并创建一个字符 `array` ### 条件判断 ```c int time = 20; if (time < 18) { printf("再会!"); } else { printf("晚上好!"); } // 输出 -> "晚上好!" int time = 22; if (time < 10) { printf("早上好!"); } else if (time < 20) { printf("再会!"); } else { printf("晚上好!"); } // 输出 -> "晚上好!" ``` ### 三元运算符 ```c int time = 20; (time < 18) ? printf("再会!") : printf("晚上好!"); ``` ### Switch ```c int day = 4; switch (day) { case 3: printf("周三"); break; case 4: printf("周四"); break; default: printf("期待周末"); } // 输出 -> "周四" (day 4) ``` ### While 循环 ```c int i = 0; while (i < 5) { printf("%d\n", i); i++; } ``` **注意**:不要忘记增加条件中使用的变量,否则循环永远不会结束,成为“死循环”! ### Do/While 循环 ```c int i = 0; do { printf("%d\n", i); i++; } while (i < 5); ``` ### For 循环 ```c int i; for (i = 0; i < 5; i++) { printf("%d\n", i); } ``` ### 跳出循环 Break/Continue ```c int i; for (i = 0; i < 10; i++) { if (i == 4) { break; } printf("%d\n", i); } ``` 在 `i` 等于 `4` 时跳出循环 ```c int i; for (i = 0; i < 10; i++) { if (i == 4) { continue; } printf("%d\n", i); } ``` 示例跳过 `4` 的值 ### While Break 示例 ```c int i = 0; while (i < 10) { if (i == 4) { break; } printf("%d\n", i); i++; } ``` ### While continue 示例 ```c int i = 0; while (i < 10) { i++; if (i == 4) { continue; } printf("%d\n", i); } ``` ### 数组 Arrays ```c int myNumbers[] = {25, 50, 75, 100}; printf("%d", myNumbers[0]); // 输出 25 ``` 更改数组元素 ```c int myNumbers[] = {25, 50, 75, 100}; myNumbers[0] = 33; printf("%d", myNumbers[0]); ``` 循环遍历数组 ```c int myNumbers[] = {25, 50, 75, 100}; int i; for (i = 0; i < 4; i++) { printf("%d\n", myNumbers[i]); } ``` 设置数组大小 ```c // 声明一个由四个整数组成的数组: int myNumbers[4]; // 添加元素 myNumbers[0] = 25; myNumbers[1] = 50; myNumbers[2] = 75; myNumbers[3] = 100; ``` ### 枚举 Enum ```c enum week { Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun }; ``` 定义枚举变量 ```c enum week a, b, c; enum week { Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun } a, b, c; ``` 有了枚举变量,就可以把列表中的值赋给它 ```c enum week { Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun }; enum week a = Mon, b = Wed, c = Sat; // 或者 enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun } a = Mon, b = Wed, c = Sat; ``` ### 枚举示例应用 ```c enum week {Mon = 1, Tues, Wed, Thurs} day; scanf("%d", &day); switch(day){ case Mon: puts("Monday"); break; case Tues: puts("Tuesday"); break; case Wed: puts("Wednesday"); break; case Thurs: puts("Thursday"); break; default: puts("Error!"); } ``` ### 用户输入 ```c // 创建一个整数变量来存储我们从用户那里得到的数字 int myNum; // 要求用户输入一个数字 printf("请输入一个数字: \n"); // 获取并保存用户输入的号码 scanf("%d", &myNum); // 输出用户输入的数字 printf("您输入的数字: %d", myNum); ``` ### 用户输入字符串 ```c // 创建一个字符串 char firstName[30]; // 要求用户输入一些文本 printf("输入您的名字: \n"); // 获取并保存文本 scanf("%s", firstName); // 输出文本 printf("Hello %s.", firstName); ``` ### 内存地址 创建变量时,会为该变量分配一个内存地址 ```c int myAge = 43; printf("%p", &myAge); // 输出:0x7ffe5367e044 ``` 要访问它,请使用引用运算符 (`&`) ### 创建指针 ```c int myAge = 43; // 一个 int 变量 printf("%d", myAge); // 输出 myAge(43)的值 // 输出 myAge 的内存地址(0x7ffe5367e044) printf("%p", &myAge); ``` ### 指针变量 ```c int myAge = 43; // 一个 int 变量 int* ptr = &myAge; // 名为 ptr 的指针变量,用于存储 myAge 的地址 printf("%d\n", myAge); // 输出 myAge (43) 的值 printf("%p\n", \&myAge); // 输出 myAge 的内存地址(0x7ffe5367e044) printf("%p\n", ptr); // 用指针(0x7ffe5367e044)输出myAge的内存地址 ``` ### 取消引用 ```c int myAge = 43; // 变量声明 int* ptr = &myAge; // 指针声明 // 参考:用指针输出 myAge 的 // 内存地址(0x7ffe5367e044) printf("%p\n", ptr); // 取消引用:用指针输出 myAge 的值 (43) printf("%d\n", *ptr); ``` 运算符 --- ### 算术运算符 ```c int myNum = 100 + 50; int sum1 = 100 + 50; // 150 (100 + 50) int sum2 = sum1 + 250; // 400 (150 + 250) int sum3 = sum2 + sum2; // 800 (400 + 400) ``` ---- | Operator | Name | Description | Example | | -------- | -------- | -------- | -------- | | `+` | 加 | 将两个值相加 | `x + y` | | `-` | 减 | 从另一个值中减去一个值 | `x - y` | | `*` | 乘 | 将两个值相乘 | `x * y` | | `/` | 除 | 将一个值除以另一个 | `x / y` | | `%` | 取模 | 返回除法余数 | `x % y` | | `++` | 增量 | 将变量的值增加 1 | `++` | | `--` | 乘量 | 将变量的值减 1 | `--x` | ### 赋值运算符 | 符号 | 示例 | 如同 | | -------- | ------- | ---------- | | `=` | x `=` 5 | x `=` 5 | | `+=` | x `+=` 3 | x `=` x `+` 3 | | `-=` | x `-=` 3 | x `=` x `-` 3 | | `*=` | x `*=` 3 | x `=` x `*` 3 | | `/=` | x `/=` 3 | x `=` x `/` 3 | | `%=` | x `%=` 3 | x `=` x `%` 3 | | `&=` | x `&=` 3 | x `=` x `&` 3 | | `\|=` | x `\|=` 3 | x `=` x `\|` 3 | | `^=` | x `^=` 3 | x `=` x `^` 3 | | `>>=` | x `>>=` 3 | x `=` x `>>` 3 | | `<<=` | x `<<=` 3 | x `=` x `<<` 3 | ### 比较运算符 ```c int x = 5; int y = 3; printf("%d", x > y); // 返回 1(真),因为 5 大于 3 ``` ---- | 符号 | 名称 | 示例 | | -------- | ------- | ------- | | `==` | 等于 | x `==` y | | `!=` | 不等于 | x `!=` y | | `>` | 大于 | x `>` y | | `<` | 小于 | x `<` y | | `>=` | 大于或等于 | x `>=` y | | `<=` | 小于或等于 | x `<=` y | 比较运算符用于比较两个值 ### 逻辑运算符 | 符号 | 名称 | 说明 | 示例 | | -------- | -------- | -------- | -------- | | `&&` | `与`逻辑 | 如果两个语句都为真,则返回真 | `x < 5 && x < 10` | | `\|\|` | `或`逻辑 | 如果其中一个语句为真,则返回真 | `x < 5 \|\| x < 4` | | `!` | `非`逻辑 | 反转结果,如果结果为真则返回假 | `!(x < 5 && x < 10)` | ### 运算符示例 ```c unsigned int a = 60; /* 60 = 0011 1100 */ unsigned int b = 13; /* 13 = 0000 1101 */ int c = 0; c = a & b; /* 12 = 0000 1100 */ printf("Line 1 - c 的值是 %d\n", c ); c = a | b; /* 61 = 0011 1101 */ printf("Line 2 - c 的值是 %d\n", c ); c = a ^ b; /* 49 = 0011 0001 */ printf("Line 3 - c 的值是 %d\n", c ); c = ~a; /*-61 = 1100 0011 */ printf("Line 4 - c 的值是 %d\n", c ); c = a << 2; /* 240 = 1111 0000 */ printf("Line 5 - c 的值是 %d\n", c ); c = a >> 2; /* 15 = 0000 1111 */ printf("Line 6 - c 的值是 %d\n", c ); ``` ### 位运算符 运算符 | 描述 | 实例 :- |:- |:- `&` | 按位与操作,按二进制位进行"与"运算 | `(A & B)` 将得到 `12` 即为 0000 1100 `\|` | 按位或运算符,按二进制位进行"或"运算 | `(A \| B)` 将得到 `61` 即为 0011 1101 `^` | 异或运算符,按二进制位进行"异或"运算 | `(A ^ B)` 将得到 `49` 即为 0011 0001 `~` | 取反运算符,按二进制位进行"取反"运算 | `(~A)` 将得到 `-61` 即为 1100 0011 `<<` | 二进制左移运算符 | `A << 2` 将得到 `240` 即为 1111 0000 `>>` | 二进制右移运算符 | `A >> 2` 将得到 `15` 即为 0000 1111 数据类型 Data Types --- ### 基本数据类型 | 数据类型 | 大小 Size | 范围 Range | 描述 Description | | ----- | ----- | ----- | ----- | | `char` | 1 字节 | `−128` ~ `127` | 单个字符/字母/数字/ASCII | | `signed char` | 1 字节 | `−128` ~ `127` | - | | `unsigned char` | 1 字节 | `0` ~ `255` | - | | `int` | `2` 到 `4` 字节 | `−32,768` ~ `32,767` | 存储整数 | | `signed int` | 2 字节 | `−32,768` ~ `32,767` | | | `unsigned int` | 2 字节 | `0` ~ `65,535` | | | `short int` | 2 字节 | `−32,768` ~ `32,767` | | | `signed short int` | 2 字节 | `−32,768` ~ `32,767` | | | `unsigned short int` | 2 字节 | `0` ~ `65,535` | | | `long int` | 4 字节 | `-2,147,483,648` ~ `2,147,483,647` | | | `signed long int` | 4 字节 | `-2,147,483,648` ~ `2,147,483,647` | | | `unsigned long int` | 4 字节 | `0` ~ `4,294,967,295` | | | `float` | 4 字节 | | | | `double` | 8 字节 | | | | `long double` | 10 字节 | | | ### 数据类型 ```c // 创建变量 int myNum = 5; // 整数 float myFloatNum = 5.99; // 浮点数 char myLetter = 'D'; // 字符串 // 高精度浮点数据或数字 double myDouble = 3.2325467; // 打印输出变量 printf("%d\n", myNum); printf("%f\n", myFloatNum); printf("%c\n", myLetter); printf("%lf\n", myDouble); ``` --- 数据类型 | 说 明 :- | :- `char` | 字符型 `short` | 短整型 `int` | 整型 `long` | 长整型 `float` | 单精度浮点型 `double` | 双精度浮点型 `void` | 无类型 ### 基本格式说明符 | 格式说明符 | 数据类型 | | ----- | ----- | | `%d` 或 `%i` | `int` 整数 | | `%f` | `float` 单精度的十进制类型 | | `%lf` | `double` 高精度浮点数据或数字 | | `%c` | `char` 字符 | | `%s` | 用于 `strings` 字符串 | ### 基本格式说明符 | | short | int | long | | ---- | ---- | ---- | ---- | | 8 进制 | `%ho` | `%o` | `%lo` | | 10 进制 | `%hd` | `%d` | `%ld` | | 16 进制 | `%hx` / `%hX` | `%x` / `%X` | `%lx` / `%lX` | ### 数据格式示例 ```c int myNum = 5; float myFloatNum = 5.99; // 浮点数 char myLetter = 'D'; // 字符串 // 打印输出变量 printf("%d\n", myNum); printf("%f\n", myFloatNum); printf("%c\n", myLetter); ``` 预处理器 --- ### 预处理器指令 指令 | 描述 ---- | ---- `#define` | 定义宏 `#include` | 包含一个源代码文件 `#undef` | 取消已定义的宏 `#ifdef` | 如果宏已经定义,则返回真 `#ifndef` | 如果宏没有定义,则返回真 `#if` | 如果给定条件为真,则编译下面代码 `#else` | `#if` 的替代方案 `#elif` | 如果 `#if` 条件为假,当前条件为`真` `#endif` | 结束一个 `#if……#else` 条件编译块 `#error` | 当遇到标准错误时,输出错误消息 `#pragma` | 使用标准化方法,向编译器发布特殊的命令到编译器中 ```c // 所有的 MAX_ARRAY_LENGTH 替换为 20 #define MAX_ARRAY_LENGTH 20 // 系统库中获取 stdio.h #include // 本地目录中获取 myheader.h #include "myheader.h" #undef FILE_SIZE #define FILE_SIZE 42 // 取消已定义并定义为 42 ``` ### 预定义宏 宏 | 描述 ---- | ---- `__DATE__` | 当前日期,一个以 "MMM DD YYYY" 格式表示的字符常量 `__TIME__` | 当前时间,一个以 "HH:MM:SS" 格式表示的字符常量 `__FILE__` | 这会包含当前文件名,一个字符串常量 `__LINE__` | 这会包含当前行号,一个十进制常量 `__STDC__` | 当编译器以 `ANSI` 标准编译时,则定义为 `1` `ANSI C` 定义了许多宏,您可以使用这些宏,但是不能直接修改这些预定义的宏 #### 预定义宏示例 ```c #include int main() { printf("File :%s\n", __FILE__); printf("Date :%s\n", __DATE__); printf("Time :%s\n", __TIME__); printf("Line :%d\n", __LINE__); printf("ANSI :%d\n", __STDC__); } ``` ### 宏延续运算符(\) 一个宏通常写在一个单行上。 ```c #define message_for(a, b) \ printf(#a " 和 " #b ": 我们爱你!\n") ``` 如果宏太长,一个单行容纳不下,则使用宏延续运算符 `\` ### 字符串常量化运算符(#) ```c #include #define message_for(a, b) \ printf(#a " 和 " #b ": 我们爱你!\n") int main(void) { message_for(Carole, Debra); return 0; } ``` 当上面的代码被编译和执行时,它会产生下列结果: ``` Carole 和 Debra: 我们爱你! ``` 需要把一个宏的参数转换为字符串常量时,使用字符串常量化运算符 `#` ### 标记粘贴运算符(##) ```c #include #define tokenpaster(n) printf ("token" #n " = %d", token##n) int main(void){ int token34 = 40; tokenpaster(34); return 0; } ``` ### defined() 运算符 ```c #include #if !defined (MESSAGE) #define MESSAGE "You wish!" #endif int main(void) { printf("Here is the message: %s\n", MESSAGE); return 0; } ``` ### 参数化的宏 ```c int square(int x) { return x * x; } ``` 宏重写上面的代码,如下: ```c #define square(x) ((x) * (x)) ``` 宏名称和左圆括号之间不允许有空格 ```c #include #define MAX(x,y) ((x) > (y) ? (x) : (y)) int main(void) { printf("Max between 20 and 10 is %d\n", MAX(10, 20)); return 0; } ``` 另见 --- - [C 教程](https://jaywcjlove.github.io/c-tutorial) _(jaywcjlove.github.io)_