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是一个整数.实际数字不足的 ...
随机推荐
- 支持IE6以上阴影效果纯CSS
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 六种简单方法提升ASP.NET Web API性能
ASP.NET Web API 是非常棒的技术.编写 Web API 十分容易,以致于很多开发者没有在应用程序结构设计上花时间来获得很好的执行性能. 在本文中,我将介绍8项提高 ASP.NET Web ...
- 【解决】python2.x版本的Django下admin管理页面css无效
折腾一下午,终于解决了这个问题,有必要记录一下,我就奇怪了为什么实验室电脑没问题,到宿舍就挂掉了,哼 主要是改mimetypes文件,位于D:\MySoftware\Python27\Lib下 1.添 ...
- POJ2923--Relocation(01背包+状压dp)
果然对状压DP,我根本就不懂=.= /************************************************** Problem: 2923 User: G_lory Mem ...
- JDBC与SQL SERVER各个版本的连接方法
转至:blog.csdn.net/ying5420/article/details/4488246 1.SQL SERVER 2000 JDBC驱动程序:msbase.jar.mssqlserver. ...
- MyCat集群部署(HAProxy + MyCat)
本文档内容的依赖龙果学院<基于Dubbo的分布式系统架构实战>课程 二.软件版本 操作系统:CentOS-6.6-x86_64 JDK版本:jdk1.7.0_72 HAProxy版本:ha ...
- Linux下OpenSSL 安装
安装环境: 操作系统:CentOs6.3 OpenSSL Version:openssl-1.0.0e.tar.gz 目前版本最新的SSL地址为http://www.openssl.org/sour ...
- 【python自动化第八篇:网络编程】
一.拾遗 动态导入模块 目的是为了在导入模块的过程中将模块以字符的格式导入. #!/usr/bin/env python # -*- coding:utf-8 -*- #Author:wanghui ...
- java transient简单介绍
我们都知道一个对象仅仅要实现了Serilizable接口,这个对象就能够被序列化,java的这样的序列化模式为开发人员提供了非常多便利,我们能够不必关系详细序列化的过程,仅仅要这个类实现了Serili ...
- jQuery Mobile方向感应事件
在现在的智能手机中,都有对方向变换的自动感知功能,比如当手机方向从水平方向切换到垂直方向时,则会触发该事件.在jQuery Mobile中,可以通过orientationchange事件进行绑定,并且 ...