c语言学习之基础知识点介绍(二十):预处理指令
一、预处理指令的介绍
预处理命令:在编译之前触发的一系列操作(命令)就叫预处理命令。
特点:以#开头,不要加分号。
#include:
文件包含指令
把指定文件的内容复制到相应的位置
#define:
#define 宏名 替换的值;
宏、宏定义或者还叫宏代换。
作用:就是在编译之前把所有用到这个宏的地方,替换成你指定的东西
规范:宏名大写,可以跟变量区分开来
之前学的宏:
INT32_MAX
INT32_MIN
宏不占据内存空间,只是帮你做简单的替换。
注意:
1.宏只是简单的替换,不参与编译,宏不会编译成指令集。
2.宏可以写在任意位置,但是一定要调用它之前。
3.宏可以嵌套,展开的时候依次展开。
4.宏只是简单的替换,如果替换的内容是表达式,它不会帮你先计算出结果,而是把整个表达式替换过去。
5.宏替换的作用域:默认是从声明的位置到文件的结束,可以用#undef 宏名 结束宏的作用。
6.双引号里面如果有遇到宏名,不会做替换,如果单引号里面写的是宏名也不会替换。
代码实例:
#include <stdio.h>
#define SUM 10 + NUM
#define NUM 10
#define MY_TEST int num = 30;
#define GET_SUM 10+30
#define HAHA GET_SUM*2
#define A 'a'
int main(int argc, const char * argv[]) {
printf("%d\n",TEST_NUM);
// char ch = 'A';
//
// printf("%c\n",ch);//A
// printf("NUM \n");//NUM
#undef NUM
/*
printf("%d\n",NUM);//编译的时候,把这句话换成了printf("%d\n",10);
int num = NUM + 30; //替换成了 int num = 10 + 30;
printf("num=%d\n",num);
*/
//int num = INT32_MAX; //编译的时候把它替换成了 int num = 2147483647;
// int num = SUM;
//
// printf("num=%d\n",num);
// MY_TEST
// printf("%d\n",num);
// printf("%d\n",GET_SUM);//40
// int res = GET_SUM * 2; // int res = 10+30*2;
// printf("%d\n",res);//
// printf("%d\n",HAHA);//先替换成(GET_SUM)*2 然后再替换成 (10+30)*2
return ;
}
二、预处理之#if-#elif -#else
/*
用的比较少
#if 宏的表达式 #elif 宏的表达式2 #else #endif 有选择的编译或者不编译某些代码 注意:#if这只能跟宏
一定要以#endif结尾 */ #include <stdio.h>
#define SCORE 65 int main(int argc, const char * argv[]) {
//以下永远只有一条语句参与编译
#if SCORE >= 90
printf("法拉利\n");
#elif SCORE >= 80
printf("奔驰\n");
#elif SCORE >= 70
printf("大众\n");
#elif SCORE >= 60
printf("拖拉机\n");
#else
printf("吊打\n");
#endif
return ;
}
三、预处理之#ifdefine
/* #ifdef:
#ifdef 宏名
代码段;
#endif 语义:如果定义了宏名,那么就编译代码段,否则不编译 #ifndef:
#ifndef 宏名
代码段;
#endif 语义:如果没有定义这个宏,那么就编译代码段,否则不编译 作用:1.防止重复导入 */ #include <stdio.h> #include "test.h" //#define TEST int main(int argc, const char * argv[]) { /*
#ifdef TEST printf("哈哈哈哈哈,我被定义了\n");
#endif
*/ #ifndef TEST printf("哈哈哈哈哈,我被定义了\n");
#endif return ;
}
四、有参数的宏
/*
#define 宏名 替换的值
有参数的宏:
#define 宏名(参数列表) 参数1+参数2
*/
#include <stdio.h>
#define MY_NUM(a) a
#define MY_SUM(a) a*2
#define MY_SUM2(a,b) a*b
int main(int argc, const char * argv[]) {
/*
int num = MY_NUM(30);
printf("num=%d\n",num);
int num2 = MY_SUM(20);
printf("num2=%d\n",num2);//40
printf("%d\n",MY_NUM(50));//50
printf("%d\n",MY_SUM(50));//100
int num3 = MY_SUM2(10, 20);
printf("num3=%d\n",num3);
*/
char ch2 = 'z';
char ch = MY_NUM(ch2);
printf("%c\n",ch);//z
return ;
}
五、条件编译的用处
/* 条件编译:
就是有选择的编译或者不编译某段代码 #if-#elif-#else-#endif #ifdef-#endif #ifndef-#endif 用来开发时的测试调试,能够改一个值就可以让这些输出的语句消失(不参与编译),就可以达到一次性把所有调试语句“删除”的目录 */ #include <stdio.h> //#define MY_DEBUG #ifndef MY_DEBUG #define LOG(a,...) #else #define LOG(a,...) printf(a, ##__VA_ARGS__); //就代表第二个参数是可变的,你可以传,也可以不传,传的话也可以传一个或者多个 #endif
int main(int argc, const char * argv[]) {
LOG("哈哈哈哈,测试1,a=%d b=%d\n",a,b);//第二个参数,只传了2个
LOG("哈哈哈,测试2\n"); //第二个参数,一个都没传 LOG("z=%d,x=%d,q=%d,v=%d\n",z,x,q,v);//第二个参数,传了4个
return ;
}
c语言学习之基础知识点介绍(二十):预处理指令的更多相关文章
- c语言学习之基础知识点介绍(十):数组
本节主要介绍数组. 一.数组 /* 数组:一个变量可以存n个变量. 语法:类型 数组名[长度(正整数)]; 例如:int score[5];//定义了一个int类型的数组,长度为5,可以保存5个数据. ...
- c语言学习之基础知识点介绍(十二):结构体的介绍
一.结构体的介绍 /* 语法: struct 结构体名{ 成员列表; }; 切记切记有分号! 说明:成员列表就是指你要保存哪些类型的数据. 注意:上面的语法只是定义一个新的类型,而这个类型叫做结构体类 ...
- c语言学习之基础知识点介绍(十四):指针的进阶
一.指针的加.减法运算 /* 1.加法运算 1).可以跟整数进行加法运算,得到的还是一个地址 公式: 地址 + 1 = 地址 + 1 * 类型所占的字节数 地址 + n = 地址 + n * 类型所占 ...
- c语言学习之基础知识点介绍(十五):函数的指针
一.函数的指针的介绍 /* 函数指针: 函数的指针,本质上一个指针 指向函数的指针,就是一个函数指针. 回忆:我们写的源代码编译成二进制的指令集,一串交给CPU执行的指令 先存在内存里面,然后CPU读 ...
- c语言学习之基础知识点介绍(十):内存空间模型、地址解释及指针变量
一.内存 /* 内存: 存在内存里的. 内存分了N多个小空间,每个小空间1个字节 每个小空间有它自己的地址.每个地址之间差1 int类型占用4个字节,等于占了4个空间(有4个地址),不需要记住4个地址 ...
- c语言学习之基础知识点介绍(十九):内存操作函数
一.malloc函数 /* 首先需要导入头文件 #include <stdlib.h> malloc void* malloc(n); n是字节大小 开辟堆空间,开辟的字节数以n为准 返回 ...
- c语言学习之基础知识点介绍(十八):几个修饰关键字和内存分区
一.几个修饰关键字 全局变量: 全局变量跟函数一样也分为声明和实现.如果是全局变量,实现在它调用之后,那么需要在调用之前进行声明.注意:全局变量的声明只能写在函数外,写在函数就不是全局变量了而是局部变 ...
- c语言学习之基础知识点介绍(十六):文件操作
一.文件的分类 1.文本文件:打开之后能看得懂的文件 2.二进制文件:打开之后看不懂,类似乱码之类的文件(视频,音频打开之后,能看.听,是应为电脑中装有播放器,播放器中含有解码器). 二.操作文件的步 ...
- c语言学习之基础知识点介绍(二):格式化控制符和变量的补充
上节简单介绍了c语言中的一些基础知识点,本节将对之前介绍的不够详细的知识点进行补充. 格式化控制符的消息介绍: %d的其他控制符: 1.%md:m代表这个整数位占用多少位,m是一个整数.实际数字不足的 ...
随机推荐
- 社区商业试玩O2O:良渚文化村新街坊牵手阿里巴巴
在电商时代,越来越多的人选择便捷的网上购物,使得实体商业受到了不小的冲击,各种大型的购物中心.购物广场已经不再那么人气十足,因此一些特色商业街区.社区商业频频出现,也不乏一些新玩儿法. 阿里巴巴(专题 ...
- asp.net的运行内幕
每当浏览器向IIS发送一个页面请求的时候,相应的网页就会被编译成DLL文件,然后由JIT来运行这个DLL文件,最后将运行结果发送给客户端.一旦网页发送了变化,下次再请求页面的话,网页又会被重新被编译成 ...
- linux统计文件夹某一些文件的大小总和
du -m smallgame_2006* | awk '{sum += $1}; END{print sum}' -m代表单位是MB, awk命令需要'',且命令需换行
- Laravel教程:laravel 4安装及入门
一.安装Composer首先你需要安装Composer,Composer是PHP依赖管理工具,Laravel框架就是使用 Composer 执行安装和依赖管理. 注:(1)若安装Composer出错, ...
- NTC(负温度)热敏电阻.阻值的计算方式
来源 :http://blog.csdn.net/blue0432/article/details/8690190 现在低成本测温方案中NTC热敏电阻用的比较多,一般采用查表的方法获取温度值,这就牵涉 ...
- zoj 2588 Burning Bridges【双连通分量求桥输出桥的编号】
Burning Bridges Time Limit: 5 Seconds Memory Limit: 32768 KB Ferry Kingdom is a nice little cou ...
- highcharts 柱形图 饼图 加URL或Click事件
我们在做图表的时候,有时候需要在单个数据上加链接或点击事件,是在plotOptions里的events里设置的 plotOptions: { pie: { cursor: 'pointer', eve ...
- vmwear 及docker
1.安装vmwear,开启cpu虚拟化 2.http://jingyan.baidu.com/article/eae0782787b4c01fec548535.html 3.docker
- Yii2 多域名跨域同步登录退出
在平台开发过程中,项目分为前台(frontend)www.xxx.com和后台(backend) yun.xxx.com两部分,绑定两个域名, 我们知道在没有绑定域名的时候前后台可以同步登录和退出,但 ...
- android 数据库的升级与降级解决方案
在我们写的程序中不避免的需要升级.或者说需要改变业务逻辑,那这个时候就需要修改数据库的字段,来适应不同的表结构 我们一般写数据库都是操作一个继承至 SQLiteOpenHelper 的类 然后我们需要 ...