Cweek6

C语言学习

十六.程序环境和预处理

1.翻译环境和运行环境

编译又分为三个阶段:

  1. 预编译(文本操作):将include引入的头文件展开成代码,并把注释删除,使用空格代替注释,替换#define的文本
  2. 编译:把c语言代码翻译成汇编代码(语法分析、词法分析、语义分析、符号汇总)
  3. 汇编:把汇编代码转换成二进制指令,形成符号表

链接:1.合并段表,2.符号表的合并和重定位
运行环境:

  1. 程序必须载入内存中,有操作系统的环境中:这个一般由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成
  2. 程序的执行然后开始,接着调用main函数
  3. 开始执行程序代码,这个时候程序将使用一个运行时堆栈,存储函数的局部变量和返回地址。 程序同时使用静态内存
  4. 终止程序

2.预定义符号

图片消失了

3.#define定义标识符

语法:#define 名字 值(可以加;,最好不加,容易报错)
这个值也可以是一段代码,如果值过长,可以分成几行写,除最后一行外,每行的后面都加一个\

#define定义宏

宏的声明:#define name(parament-list) stuff
parament-list是由,隔开的参数列表
注意:传参是完全替换,如果参数里写1 + 1,那传过去的就是1 + 1,解决方法是把X + X写成((X) + (X))

#define替换规则

①调用宏时,首先对参数进行检查,查看是否包含任何由#define定义的符号。如果是,则替换
②替换文本随后被插入到程序中原来文本的位置,对于宏,参数名被他们的值替换
③最后,再次对结果文件进行扫描,查看是否包含任何由#define定义的符号。如果是,则重复上述步骤
注意事项:

  1. 宏参数和#define定义中可以出现其它#define定义的变量。但是对于宏,不能出现递归
  2. 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不会被搜索

4.#和##

#define PRINT(X) printf("X say", X)

这段代码中,X是字符串中的字符,不会被替换
可以用#让参数插入到字符串中:

#define PRINT(X) printf(#X" say", X)

##的作用:可以把它两边的可以将两个宏参数连接成一个单一的标记
例子:

#define CONCAT(a, b) a ## b

int main() {
    int xy = 10;
    int x = 1;
    int y = 2;
    
    // 使用宏CONCAT来连接x和y,形成标识符xy
    printf("%d\n", CONCAT(x, y));  // 输出: 10
    
    return 0;
}

5.带有副作用的宏参数

当宏参数在宏的定义中出现超过一次的时候,如果参数带有副作用,那么这个宏的使用就存在风险
比如a++在宏中出现超过一次时,使用宏之后a会不止加一次1

6.宏和函数的对比

宏在调试时就被替换,所以效率高,宏是类型无关的
但是宏是无法调试的,不能递归的,不够严谨的,容易出错的
但是宏可以做到函数做不到的:宏的参数可以出现类型
宏的命名一般是全部大写,函数名全不大写

7.#undef

#undef 是一个预处理指令,用于取消定义一个预处理器符号(宏)。当你使用 #define 定义了一个宏之后,可以使用 #undef 来取消该宏的定义

8.命令行定义

在用命令行运行代码时,可以用命令行定义符号
如:gcc test.c -D SZ=5

9.条件编译

调试性的代码,删除可惜,保留又碍事,所以我们可以选择性的编译
常见的条件编译指令:

  1. #if 代码 #endif
  2. #if 代码 #elif 代码 #else 代码 #endif
  3. #if defined(符号)等价于#ifdef 变量名,意为如果符号被定义了(后面也要加#endif)
  4. #if !defined(符号)等价于#ifndef 变量名,意为符号没有被定义(后面也要加#endif)
  5. #if defined(符号) 代码 #elif defined 代码 #endif

10.文件包含

本地文件被包含:#include “文件名”
库文件包含:#include <文件名>
如果硬要使用 #include <> 来包含本地文件,编译器会在系统的标准头文件路径中查找该文件,而不是在当前源文件所在的目录中查找。因此,如果你的本地文件不在标准头文件路径中,编译器就会报错,无法找到该文件

文件嵌套包含

在引文件时可能会重复引用,为了避免这个问题可以用条件编译:
在每个文件的开头写:
请添加图片描述

或者:
#pragma once

11.其它预处理指令

图片消失了

详见官网

相关推荐

  1. <span style='color:red;'>Cweek</span><span style='color:red;'>6</span>

    Cweek6

    2024-06-17 08:04:01      7 阅读
  2. <span style='color:red;'>Cweek</span>4+5

    Cweek4+5

    2024-06-17 08:04:01      12 阅读
  3. 2024/6/6随笔

    2024-06-17 08:04:01       10 阅读
  4. 作业<span style='color:red;'>6</span>.<span style='color:red;'>6</span>

    作业6.6

    2024-06-17 08:04:01      10 阅读
  5. git-<span style='color:red;'>6</span>

    git-6

    2024-06-17 08:04:01      39 阅读
  6. CTF <span style='color:red;'>6</span>

    CTF 6

    2024-06-17 08:04:01      40 阅读
  7. day 6

    2024-06-17 08:04:01       47 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-17 08:04:01       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-17 08:04:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-17 08:04:01       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-17 08:04:01       20 阅读

热门阅读

  1. 力扣2517.礼盒的最大甜蜜度

    2024-06-17 08:04:01       7 阅读
  2. 分布式压测

    2024-06-17 08:04:01       7 阅读
  3. 数据驱动和vue的双向绑定有何异同

    2024-06-17 08:04:01       6 阅读
  4. 使用Python进行数据分析与可视化

    2024-06-17 08:04:01       7 阅读
  5. 数据分析------知识点(六)

    2024-06-17 08:04:01       6 阅读
  6. 【Python】 Stacking: 强大的集成学习方法

    2024-06-17 08:04:01       11 阅读