目录:
一、宏定义
1 宏是常用的预处理功能之一,是在编译之前进行宏替换,即将宏名替换成所定义的宏体。
2 优点:可以使代码更简单,更容易,避免大量使用。
3 宏定义
定义在函数外面;
格式:#define PI 3.14
PI为宏的文件内容
在编译前将PI的内容替换成3.14
4 宏与全局变量的区别
宏相当于字符串的替换操作,内存中不存在
全局变量在内存中是存在的。
相同点:通常定义一个全局变量加上const修饰符,全局变量的值是不可以修改的。
5 宏函数
#define MianJi(r) PI*r*r
宏函数只是文本,只是相当于做了内容替换的操作,注意参数是没有数据类型
6 在声明数组时也可以使用宏
#define SIZE 10
int array[SIZE];
作业:
1)使用宏来求两个数的和、积
2)使用宏将小写字母转换成大写字母
3)使用宏求两个数的最大值
1 #include <stdio.h> 2 3 //在编译前操作,在函数外定义宏,纯的替换操作,把宏后面的值或表达式替换使用的那个位置。gcc -E main.c查看 4 #define PI 3.14 5 #define MianJi(r1) PI*r1*r1 6 #define He(x,y) x+y 7 #define Ji(x,y) ((x)*(y)) 8 #define SIZE 10 9 /* 10 作业: 11 1)使用宏来求两个数的和、积 12 2)使用宏将小写字母转换成大写字母 13 3)使用宏求两个数的最大值 14 */ 15 #define He(x,y) x+y 16 #define Ji(x,y) ((x)*(y)) 17 #define Swap(x) x-('a'-'A') 18 #define Max(x,y) x>y?x:y 19 20 int main(int argc, const char * argv[]) 21 { 22 int array[SIZE]; 23 float pi = 3.14; 24 float r = 2.0f; 25 printf("pi:%f ",PI); 26 printf("area:%f ",MianJi(r));//这里是在编译前替换操作 27 int i = 10; 28 int j = 20; 29 printf("he:%d ",He(i, j)); 30 printf("ji:%d ",Ji(i, j)); 31 printf("ji(1+2,3+4):%d ",21 / Ji(1+2, 3+4));//1+2*3+4 32 33 34 int i = 2,j = 3; 35 printf("he:%d ",He(i, j)); 36 printf("ji:%d ",Ji(i, j)); 37 printf("a:%c ",Swap('c')); 38 printf("i和j的最大值:%d ",Max(i,j)); 39 return 0; 40 }
二、#x,##x使用和预定义宏
1 #x 代表把x的内容转换为字符串
#define STR(x) #x
printf("%s ",STR(10));
输出结果:10(此时是字符串10)
2 ##x 代表将标识的内容与其他内容拼接在一起成为新的标识
定义:
#define QuanJu(x) g_##x //把x自动加上前缀g_(表示全局变量)
int QuanJu(i) = 20;//相当于int g_i = 20;
使用:
printf("g_i:%d ",g_i);
printf("g_i:%d ",QuanJu(i));
1 #include <stdio.h> 2 #define PI 3.14 3 #define CHAR "hello"//字符串就加上双引号 4 #define A -a 5 6 #define MIANJI(r) PI*r*r//宏可以嵌套,可以使用已经定义的宏 7 #define F1(x,y) printf("max:%d ",x>y?x:y); 8 9 #define STR(x) #x //把x转换为字符串 10 #define QUANJU(x) g_##x //把x自动加上前缀g_(表示全局变量) 11 //int g_i = 20; 12 int QUANJU(i) = 20;//相当于int g_i = 20; 13 int main(int argc, const char * argv[]) 14 { 15 int i = 10; 16 //printf("%s ",STR(10)); 17 printf("i:%d ",i); 18 printf("g_i:%d ",g_i); 19 printf("pi:%f ",PI); 20 //#undef PI//宏结束,只是PI宏名结束 21 //printf("pi:%f ",PI);//PI的值在这就不能用了会报错 22 printf("g_i:%d ",QUANJU(i)); 23 printf("mianji:%f ",MIANJI(i)); 24 printf("CHAR:%s ",CHAR);//加了双引号的宏名不予替换 25 26 int a = 1; 27 printf("%d ",-A);//printf("%d ",- -a);宏替换时会隐含一空格符 28 #define N 5//宏可以定义在任何位置 29 #undef N 30 #define N 8//要重新定义该宏,必须先取消宏定义 31 #define M N+3 32 printf("M:%d ",M);//11 33 34 F1(8, 3); 35 return 0; 36 }
3 C语言内部预定义的宏
__LINE__当前行号(__两个下划线)
__FILE__当前的文件名
__DATE__当前日期
__TIME__当前时间
__STDC__是否是C语言的标准返回值为0或1
__STDC__?"符合":"不符合";
printf("行号:%d ",__LINE__);
printf("当前文件名:%s ",__FILE__);
printf("当前日期:%s ",__DATE__);
printf("当前时间:%s ",__TIME__);
printf("是否是C 语言标准:%s ",__STDC__?"是":"不是");
三、宏的高级使用(条件编译)
1 在代码中设置编译条件,根据编译条件进行代码的编译并运行。(跨平台)
2 在编译文件的时候传入一个参数,根据参数进行对代码有选择的编译。
命令行传参:gcc -DZHAOBENSHAN 高级宏使用.c
ZHAOBENSHAN是参数
.c中使用:
1 #include <stdio.h> 2 #define ZHAOBENSHAN 1 3 int main() 4 { 5 int i = 0; 6 printf("输入菜单号: "); 7 scanf("%d",&i); 8 #ifndef ZHAOBENSHAN //编译条件,ifndef如果没有 9 if (i == 1) { 10 printf("这个菜有 "); 11 }else{ 12 printf("这个菜没有 "); 13 } 14 #else 15 if (i == 1) { 16 printf("这个菜没有 "); 17 }else{ 18 printf("这个菜真没有 "); 19 } 20 #endif 21 return 0; 22 }
3 条件指令
#if如果
#ifdef 如果定义
#ifndef 如果没定义
#elif 如果(else if)
#else 否则
#endif 结束标识
#undef 取消宏
#define定义宏
4 编译方式
根据参数编译:gcc -DXXX main.c
根据宏值(参数):#define ZHAOBENSHAN 1
根据宏"值(逻辑)"进行编译:
#if ZHAOBENSHAN == 1
练习:根据设备来生成不同的程序
iphone1~4
iphone 4s
iphone 5~5s
iphone ipad
iphone mini
1 #include <stdio.h> 2 #define DEVICE 2 3 int main() 4 { 5 #if DEVICE == 0 6 printf("ipone1and4 "); 7 #elif DEVICE == 1 8 printf("iphone4s "); 9 #elif DEVICE == 2 10 printf("iphone5~5s "); 11 #elif DEVICE == 3 12 printf("iphoneipad "); 13 #elif DEVICE == 4 14 printf("iphonemini "); 15 #else 16 printf("ipone1and4 "); 17 #endif 18 return 0; 19 }