c语言执行流程
- 编译:形成目标代码(.obj),目标代码是在目标机器上运行的代码
- 连接:将目标代码与c函数库相连接,并将源程序所用的库代码与目标代码合并,并形成最终可执行的二进制机器代码(程序)。
- 执行:在待定的机器环境下运行c程序
预编译(预处理),为编译做准备工作,完成代码文本的替换工作
C:\Program Files (x86)\Microsoft Visual Studioxx\VC\include
C:\Program Files (x86)\Microsoft Visual Studioxx\VC\crt\src
头文件告诉编译器有什么样的函数,连接器负责找到这个函数的实现。
#ifndef #define #endif
防止头文件被重复引用
头文件被重复引用引起的后果:有些头文件重复引用只是增加了编译工作的工作量,不会引起太大的问题,仅仅是编译效率低一些,但是对于大工程而言编译效率低下那将是一件多么痛苦的事情。
有些头文件重复包含,会引起错误,比如在头文件中定义了全局变量(虽然这种方式不被推荐,但确实是C规范允许的)这种会引起重复定义。
test.h
#ifndef TESTH //防止test.h被重复引用
#define TESTH//一般是文件名的大写
...
#endif //文件末尾
也可以这样:
#pragma once //这句话作用同上,该头文件只被包含一次,让编译器自定义处理好循环包含问题
#include "A.h"
void printfTest();
define 宏定义/宏替换/预编译指令
- 定义标识
#ifdef __cplusplus 标识c++语法
- 防止文件重复引入
- 定义常数(便于修改与阅读)
#define MAX 100;
void main(){
int i = 90;
if(i < MAX){
printf("low max");
}
getchar();
}
- 定义“宏函数”
void com_jni_eat(){
printf("eat");
}
void com_jni_run(){
printf("run");
}
//NAME是参数
#define jni(NAME) com_jni_##NAME();
//webrtc JNI函数名称很长,也是JOW宏函数缩短函数名称
void main(){
jni(eat);//替换 com_jni_eat();
jni(run);//相当于com_jni_run();
getchar();
}
demo
//__VA_ARGS__可变参数
#define LOG(FORMAT,...)printf(##FORMAT, __VA_ARGS__);
#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", "num:", 123);
//相当于:printf("INFO:");printf("%s%d", "num:", 123);
getchar();
}
//__VA_ARGS__可变参数
#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", "num:", 123);
getchar();
}