1. 区分预处理代码
在C语言程序里,出现的#开头的代码段都属于预处理。
预处理:是在程序编译阶段就执行的代码段。
比如: 包含头文件的的代码
#include <stdio.h> #include <stdlib.h> #include <string.h>
下面列出C语言里常用的预处理代码段:
2. #define 预处理指令: 宏定义和宏替换
#include <stdio.h> //C预处理器只不过是一个文本替换工具而已,它们会指示编译器在实际编译之前完成所需的预处理 #define STR_DATA "123456" //宏替换用法 //替换的宏一般都是大写 //STR_DATA 称为替换标识符 #define INT_DATA 6666 //带参宏 #define PRINT_DATA(x) if(x){printf("为真.\n");} \ else {printf("为假.\n");} int main(int argc,char **argv) { printf("%s\n",STR_DATA); printf("%d\n",INT_DATA); PRINT_DATA(1); PRINT_DATA(0); return 0; }
2.2 宏替换的高级用法:#(字符串常量替换符号)
#include <stdio.h> //字符串常量替换 #define PRINT_DATA1(a,b) printf(#a"456"#b"\n"); #define PRINT_DATA2(a,b) printf("%s,%s\n",#a,#b); int main(int argc,char **argv) { PRINT_DATA1(123,"789"); PRINT_DATA2(123,"789"); return 0; }
2.3 宏替换的高级用法:##(数据拼接符号)
#include <stdio.h> //数据拼接符号 #define PRINT_DATA1(a,b) printf("%d\n",a##b); int main(int argc,char **argv) { PRINT_DATA1(1,4); PRINT_DATA1(100,400); return 0; } #include <stdio.h> //数据拼接符号 #define PRINT_DATA(a) a##a int main(int argc,char **argv) { printf("%d\n",PRINT_DATA(6)); return 0; }
2.4 宏定义用法
#include <stdio.h> //#define DEF_A #ifdef DEF_A #define STR_DATA "123" #else #define STR_DATA "456" #endif int main(int argc,char **argv) { printf("STR_DATA=%s\n",STR_DATA); return 0; }
3. #ifndef、#ifdef 语句
#include <stdio.h> #define AA #ifndef AA #error "你没有定义AA标识符" #endif #ifdef A1 #define STR_DATA "123" #elif 12==12 #define STR_DATA "456" #elif 34==45 #define STR_DATA "789" #else #define STR_DATA "ABC" #endif int main(int argc,char **argv) { printf("%s\n",STR_DATA); return 0; }
4. defined 预编译语句
#if 0 #include <stdio.h> //常规的常量替换 #define A1 "1234" #define A2 6666 /*带参宏*/ #define MAX(a,b) ((a)>(b)?(a):(b)) #define A3(a) if(a){printf("为真.\n");} \ else {printf("为假.\n");} //替换字符串常量 # #define PRINTF_1(a) printf("%s\n",#a); #define PRINTF_2(a,b) printf(#a"456"#b"\n"); //"123456789" //数据拼接符号 ## #define PRINTF_3(a,b) printf("%d\n",a##b); //1234 int main(int argc,char **argv) { printf("%s\n",A1); printf("%d\n",A2); printf("MAX=%d\n",MAX(12,77)); A3(1); PRINTF_1(1234); PRINTF_2(123,789); PRINTF_3(12,34); return 0; } #endif #if 0 #include <stdio.h> /* #if 0 //为真的时候执行 int data=123; #else //为假的时候执行 int data=666; #endif */ #define B1 //定义一个标识符 B1 #undef B1 //取消标识符B1定义 #ifdef B1 //为真的时候执行 int data=123; #else //为假的时候执行 int data=666; #endif int main(int argc,char *argv[]) { printf("data=%d\n",data); return 0; } #endif #include <stdio.h> #define A3 #if !defined(A1) && !defined(A2) && !defined(A3) #error "没有定义 A1或者A2或者A3" #endif int main(int argc,char *argv[]) { return 0; }
5. #include 预编译语句
#include <stdio.h> #include "./include_file/app.h" //#include "/mnt/hgfs/linux-share-dir/linux_c/include_file/app.h" /* #include 语法: <> 和 "" #include <stdio.h> 告诉编译器,从系统的目录下寻找stdio.h 这个文件。 #include "stdio.h" 告诉编译器,从当前用户目录下寻找stdio.h 这个文件,如果找不到再从系统的目录下寻找。 #include "./include_file/app.h" 告诉编译器,从./include_file目录下寻找头文件 #include "include_file/app.h" #include "/mnt/hgfs/linux-share-dir/linux_c/include_file/app.h" */ int main(int argc,char *argv[]) { printf("%s\n",A1); return 0; }
6. typedef 关键字
typedef 给类型取别名。
比如:
#include <stdio.h> void func1(void); void func2(void); #if 0 //宏替换 #define u8 unsigned char #define u16 unsigned short #define u32 unsigned int #endif #if 1 //声明一种新类型 typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; //声明新数据类型: 函数指针类型: 类型名称 func_p typedef void (*func_p)(void); //定义一个存放函数地址的数组 func_p func_addr[10]={func1,func2}; //声明新数据类型: 类型abc typedef char abc[10]; #endif int main(int argc,char **argv) { u8 a; abc a1,a2; //通过数组调用函数 func_addr[0](); func_addr[1](); printf("%d\n",sizeof(a1)); printf("%d\n",sizeof(a2)); return 0; } void func1(void) { printf("123\n"); } void func2(void) { printf("456\n"); }