【C】程序的编译/链接/预处理详解(C语言内功,精炼,基础)

简介: 【C】程序的编译/链接/预处理详解(C语言内功,精炼,基础)

一.程序的翻译环境和执行环境

在ANSI C的任何一种实现中,存在两个不同的环境

  • 翻译环境,此过程中源代码转换为可执行的机器指令
  • 执行环境,它用于实际执行代码

image.png

二.编译和链接的过程

image.pngimage.png

三.编译的几个阶段

image.png

image.png

1.形成符号表的过程:

image.png

image.png

2.段表的合并和重定位随后进行链接:

image.png

四.运行环境

程序执行的过程:


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

程序的执行便开始,接着调用main函数

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

五.预定义符号

__FILE__       //进行编译的源文件

__LINE__      //文件当前的行号

__DATE__     //文件被编译的日期

__TIME__     //文件被编译的时间

__STDC__     //如果编译器遵循ANSI C,其值为1,否则未定义

image.png

六.define/undef

define的两个用法:


  •  定义符号(标识符)
  •  定义

undef:用于移除宏定义  

image.png

image.png

1.define定义符号时,语法要求:

image.png

  • 不要加上  ;
  • 一般情况下大写

 image.png

2.define定义宏时,语法要求:

image.png

  • 注意要加入括号,防止整体替换时次序发生变化
  • image.png image.png

七.#define替换规则

image.png

八.#和##的应用

1.#作用:把一个宏的参数变成对应的字符串

image.png

2.##的作用: 可以把位于其两端的(分离片段)符号合成一个符号

image.png

九.带副作用(功能)的宏参数

image.png

十.宏与函数的对比

1.宏的优点:

          1.小型工作时反应速度更快


          2.不需要指定特定类型(宏是类型无关的)


2.宏的缺点:

         1,用一次,会在文本中插入一次代码


         2,无法调试


         3,与参数类型无关,不够严谨


         4,可能存在运算符优先级的问题


3.宏能做到而函数做不到的例子:  

image.png

4.宏和函数全面对比一览:

image.png

十一.条件编译(预处理指令)

image.png

例如:

image.png

1.预处理指令和普通判断语句的区别:

  • 预处理指令在预处理阶段就将不要的代码删除
  • 后面都要跟一个endif收尾

2.常见的条件编译指令:

  • 普通条件编译:if/endif

image.png

  • 多分支的条件编译:if/elif/else/endif
  • image.png
  • 判断是否被定义

          if defined(symbol)/ifdef symbol   if !defined(symbol)/ifndef symbol

image.png

  • 嵌套指令
  • image.png

十二.文件包含过程

  • " " 查找两次
  • < >查找一次

image.png

1.例题: include"test.h"与include <test.h>有什么区别?

答:两者查找策略不同

十三.解决嵌套头文件包含问题

在进行大项目制作时,常常会出现如下情况:comm.h同时通过左右被重复包含,造成冗余

image.png

1.两种解决方案:

  1. prama once(编译器创建头文件时有时候会默认加
  2. 条件编译

image.png

2.例题:头文件中的ifndef/define/endif是干什么用的?

答:防止头文件被重复包含

相关文章
|
1月前
|
存储 自然语言处理 编译器
【C语言】编译与链接:深入理解程序构建过程
【C语言】编译与链接:深入理解程序构建过程
|
1月前
|
存储 自然语言处理 编译器
C语言编译和链接
C语言编译和链接
C语言编译和链接
|
1月前
|
自然语言处理 编译器 Linux
C语言中抽象的编译和链接原理
C语言中抽象的编译和链接原理
20 1
|
1月前
|
存储 文件存储 C语言
深入C语言:文件操作实现局外影响程序
深入C语言:文件操作实现局外影响程序
|
1月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
34 3
|
C语言 网络协议
C语言及程序设计进阶例程-8 预处理之宏定义
贺老师教学链接  C语言及程序设计进阶 本课讲解 宏定义 #include &lt;stdio.h&gt; #define PI 3.1415926 int main ( ) { float r,l,s,sq,vq; printf("please enter r:"); scanf("%f", &amp;r); l=2 * PI *r; s=r * r * PI;
1007 0
|
C语言
C语言预处理之二-----宏定义那点事儿
1、关于宏的副作用,请看下面代码:   #include stdio.h> #define GOODDEF (input+3) #define POORDEF input+3   //这里是宏的副作用最经典的例子,不穿裤子!!!如果你这样用,下面你就知错!! ...
995 0
|
11天前
|
C语言
c语言调用的函数的声明
被调用的函数的声明: 一个函数调用另一个函数需具备的条件: 首先被调用的函数必须是已经存在的函数,即头文件中存在或已经定义过; 如果使用库函数,一般应该在本文件开头用#include命令将调用有关库函数时在所需要用到的信息“包含”到本文件中。.h文件是头文件所用的后缀。 如果使用用户自己定义的函数,而且该函数与使用它的函数在同一个文件中,一般还应该在主调函数中对被调用的函数做声明。 如果被调用的函数定义出现在主调函数之前可以不必声明。 如果已在所有函数定义之前,在函数的外部已做了函数声明,则在各个主调函数中不必多所调用的函数在做声明
27 6
|
1月前
|
存储 缓存 C语言
【c语言】简单的算术操作符、输入输出函数
本文介绍了C语言中的算术操作符、赋值操作符、单目操作符以及输入输出函数 `printf` 和 `scanf` 的基本用法。算术操作符包括加、减、乘、除和求余,其中除法和求余运算有特殊规则。赋值操作符用于给变量赋值,并支持复合赋值。单目操作符包括自增自减、正负号和强制类型转换。输入输出函数 `printf` 和 `scanf` 用于格式化输入和输出,支持多种占位符和格式控制。通过示例代码详细解释了这些操作符和函数的使用方法。
36 10
|
25天前
|
存储 算法 程序员
C语言:库函数
C语言的库函数是预定义的函数,用于执行常见的编程任务,如输入输出、字符串处理、数学运算等。使用库函数可以简化编程工作,提高开发效率。C标准库提供了丰富的函数,满足各种需求。