在代码执行前,会将源文件转化为可执行的机器指令
2、预处理详解 2.1 预定义符号预定义符号是语言内置的符号可以直接使用
__FILE__ //进行编译的源文件 __LINE__ //文件的当前行 __DATE__ //文件被编译的日期 __TIME__ //文件被编译的时间 __STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义
一般在写日志的时候会用到
2.2 #define 2.2.1 #和###:把一个宏参数变成对应的字符串
#include#define PRINT(n) printf("the value of "#n" is %dn",n ) int main() { int a = 10; PRINT(a); int b = 20; PRINT(b); return 0; }
##: 把位于它两端的符号合成一个符号
#include#define CAT(s,num) s##num int main() { int sum5 = 2; int b = CAT(sum, 5);//sum5 printf("%d", b); return 0; }
2.2.2 宏与函数
1、代码长度
宏:每次使用时,宏代码都会被插入到程序中。除了非常小的宏之外,程序的长度会大幅度增长
函数:函数的代码只出现与一个地方;每次使用这个函数时调用的是同一份代码
2.执行速度:
宏:更快
函数:函数的调用和返回需要额外开销,相对来说会慢一点
3.操作符优先级
宏:宏使用的时候是直接替换,如果没加括号的话,可能会因为优先级问题参数预料之外的结果
函数:函数在传参前先求值
4.带有副作用的参数
宏:参数可能被替换到宏体的多个位置
比如:
#include#define MAX(x,y) (x)>(y)?(x):(y) int main() { int a = 2; int b = 3; int m = MAX(a++, b++); return 0; }
a、b会进行多次自增操作
函数:只在传参的时候计算一次
5.参数类型
宏:宏的参数与类型无关,只要对参数的操作是合法的,它就可以使用于任何参数类型
#include#define MALLOC(type,size) (type*)malloc(sizeof(type)*size); int main() { int* p = MALLOC(int, 5); return 0; }
函数:传参的参数需要与定义是的参数对应
6.调试
宏:宏是预处理阶段的操作,不便于调试
函数:可以逐句调试
7.递归
宏:不能递归
函数:可以递归
2.3 #undefine移除一个宏定义
2.4 命令行定义许多C 的编译器提供了一种能力,允许在命令行中定义符号。用于启动编译过程。
#includeint main() { int array [ARRAY_SIZE]; int i = 0; for(i = 0; i< ARRAY_SIZE; i ++) { array[i] = i; } for(i = 0; i< ARRAY_SIZE; i ++) { printf("%d " ,array[i]); } printf("n" ); return 0; }
编译指令
//linux 环境演示 gcc -D ARRAY_SIZE=10 programe.c2.5 条件编译
一些调试性的代码,删除可惜,保留又碍事,所以我们可以选择性的编译。
#include#define __DEBUG__ int main() { int i = 0; int arr[10] = {0}; for(i=0; i<10; i++) { arr[i] = i; #ifdef __DEBUG__ printf("%dn", arr[i]);//为了观察数组是否赋值成功。 #endif //__DEBUG__ } return 0; }
多分支条件编译
#include#define M 150 int main() { #if M<100 printf("lessn"); #elif M==100 printf("==n"); #elif M>100 printf("moren"); #else printf("hehen"); #endif return 0; }
判断是否被定义
#define _CRT_SECURE_NO_WARNINGS #include#define M 150 int main() { #if defined(M)//如果定义了为真 printf("hehen"); #endif #ifdef m//如果定义了为真 printf("hahan"); #endif #if !defined(m)//如果没定义为真 printf("wangwang~n"); #endif #ifndef M//如果没定义为真 printf("miaomiao~n"); #endif }
嵌套指令
#if defined(OS_UNIX) #ifdef OPTION1 unix_version_option1(); #endif #ifdef OPTION2 unix_version_option2(); #endif #elif defined(OS_MSDOS) #ifdef OPTION2 msdos_version_option2(); #endif #endif2.6 文件包含
" ":先在源文件所在目录下查找,如果该头文件未找到,编译器就会在标准位置查找头文件,如果找不到就报错
<>:直接在标准路径下查找,如果找不到就报错
解决当多次包含同一个头文件时只包含一次
1.
#ifndef __TEST_H__ #define __TEST_H__ //头文件的内容 #endif
2.
#pragma once



