小工具知识网

当前位置: 首页 > 行业知识 > 程序的编译相关操作(C语言)

行业知识

程序的编译相关操作(C语言)

2026-10-25 02:35:43 来源:互联网转载

���已深

冬将至

人间至此秋色尽

一世繁华一世荒

程序的编译与预处理

  • 程序环境
    • 程序翻译环境
    • 程序执行环境
    • 程序预处理
      • 相关符号介绍
        • ️预定义符号
        • ️#define定义标识符
        • ️define定义宏
        • 宏和函数的对比
        • 其它预处理命名

          程序环境

          程序翻译环境

          在这个环境中源代码被转换为可执行的机器指令。

          程序执行环境

          1. 程序必须载入内存中。在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。

          2. 程序的执行便开始。接着便调用main函数。

          3. 开始执行程序代码。这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程一直保留他们的值。

          4. 终止程序。正常终止main函数;也有可能是意外终止。

          程序预处理

          相关符号介绍

          ️预定义符号

          NULL:表示空指针,用于指示指针变量没有指向任何对象。

          EOF:表示文件结束符,用于在文件输入时表示已经到达文件末尾。

          sizeof:用于获取数据类型或变量所占用的内存空间大小。

          const:用于声明常量,表示其值不可修改。

          volatile:用于声明变量的值可能会在程序运行期间被意外修改。

          signed:用于声明有符号类型的变量,可以表示正数和负数。

          unsigned:用于声明无符号类型的变量,只能表示非负整数。

          void:用于声明无类型类型的变量或函数,表示不返回任何值。

          do-while:用于创建循环结构,先执行循环体,再判断循环条件。

          for:用于创建循环结构,通常用于需要执行固定次数的循环操作。

          if:用于条件判断,根据条件是否成立来执行不同的代码块。

          switch:用于多分支条件判断,根据不同的条件执行不同的代码块。

          while:用于循环结构,先判断循环条件,再执行循环体。

          ......

          这些都是一些普通的预定义符号

          __FILE__      //进行编译的源文件__LINE__     //文件当前的行号__DATE__    //文件被编译的日期__TIME__    //文件被编译的时间__STDC__    //如果编译器遵循ANSI C,其值为1,否则未定义

          这些都是C语言内置的预定义符号。大家可以试着去编译下,看看效果,平常我们都很少用到。

          ️#define定义标识符

          在C语言中,#define是预处理指令,它用来定义标识符或常量。当你使用#define定义一个标识符时,编译器会将其替换为你在定义时指定的文本。例如,你可以使用#define定义一个常量:

          #define PI 3.14159//在这个例子中,当你使用PI时,编译器会将其替换为3.14159。
          #define  max 100//在这个例子中,当你使用PI时,编译器会将其替换为3.14159。

          ️define定义宏

          #define Add(x) ((x) * (x))//在这个例子中,Add(x)会被替换为((x) * (x))。//注意宏的参数在替换时需要用括号括起来,以避免因为运算符优先级产生的问题。//例如,如果你不使用括号,Add(x + 2)会被展开为x + 2 * x + 2,而不是你预期的(x + 2) * (x + 2)。

          需要注意的是,#define定义的标识符在预处理阶段就会被展开,而不会在运行时进行计算。因此,使用宏进行计算可能会影响程序的性能。

          注意:

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

          宏和函数的对比

          宏和函数在C语言中都用于实现代码的复用和简化,但它们在实现方式和用途上有一些不同。

          执行方式:函数在程序运行时被调用,执行对应的代码块。宏在预处理阶段进行文本替换,不占用函数调用的时间和空间。

          类型检查:函数具有强类型检查,编译器会检查函数参数类型和返回值类型。宏在替换时不会进行类型检查,容易出现错误。

          安全性:函数是安全的,因为它们有参数类型检查和返回值。宏可能会出现错误或不安全的表达式。

          调试:函数可以设置断点进行调试,而宏不能进行调试。

          作用域:函数具有局部作用域,宏具有全局作用域。

          性能:函数调用需要一定的开销,包括保存寄存器、栈操作等。宏替换没有这些开销,但可能会增加代码大小,降低运行速度。

          使用场景:函数是可重用的代码块,通常用于封装复杂逻辑。宏通常用于替换简单的文本或常量,提高代码可读性。

          在实际编程中,应根据具体需求选择使用宏还是函数。如果需要类型检查、安全性高或需要调试的代码块,应使用函数。如果需要替换简单的文本或常量,提高代码可读性,可以使用宏。

          其它预处理命名

          除了#define,C语言中还有其他一些预处理命名,包括:

          #include:用于包含头文件,将头文件中的代码插入到程序中。

          #ifndef、#define、#endif:用于防止头文件被重复包含。

          #if、#elif、#else、#endif:用于条件编译,根据条件决定是否编译某段代码。

          #warning:用于在编译时输出警告信息。

          #error:用于在编译时输出错误信息。

          #line:用于改变预处理器所报告的当前文件名和行号。

          #pragma:用于改变编译器的特定设置。

          这些预处理命名都是在编译阶段进行处理的,可以用来控制编译过程、生成特定代码或输出信息等。

上一篇:物理服务器项目介绍怎么写?

下一篇:怎么建造服务器计分板?