C语言的执行流程
1 编译
形成目标代码(.obj)
void main(){
myprintf("疾风剑豪");
getchar();
}
因为没有myprintf();这个方法,所以会报错。
2 连接
将目标与C函数库连接合并,形成最终的可执行文件。
可以看到上面的图片中,error LinK2091.无法解析的外部符号。说明已经生成了.obj文件,但是没有找到此方法。也就是说在连接的过程出现了错误。
3 预编译
完成代码的替换工作
添加新建项为text.txt
并在此文件中添加这一行:
printf("%s","Just do it!");
在c文件中引入此text.txt
void main(){
#include "text.txt"
getchar();
}
打印结果
Just do it!
源码位置
转到声明看源码
define指令
1.定义标识
标识支持c++语法
ifdef __cplusplus
2 定义常数
#define MAX 100
void main(){
int i = 50;
if (i<MAX){
printf("%d",i);
}
getchar();
}
和变量的区别:变量有类型 此处没有类型。相当于宏替换。
宏定义 可以叫宏替换又可以叫预编译指令。
输出结果
50
3 定义宏函数
void com_alibaba_jni_read(){
printf("read\n");
}
void com_alibaba_jni_wirte(){
printf("write\n");
}
#define jni(NAME) com_alibaba_jni_##NAME(); //NAME是参数
void main(){
jni(read); //会替换成com_alibaba_jni_read()
getchar();
}
打印结果
read
带参宏函数
#define LOG(FORMAT,...) printf(##FORMAT,__VA_ARGS__);//__VA_ARGS__表示可变参数
void main(){
LOG("%s%d","年龄:",18);
getchar();
}
打印结果
年龄:18
打印日志
#define LOG_I(FORMAT,...) printf("INFO:");printf(##FORMAT,__VA_ARGS__);
#define LOG_E(FORMAT,...) printf("ERROR:");printf(##FORMAT,__VA_ARGS__);
void main(){
LOG_I("%s%d\n", "年龄:", 18);
LOG_E("%s%d\n", "年龄:", 18);
getchar();
}
INFO:年龄:18
ERROR:年龄:18
升级日志版本
#define LOG(LEVEL,FORMAT,...)printf(LEVEL);printf(##FORMAT,__VA_ARGS__);
#define LOG_I(FORMAT,...) LOG("INFO:",FORMAT,__VA_ARGS__);
#define LOG_E(FORMAT,...) LOG("ERROR:",FORMAT,__VA_ARGS__);;
void main(){
LOG_I("%s%d\n", "年龄:", 18);
LOG_E("%s%d\n", "年龄:", 18);
getchar();
}
4 防止文件重复引入
在B.h中
#include "A.h"
void printB();
在A.h中
#include"B.h"
void printA();
调用printA()方法
void printA(){
printf("金刚葫芦娃");
}
void main(){
printA();
getchar();
}
执行后会报错:
添加宏定义后
A.h
//如果没有定义AH,才回去定义AH
#ifndef AH
#define AH
#include"B.h"
void printA();
#endif
打印结果
金刚葫芦娃
在主函数所在的.c文件中,引入了A.h。在A.h中引入了B.h。但是B.h中又引入了A.h。所以添加宏定义的意义就是在A.h中,如果没有定义了AH才会去定义AH。这样不会重复引入。
同样也可以这样:
#pragma once
void printA();