柳州网站建设柳州,在青岛做阿里巴巴网站找谁,wordpress插件 投票,杭州钱塘区//extern int ADD(int x, int y);//声明引用外部文件 //c语言预处理 // 文本文件 翻译链接 二进制文件 运行 //test.cpp————————》test.exe————————》 // 编译器 翻译环境 链接器 执行环境 // test.obj#xff08;目标文件//声明引用外部文件 //c语言预处理 // 文本文件 翻译链接 二进制文件 运行 //test.cpp————————》test.exe————————》 // 编译器 翻译环境 链接器 执行环境 // test.obj目标文件 // //linux系统翻译器 // gcc -E // 预编译test.i把头文件放进文件里 // 删除注释空格替换 // #define 定义的进行替换 // gcc -S // 编译test.s把c代码翻译成汇编代码 // 语法分析词法分析语义分析符号汇总 // gcc -c //汇编test.o:形成符号表 // 把汇编代码转换成二进制代码指令 // obj文件目标文件 二进制文件 // // 链接器 // 多个 .obj 文件通过链接器链接 // 合并段表符号表固定格式分段 elf格式 多个程序分段形成符号表 // 符号表的合并和重定位 多个符号表合并 // 符号重定位把一个文件内的声明的符号地址改成 // 另一个文件的实际有效地址这样就链接起来了 // // // 运行环境 // 程序必须载入内存中有操作系统就由操作系统完成 // 独立环境中程序需要手动安排或可执行代码置入只读内存 // 程序开始执行调用main函数 // 开始执行代码使用一个运行时堆栈stack存储函数局部变量和返回地址 // 同时可以使用静态static内存中的变量并在执行过程中一直保留他们的值 // 终止程序正常终止或意外终止 // // 预处理详解 // 预定义符号 __FILE__ 进行编译的源文件——当前文件的路径 // __LINE__ 文件当前的行号——当前代码的行号 // __DATE__ 文件被编译的日期 // __TIME__ 文件被编译的实际 // __STDC__ 如果编译器遵循ANSI C 值为1 否则未定义 // ... // 预处理指令 // #define// 定义的静态值可在程序中完成替换不能在内容后面加 // #include // #pragma pack4 设置默认对齐数 // #pragma pack // #if // #endif // #error // #line // #开头定义的指令 //
//#define 定义标示符号 #define name stuff name名字 stuff内容 //#define MAX 100 //#define STR HEHE //#define reg register//存储器关键字 //#define do_forever for(::)//用形象的符号替换一种函数实现 //#define CASE break:case//在case 语句后面自动把break写上 //#define DEBUG_PRINT printf(%s\n, __TIME__)//如果内容过长每行加上 \ (续航符) //#define定义宏 //#define机制包括了一个规定允许把参数替换到文本中这种实现通常称为宏macro // 定义宏define macro // #define name(parament-list) stuff // parament-list是参数列表用逗号隔开 // 参数可以出现在suff里面注左括号和name紧贴一起 // stuff内容根据符号优先级用进行分装 // // #define 替换规则 // 1;在调用宏时首先对参数进行检查看看是否包含任何由#define定义的符号 // 发现有就进行替换。 // 2替换文本随后被插入程序中的原文本位置对于宏参数名都会被他们的值替换 // 3最后再次扫描是否有#define定义的符号发现有就再次替换 // 注意 // 1宏参数和#define可以出去其他#define定义的符号但是宏不能递归 // 2预处理器搜索#define定义的符号的时候字符串常量的内容并不被搜索 // // // #和## // # 字符串常量化运算符 把宏参数插入到字符串中 // ## 合并粘贴运算符可以把它两边的符号合成一个符号 // 允许宏定义从分离的文本片段创建标识符 // // // 带有副作用的宏参数 // // 函数有参数类型宏没有参数类型 // // #undef 取消宏定义 // // // 命令行定义 // 在程序执行时许多编译器提供了允许在命令行中定义符号的功能给程序中的变量赋值 // 有的命令行有参数 有的没有 // // // 条件编译指令 // 选择性的对语句进行编译或者放弃有条件的编译指令 // 1, #if 常量表达式 // #endif ——结束 // // 2#if 常量表达式 ---如果 // #elif 常量表达式 ——或如果 // #else 常量表达式 ——否则 // #endif ——结束 // // 3判断是否被定义 // #if definedsymbol--如果定义了symbol // #ifdef symbol 和上一句等价 // // #if !defined(symbol) --如果没有定义symbol // #ifndef symbol 和上一句等价 // // #endif ---结束 // 4嵌套指令 // #if definedstr1//如果定义了str1 // #ifdef ptr1//如果定义了ptr1 // r1//执行r1 // #endif ---内结束 // #ifdef ptr2//如果定义了ptr2 // r2执行r2 // #endif ---内结束 // #elif definedstr2//或如果定义了str2 // #ifdef ptr2//如果定义了ptr2 // r2//执行r2 // #endif ---内结束 // #endif ---外结束 // // // 文件包含 #include // 使另一个文件被编译拷贝到当前文件里 // 库函数头文件 在标准路径安装路径去查找 // 自编本地头文件 // 查找策略先查源文件所在目录下找未发现就在标准位置安装路径查找最后未发现提示编译错误 // // // 嵌套文件重复包含头文件解决方案 // 方案1, #ifndef __TEST_H__ // #define __TEST_H__ // (头文件内容) // #endif // 方案2,#pragma once //
//含参数的宏定义 //#define MAX 100 //#define SQUARE(X) ((X)*(X))//stuff内容根据符号优先级用进行分装
//#把宏定义参数插入字符串里 //void print(int x) //{ // printf(the value of x is %d\n, x);//x是固定的不能转换a或者b //} //#define PRINT(X) printf(the value of #X is %d\n, X)//多个字符串放在一起会自动连在一起
//##字符串粘连 //#define CAT(X,Y) X##Y//把X的内容和Y的内容连在一起
//宏定义参数中存在 -- 等副作用参数 //#define MAX(X,Y) ((X)(Y)?(X):(Y)) //给X,Y 的变量是直接整体替换的不会进行计算 //#define 优势预处理完成替换直接到判断语句没有函数调用和返回的开销更省时间 // 宏没有参数类型(通用)还可以传类型参数 // 劣势宏会直接将代码插入到程序中如果宏很长就会增加程序的长度 // 宏不能调试没参数类型不严谨 // 宏会有运算符优先级带来的副作用 //函数会有调用和返回的开销且有函数参数类型要求
//#undef MAX 取消宏定义
//int Max(int x, int y) //{ // return (x y ? x : y); //}
//#define DEBUG int main() { int arr[10] { 0 }; int i 0; int a 10; int b 20; FILE* pf fopen(log.txt, w); for (i 0; i 10; i) { arr[i] i; fprintf(pf, file:%s line:%d date:%s time:%s i %d\n, __FILE__,__LINE__,__DATE__,__TIME__,i); } fclose(pf); pf NULL; for (i 0; i 10; i) { printf(%d , arr[i]); } int c ADD(a, b); printf(%d, c); //printf(%s\n, __FILE__);//当前文件的路径 //printf(%d\n, __LINE__);//当前代码的行号 //printf(%s\n, __DATE__); //printf(%s\n, __TIME__); //printf(%d\n, __STDC__);VS是未定义这个的 //宏定义参数替换 int ret SQUARE(5);//ret 25 ret SQUARE(5 1);//ret 11宏是直接用51替换X使用得到11 //可以在宏定义用X进行分开成单独个体 ret SQUARE(MAX); printf(MAX %d\n, MAX);//MAX %d\n中的字符串MAX不会被#define检测替换 //#把宏参数插入到字符串中 int a 10; int b 20; print(a); print(b); PRINT(a); printf(the value of #X is %d\n, X) PRINT(b); //##把字符串粘连在一起 //int abcd10 2019; //printf(%d\n, CAT(abcd, 10));//abcd##10 abcd10 //带有副作用的宏参数 int a 10; int b 11; int max MAX(a, b);//改变了a和b的值 max ((a)(b)?(a):(b)) // 这个代码执行先比较a和b b大然后ab再把b的赋值给max最后b printf(%d\n, max);//12 printf(%d\n, a);//11 printf(%d\n, b);//13 //函数和宏比较 int a 10; int b 11; float c 3.0f; float d 3.1f; int max MAX(a, b); printf(%d\n, max); max Max(a, b); printf(%d\n, max); float max1 MAX(c, d); //条件编译 int arr[10] { 1,2,3,4,5,6,7,8,9,10 }; int i 0; for (i 0; i 10; i) { arr[i] 0; #ifdef DEBUG//如果DEBUG定义了就执行printf #if defined DEBUG//如果DEBUG定义了就执行printf #ifndef DEBUG//如果没有定义DEBUG #if !defined DEBUG printf(%d , arr[i]); #endif // DEBUG 结束条件编译 }
#if 10 printf(1\n); #elif 22 printf(2\n); #else printf(3)
#endif return 0; }