程序的编译

mac2026-09-04  1

程序的翻译和执行环境

翻译环境:源代码被转换为可执行的机器指令;执行环境:实际执行代码。 文件后缀:.c —>.obj —>.exe C程序由源程序变为可执行文件的四个阶段是:

预处理:展开头文件,宏替换,删除注释,条件编译;编译:编译器对经过预处理后的程序进行编译,检查语法,生成汇编代码;汇编:转换为二进制代码,并生成目标文件;链接:链接器对目标文件和用到的函数库进行链接,合成可执行程序,寻找对应声名生成可执行文件。

预处理:

extern,static
extern:声明外部符号(函数或变量)。可置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量或函数时,在其它模块中寻找其定义。static:修饰局部变量,提升局部变量的生存周期; 修饰全局变量,作用域被限制在当前源文件; 修饰函数,不能被其他源文件内调用,被限制在当前源文件当中。

注意: 当使用static在头文件定义一个变量或函数,在源文件使用extern时将会报错,二者冲突

#define
预处理指令,在预处理时进行简单而机械的字符串替换,不作正确性检查,只有在编译已被展开的源程序时才会发现可能的错误并报错,没有作用域限制。#define定义宏:允许把参数替换到文本中。#undef NAME:如果现存的一个名字需要被重新定义,那么它的旧名字首先要被移除。 //define定义一个宏:(注意加括号) #define ADD(x,y) x+y;//注意 :2*ADD(x,y)=2*x+y #define MUL(x,y) x*y; //注意 :2*ADD(x+z,y)=2*x+z+y #define替换规则:

①使用 # ,把一个宏参数变成对应的字符串。

#include<stdio.h> #define PRINT(FORMAT, VALUE) printf("the value of "#VALUE" is "FORMAT"\n", VALUE); int main() { int i=10; PRINT("%d",i+3); //the value of i+3 is 13 return 0; }

② ## 可以把位于它两边的符号合成一个符号;它允许宏定义从分离的文本片段创建标识符。

#include<stdio.h> #define ADD_TO_SUM(num, value) sum##num += value int main() { int sum1, sum2, sum3 = 1; ADD_TO_SUM(3, 10); //给sum3增加10. getchar(); return 0; } 宏函数与函数: #define MALLOC(num,type) (type*)malloc(num*sizeof(type)) MALLOC(10,int); //类型作为参数 //预处理器替换之后: (int*)malloc(10*sizeof(int));

宏可以增强代码可维护性,其规模与速度优于函数;宏的参数可以出现类型,但是函数做不到 注意: ①使用宏会将一份宏定义的代码插入程序。除非宏比较短,否则可能会增加程序的长度; ②宏是不可调试的。宏不能递归; ③宏由于类型无关,也就不够严谨。 ④宏可能会带来运算符优先级的问题,导致程容易出现错。

define无法正确处理指针 typedef: 关键字,在编译时处理,有类型检查功能,没有作用域限制。 ①为基本数据类型定义新的类型名 typedef unsigned int COUNT; ②为数组定义简洁的类型名称 typedef int ARR[100]; ARR arr [ ]= { } ; ③为指针定义简洁的名称 typedef char* PCH; PCH pa; #define INTPTR1 int* typedef int* INTPTR2; INTPTR1 p1, p2; INTPTR2 p3, p4; 含义分别为:声明一个指针变量p1和一个整型变量p2 声明两个指针变量p3、p4,
头文件

注意: ①自定义头文件用#include" ",库文件用#include< >可以提高效率; ②#pragma once可以防止头文件重复引用;条件编译还可以防止嵌套文件中头文件重复引用。

条件编译

编译条件 #if 常量表达式 , 多个分支的条件编译 //... , #if 常量表达式 #endif , //... //常量表达式由预处理器求值。如: , #elif 常量表达式 #define __DEBUG__1 , //... #if __DEBUG__ , #else //.. , //... #endif #endif 判断是否被定义 #if defined(symbol) #ifdef symbol

eg.

#include<stdio.h> #define __ DEBUG__ 1 int main() { int i = 0; int arr[10] = { 0 }; for (i = 0; i < 10; i++) { arr[i] = i; #ifdef __ DEBUG__ printf("%-2d", arr[i]); //调试性的代码,为了观察数组是否赋值成功。 #endif //__ DEBUG__ } return 0; }
关键字:

①register:建议将定义放入寄存器。 ②auto:声明变量的生存周期为自动。 ③const:必须在定义时初始化;不可以给常量赋值。

最新回复(0)