【C语言天天练(二)】预处理
引言:
学C语言之初。一提到预处理,脑子里想到的就是#define的宏定义以及#include包括的头文件。后来随着对C的深入学习发现。预处理不止这些。比方条件编译、提前定义的宏等等。以下对此进行总结。
先给出预处理的定义:在编译程序之前,先由预处理器检查程序(因此称为预处理器),依据程序中使用的预处理器命令,预处理器用符号缩略语所代表的内容替换程序中的缩略语。
1. #define
最经常使用的预处理器命令就是define命令,该预处理器命令有三部分组成:#define本身、符号缩略语、替换列表(或称为主体)。
结构可写为:#define 宏 主体 当中宏部分不能有空格,仅仅能是数字、下划线、字母。但第一个字符不能使数字。
如:#define PX printf("x is %d.\n", x)
预处理器发现程序中的宏后,会用它的等价替换文件取代宏。假设该字符串中还包含宏。则继续替换这些宏。假设宏出如今双引號中,则不做替换。
假设在双引號中出现的宏前面有“#运算符”,则能够用宏參数创建字符串。如:
#define PSQR(X) printf("The square of X is %d.\n", ((X)*(X)))
PSQR(8) //等价于printf("The square of X is %d.\n", ((8)*(8)))。输出The square of X is 64.
#define PSQR(X) printf("The square of "#X" is %d.\n", ((X)*(X)))
PSQR(8) //等价于printf("The square of8 is %d.\n", ((8)*(8))),输出The square of8 is 64.
小结:引號中的字符中中的X被看作普通文本,而不是被看作一个可替换的语言符号。#符号用作一个预处理运算符,它能够把语言符号转化为字符串。
预处理器的粘合剂:##运算符。和上面的#运算符一样。##运算符能够用于类函数宏的替换部分。
##还能用于类对象宏的替换部分,把两个符号组合成单个语言符号,如:
#define XNAME(n) x##n
XNAME(4) //等价于x4
从宏的定义和使用能够看出,它与函数很相近,但宏与函数又有所不同,他们的选择实际上是时间和空间的权衡。
宏产生内联代码,也就是说在程序中产生语句。
假设使用宏20次,则会把20行代码插入程序中。假设使用函数20次,那么程序中仅仅有一份函数的语句拷贝,因此节省了空间。
还有一方面。程序的控制必须转移到函数中并随后返回调用程序。因此这比内联代码话费的时间多。
2.#include
预处理器发现#include指令后,就会寻找后跟的文件名称并把这个文件的内容包括到当前文件里。被包括文件的文本将替换源码文件里的#include指令。就像把被保护文件里的所有内容键入到源文件里的这个特定位置一样。
#include <name.h> // 文件放在尖括号里,搜索系统工作文件夹
#include “name.h” // 文件名称放在双引號中,搜索当前工作文件夹
#include "/dir1/dir2/name.h" // 搜索/dir1/dir2文件夹
头文件里一般包括的内容有:明显常量、宏函数、函数声明、结构体模板定义、类型定义
3. 其它指令
#undef指令取消前面的#define定义。
#if #ifdef #ifndef #else #elif #endif指令可用于选择什么情况下编译哪些代码。#line指令用于重置行和文件信息,#error指令用于给出错误消息。#param指令用于想编译器发出指示
4. 提前定义的宏:
__DATE__ : 进行预处理的日期
__FILE__ :代码当前源码文件名称的字符串文字
__LINE__ :代表当前源码文件里的行号的整数常量
__STDC__ :设置为1时。表示该实现遵循C标准
__TIME__ : 源文件编译时间
【C语言天天练(二)】预处理的更多相关文章
- 【C语言天天练(二四)】内存分配
引言: 对于C语言程序,了解它执行时在内存中是怎样分配的对于我们理解它的执行机制是很实用的.以下就总结一下C语言程序的一些内存分配知识. 一 一段C程序.编译连接后形成的可运行文件一般有代码段.数据段 ...
- 【C语言天天练(二一)】内联函数
引言:调用函数时,一般会由于建立调用.传递參数.跳转到函数代码并返回等花费掉一些时间,C语言的解决的方法是使用类函数宏.在C99中,还提出了第二种方法:内联函数. 内联 ...
- 【C语言天天练(二)】statickeyword
引言: statickeyword不仅能够修饰变量.并且能够修饰函数.了解它的使用方法,不仅对阅读别人的代码有帮助,也有助于自己写出更加健壮的程序. 使用方法: ...
- 【C语言天天练(二二)】位操作
C的位运算符 1.二进制反码或按位取反:~ ~(10011010) = (01100101). 假设val是一个unsigned char,~val不改名原来val的值. 2.位与:& 二进制 ...
- 【C语言天天练(十一)】深入理解指针
引言:在C语言中.指针的地位是不言而喻的,要想非常好的掌握C语言,掌握指针是必须的,这也是C语言不同于其它语言的地方. (一)指针的指针 样例: int i; int *pi;/*把pi初始化为指向变 ...
- 【C语言天天练(二三)】errno变量
引言: 在C编程中,errno是个必不可少的变量.特别是在网络编程中. 假设你没实用过errno,那仅仅能说明你的程序不够健壮. 为什么会使用errno呢?这是系统库设计中的一个无奈之举.他很多其它的 ...
- 【C语言天天练(九)】动态内存分配
引言:数组的元素存储于内存中连续的位置上.当一个数组被声明时.它所须要的内存在编译时就被分配. 可是,我们能够使用动态内存分配在执行时为它分配内存. 一块内存的生命周期能够分为四个阶段:分配.初始化. ...
- 【C语言天天练(十五)】字符串输入函数fgets、gets和scanf
引言:假设想把一个字符串读到程序中.必须首先预留存储字符串的空间.然后使用输入函数来获取这个字符串. 读取字符串输入的第一件事是建立一个空间以存放读入的字符串. char *name; scanf(& ...
- 【C语言天天练(三)】typedef具体解释
引言: typedef能够看作type define的缩写,顾名思义就是类型定义,也就是说它仅仅是给已有的类型又一次定义了一个方便使用的别名.并没有产生新的数据类型. typedef与define的不 ...
随机推荐
- jedis连接集群
/** * 集群版 */ @Test public void JedisJiuQun() { HashSet< ...
- java读取本地txt文件并插入数据库
package com.cniia.ny.web.control.configManage; import java.io.BufferedReader; import java.io.File; i ...
- ajax 参数data问题 data中的 参数名 参数值为string 提交到后台后,会自动转换参数名相同的 类型 和 js字符串拼接
latlng"14.6005238,100.43635419999998"Cusid"accb5c1b-6aef-4f3b-a4eb-d60ea1ca5f54" ...
- PayPal 对接
时间:2019-1-29 15:39:39 文章相应链接: 官方SDK:https://developer.paypal.com/docs/api/rest-sdks/ 官方API:https://d ...
- EMQ -- 用户密码认证
emq 的用户密码认证 MQTT 认证设置 EMQ 消息服务器认证由一系列认证插件(Plugin)提供,系统支持按用户名密码.ClientID 或匿名认证. 系统默认开启匿名认证(anonymous) ...
- swipeRefreshLayout与webview滑动冲突
遇到这么个bug,webview使用swipeRefreshLayout时,下拉时事件不会被webview捕获,而是执行swipeRefreshLayout的刷新,网上一大堆一大堆的解决办法,都是什么 ...
- NFS介绍
一.NFS服务介绍 NFS是 Network File system的缩写 NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机 ...
- CSS/JQuery元素选择器之&&和||,选择器的逻辑操作
使用CSS或JQuery选中元素的时候.非常多时候我们须要对条件进行&&或者||操作. JQuery或者CSS中的||操作是非经常常使用的.也非常easy,就是通过逗号来分隔的. se ...
- Atitit.软件开发的几大规则,法则,与原则。。。attilax总结
Atitit.软件开发的几大规则,法则,与原则... 1. 设计模式六大原则 2 1.1. 设计模式六大原则(1):单一职责原则 2 1.2. 设计模式六大原则(2):里氏替换原则 2 1.3. 设计 ...
- iOS开发多线程篇 08 —GCD的常见用法
iOS开发多线程篇—GCD的常见用法 一.延迟执行 1.介绍 iOS常见的延时执行有2种方式 (1)调用NSObject的方法 [self performSelector:@selector(run) ...