vault backup: 2026-01-22 20:49:01

This commit is contained in:
2026-01-22 20:49:01 +08:00
parent b810d55176
commit 4ff1cb1a94
6 changed files with 175 additions and 162 deletions

View File

@@ -77,19 +77,19 @@ gcc hello.o -o hello
1. 向编译器传送特定指令:#progma
| 指令 | 描述 | 使用示例 |
| -- | -- | -- |
| #define | 定义宏(符号常量或函数式宏) | #define PI 3.14159 |
| #include | 包含头文件 | #include <stdio.h> |
| #undef | 取消已定义的宏 | #undef PI |
| #ifdef | 如果宏已定义则编译后续代码 | #ifdef DEBUG |
| #ifndef | 如果宏未定义则编译后续代码(常用于头文件保护) | #ifndef HEADER_H |
| #if | 条件编译可配合defined操作符使用 | #if VERSION > 2 |
| #else | #if | #ifdef WIN32 |
| #elif | 类似于else if | #if defined(UNIX) |
| #endif | 结束条件编译块 | 如上例所示 |
| #error | 产生编译错误并输出消息 | #if !defined(C99) |
| #pragma | 编译器特定指令(非标准,各编译器不同) | #pragma once |
| 指令 | 描述 | 使用示例 | |
| ---------- | ----------------------- | ------------------- | --- |
| `#define` | 定义宏(符号常量或函数式宏) | `#define PI 3.14159` | |
| `#include` | 包含头文件 | `#include <stdio.h>` | |
| `#undef` | 取消已定义的宏 | `#undef PI` | |
| `#ifdef` | 如果宏已定义则编译后续代码 | `#ifdef DEBUG` | |
| `#ifndef` | 如果宏未定义则编译后续代码(常用于头文件保护) | `#ifndef HEADER_H` | |
| `#if` | 条件编译可配合defined操作符使用 | `#if VERSION > 2` | |
| `#else` | `#if` | `#ifdef WIN32` | |
| `#elif` | 类似于else if | `#if defined(UNIX)` | |
| `#endif` | 结束条件编译块 | 如上例所示 | |
| `#error` | 产生编译错误并输出消息 | `#if !defined(C99)` | |
| `#pragma` | 编译器特定指令(非标准,各编译器不同) | `#pragma once` | |
- 基本语法
@@ -214,7 +214,7 @@ int main()
}
```
直观上看,无论 y 的取值是多少,表达式 y==200?888:999 的值一定比 x 要大,但由于宏定义仅仅是文本替换,中间不涉及任何运算,因此等价于:
直观上看,无论 y 的取值是多少,表达式 `y==200?888:999` 的值一定比 x 要大,但由于宏定义仅仅是文本替换,中间不涉及任何运算,因此等价于:
```c
printf("最大值:%d\n", x>y==200?888:999 ? x : y==200?888:999);
@@ -476,11 +476,11 @@ int main(int argc, char *argv[])
- 总结:
- #ifdef#ifndef此种形式,判定的是宏是否已被定义,这不要求宏有值。
- `#ifdef``#ifndef`此种形式,判定的是宏是否已被定义,这不要求宏有值。
- #if#elif 这些形式,判定的是宏的值是否为真,这要求宏必须有值。
- `#if``#elif` 这些形式,判定的是宏的值是否为真,这要求宏必须有值。
- #ifdef#ifndef#if结尾需要添加#endif表示结束条件,用以包裹代码块选择那一部分代码参与编译。
- `#ifdef``#ifndef``#if`结尾需要添加`#endif`表示结束条件,用以包裹代码块选择那一部分代码参与编译。
### **条件编译的使用场景**
@@ -714,9 +714,9 @@ union attr // 6联合体的定义
- 特别说明:
1. 全局变量、普通函数的定义一般出现在某个源文件(*.c )中,其他的源文件想要使用都需要进行声明(extern),因此一般放在头文件中更方便。
1. 全局变量、普通函数的定义一般出现在某个源文件(`*.c` )中,其他的源文件想要使用都需要进行声明(extern),因此一般放在头文件中更方便。
1. 静态函数、宏定义、结构体、联合体的定义都只能在其所在的文件可见,因此如果多个源文件都需要使用的话,放到头文件中定义是最方便,也是最安全的选择。
2. 静态函数、宏定义、结构体、联合体的定义都只能在其所在的文件可见,因此如果多个源文件都需要使用的话,放到头文件中定义是最方便,也是最安全的选择。
### **头文件的使用**
@@ -741,7 +741,7 @@ int main()
### **头文件的格式**
由于头文件包含指令 #include 的本质是复制粘贴,并且一个头文件中可以嵌套包含其他头文件,因此很容易出现一种情况是:头文件被重复包含。
由于头文件包含指令 `#include` 的本质是复制粘贴,并且一个头文件中可以嵌套包含其他头文件,因此很容易出现一种情况是:头文件被重复包含。
- 使用条件编译,解决头文件重复包含的问题,格式如下:
@@ -776,7 +776,7 @@ gec@ubuntu:~/pro$ gcc main.c -o main -I /home/gec/pro/inc
- 语法要点:
- 预处理指令 #include 的本质是复制粘贴:将指定头文件的内容复制到源码文件中。
- 预处理指令 `#include` 的本质是复制粘贴:将指定头文件的内容复制到源码文件中。
- 系统标准头文件路径可以通过编译选项 -v 来获知,比如:
@@ -797,7 +797,7 @@ gec@ubuntu:~/pro$ gcc main.c -I /home/gec/pro/inc -v
![](images/WEBRESOURCEcb03335b039dd3101bd1e33868113656image.png)
**注意:*是通配符表示将src目录下的所有以.c结尾的文件都参与编译**
**注意:`*`是通配符表示将src目录下的所有以.c结尾的文件都参与编译**
![](images/WEBRESOURCE54710c7a76c34ce186adf7550689b814image.png)