C++ 高级篇(五)—— 预处理指令

预处理指令是我们写在程序代码中的给预处理器(preprocessor)的 命令,而不是程序本身的语句。预处理器在我们编译一个C++程序时由编译器自动执行,它负责控制对程序代码的第一次验证和消化。

所有这些指令必须写在单独的一行中,它们不需要加结尾的分号;。


#define

在这个教程的开头我们已经提到了一种预处理指令: #define ,可以被用来生成宏定义常量(defined constantants 或 macros),它的形式是:

#define name value

它的作用是定义一个叫做name 的宏定义,然后每当在程序中遇到这个名字的时候,它就会被value代替,例如:

#define MAX_WIDTH 100
char str1[MAX_WIDTH];
char str2[MAX_WIDTH];

它定义了两个最多可以存储100个字符的字符串。

#define 也可以被用来定义宏函数:

#define getmax(a,b) a>b?a:b
int x=5, y;
y = getmax(x,2);

这段代码执行后y 的值为5 。


#undef

#undef 完成与 #define相反的工作,它取消对传入的参数的宏定义:

#define MAX_WIDTH 100
char str1[MAX_WIDTH];
#undef MAX_WIDTH
#define MAX_WIDTH 200
char str2[MAX_WIDTH];

#ifdef, #ifndef, #if, #endif, #else and #elif

这些指令可以使程序的一部分在某种条件下被忽略。

#ifdef 可以使一段程序只有在某个指定常量已经被定义了的情况下才被编译,无论被定义的值是什么。它的操作是:

#ifdef name
// code here
#endif

例如:

#ifdef MAX_WIDTH
char str[MAX_WIDTH];
#endif

在这个例子中,语句char str[MAX_WIDTH]; 只有在宏定义常量MAX_WIDTH 已经被定义的情况下才被编译器考虑,不管它的值是什么。如果它还没有被定义,这一行代码则不会被包括在程序中。

#ifndef 起相反的作用:在指令#ifndef 和 #endif 之间的代码只有在某个常量没有被定义的情况下才被编译,例如:

#ifndef MAX_WIDTH
#define MAX_WIDTH 100
#endif
char str[MAX_WIDTH];

这个例子中,如果当处理到这段代码的时候MAX_WIDTH 还没有被定义,则它会被定义为值100。而如果它已经被定义了,那么它会保持原值 (因为#define 语句这一行不会被执行) 。

指令#if, #else 和 #elif (elif = else if) 用来使得其后面所跟的程序部分只有在特定条件下才被编译。这些条件只能够是常量表达式,例如:

#if MAX_WIDTH>200
#undef MAX_WIDTH
#define MAX_WIDTH 200

#elsif MAX_WIDTH<50
#undef MAX_WIDTH
#define MAX_WIDTH 50

#else
#undef MAX_WIDTH
#define MAX_WIDTH 100
#endif

char str[MAX_WIDTH];

注意看这一连串的指令 #if, #elsif 和 #else 是怎样以 #endif 结尾的。


#line

当我们编译一段程序的时候,如果有错误发生,编译器会在错误前面显示出错文件的名称以及文件中的第几行发生的错误。

指令#line 可以使我们对这两点进行控制,也就是说当出错时显示文件中的行数以及我们希望显示的文件名。它的格式是:

#line number "filename"

这里number 是将会赋给下一行的新行数。它后面的行数从这一点逐个递增。

filename 是一个可选参数,用来替换自此行以后出错时显示的文件名,直到有另外一个#line指令替换它或直到文件的末尾。例如:

#line 1 "assigning variable"
int a?;

这段代码将会产生一个错误,显示为在文件"assigning variable", line 1 。


#error

这个指令将中断编译过程并返回一个参数中定义的出错信息,例如:

#ifndef __cplusplus
#error A C++ compiler is required
#endif

这个例子中如果 __cplusplus 没有被定义就会中断编译过程。


#include

这个指令我们已经见到很多次。当预处理器找到一个#include 指令时,它用指定文件的全部内容替换这条语句。声明包含一个文件有两种方式:

#include "file"
#include <file>

两种表达的唯一区别是编译器应该在什么路经下寻找指定的文件。第一种情况下,文件名被写在双引号中,编译器首先在包含这条指令的文件所在的目录下进行寻找,如果找不到指定文件,编译器再到被配置的默认路径下(也就是标准头文件路径下)进行寻找。

如果文件名是在尖括号 <> 中,编译器会直接到默认标准头文件路径下寻找。


#pragma

这个指令是用来对编译器进行配置的,针对你所使用的平台和编译器而有所不同。要了解更多信息,请参考你的编译器手册。

如果你的编译器不支持某个#pragma的特定参数,这个参数会被忽略,不会产生出错。


预定义的宏名称 (Predefined macro names)

以下宏名称在任何时候都是定义好的:


macro value
__LINE__整数值,表示当前正在编译的行在源文件中的行数。
__FILE__字符串,表示被编译的源文件的文件名。
__DATE__一个格式为 "Mmm dd yyyy" 的字符串,存储编译开始的日期。
__TIME__一个格式为 "hh:mm:ss" 的字符串,存储编译开始的时间。
__cplusplus整数值,所有C++编译器都定义了这个常量为某个值。如果这个编译器是完全遵守C++标准的,它的值应该等于或大于199711L,具体值取决于它遵守的是哪个版本的标准。

例如:

// 标准宏名称
#include <iostream>
using namespace std;int main()
{cout << "This is the line number " << __LINE__;cout << " of file " << __FILE__ << ".\n";cout << "Its compilation began " << __DATE__;cout << " at " << __TIME__ << ".\n";cout << "The compiler gives a "<<"__cplusplus value of " << __cplusplus;return 0;
}
This is the line number 7 of file /home/jay/stdmacronames.cpp.
Its compilation began Nov 1 2005 at 10:12:29.
The compiler gives a __cplusplus value of 1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/401819.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

yarn oom问题一例

线上部分job运行失败&#xff0c;报OOM的错误:因为是maptask报错&#xff0c;怀疑是map数量过少&#xff0c;导致oom&#xff0c;因此调整参数&#xff0c;增加map数量&#xff0c;但是问题依然存在。看来和map的数量没有关系。通过jobid查找jobhistory中对应的日志信息&#x…

C++ 高级篇(三)—— 出错处理

本节介绍的出错处理是ANSI-C 标准引入的新功能。如果你使用的C 编译器不兼容这个标准&#xff0c;则你可能无法使用这些功能。 在编程过程中&#xff0c;很多时候我们是无法确定一段代码是否总是能够正常工作的&#xff0c;或者因为程序访问了并不存在的资源&#xff0c;或者由…

kickStart脚本

kickstart是什么 许多系统管理员宁愿使用自动化的安装方法来安装红帽企业 Linux.为了满足这种需要,红帽创建了kickstart安装方法.使用kickstart,系统管理员可以创建一个文件,这个文件包含了在典型的安装过程中所遇 到的问题的答案. Kickstart文件可以存放于单一的…

C++ 高级篇(二)—— 名空间 (Namespaces)

通过使用名空间(Namespaces)我们可以将一组全局范围有效的类、对象或函数组织到一个名字下面。换种说法&#xff0c;就是它将全局范围分割成许多子域范围&#xff0c;每个子域范围叫做一个名空间(namespaces). 使用名空间的格式是&#xff1a; namespace identifier{namespace-…

32位CentOS系统安装kernel-PAE支持4g以上内存

转载自http://hi.baidu.com/yinhuama/item/31e572bb0a38f2ea4ec7fd7f 32位centos系统默认安装i386的内核不支持4g的内存 用yum安装kernel-PAE yum -y install kernel-PAE>vim /boot/grub/grub.conf修改设置为默认启动&#xff0c;default1改为default0 重启服务器 reboot再执…

C++ 高级篇(一)—— 模板(Templates)

模板(Templates)是ANSI-C 标准中新引入的概念。如果你使用的 C 编译器不符合这个标准&#xff0c;则你很可能不能使用模板。 函数模板( Function templates) 模板(Templates)使得我们可以生成通用的函数&#xff0c;这些函数能够接受任意数据类型的参数&#xff0c;可返回任意类…

Java笔试之Singleton

单例模式的出现&#xff0c;其主要的目的是为了使一个类只有一个实例存在。 实现单例模式主要有两种方式&#xff08;我所知道的&#xff09; 饿汉式&#xff1a;不管有没有需要&#xff0c;都在内部先new出一个实例public class Singleton{//私有的默认构造子 private Single…

Linux--文件结构体struct file

代码:struct file {   struct file *f_next&#xff0c;**f_pprev;   struct dentry *f_dentry;   struct file_operations *f_op;   mode_t f_mode;   loff_t f_pos;   unsigned int f_count&#xff0c;f_flags;   unsigned long f_reada&#xff0c;f_…

PPT到底是天使还是魔鬼?

说老实话&#xff0c;我非常不喜欢那些PPT的培训者一味地鼓吹PPT的重要性&#xff0c;视觉化思维的重要性&#xff0c;PPT在演讲中的重要性等等&#xff0c;我很清楚他们这么说是因为他们必须这么说&#xff0c;因为如果不把PPT的重要性强调一下&#xff0c;谁来上他的课呢&…

ultraedit正则表达式

一般使用ultraedit中的Perl风格的正则表达式&#xff0c;下面是perl正则的基本语法 perl中的元字符如下&#xff1a; ^ 表示一行的开头&#xff1b; $ 表示一行的结尾&#xff1b; ( ) 表示一个匹配块的&#xff0c;可以对匹配上的块通过$1,$2...进行读取&#xff0c;…

微软云介绍

微软云介绍 http://msdn.microsoft.com/zh-cn/ff380142 什么是云开发&#xff1f;&#xff08;概述&#xff09; 云计算是指远程运行并通过 Internet 访问的计算机和应用程序。在云计算中&#xff0c;虚拟机在大型数据中心中运行&#xff0c;并取代了物理 PC 和服务器。通过将许…

IO端口和IO内存的区别及分别使用的函数接口

IO端口和IO内存的区别及分别使用的函数接口 每个外设都是通过读写其寄存器来控制的。外设寄存器也称为I/O端口&#xff0c;通常包括&#xff1a;控制寄存器、状态寄存器和数据寄存器三大类。根据访问外设寄存器的不同方式&#xff0c;可以把CPU分成两大类。一类CPU&#xff08…

DHCP服务开启了,为什么老是网络冲突

<b><a target"_blank" href"http://www.hnbkhb.com/ " >河南</a><a target"_blank" href"http://www.hnzzfk.com/ " >河南</a><a target"_blank" href"http://www.0371fkyy.com/ &qu…

Linux进程状态解析之R、S、D、T、Z、X

Linux进程状态解析之R、S、D、T、Z、X&#xff1b;Linux是一个多用户&#xff0c;多任务的系统&#xff0c;可以同时运&#xff1b;众所周知&#xff0c;现在的分时操作系统能够在一个CPU上运&#xff1b;在linux系统中&#xff0c;每个被运行的程序实例对应一个&#xff1b;Li…

Win8 HTML5与JS编程学习笔记(二)

近期一直受到win8应用的Grid布局困扰&#xff0c;经过了半下午加半个晚上的奋斗&#xff0c;终于是弄明白了Grid布局方法的规则。之前我是阅读的微软官方的开发教程&#xff0c;书中没有详细说明CSS3的布局规则&#xff0c;自己鼓捣了半天也是一头雾水&#xff0c;于是又找到了…

flsah的分类

1. flash按照内部存储结构不同&#xff0c;分为两种&#xff1a;nor flash和nand flash。 nor flash&#xff1a;像访问SDRAM一样&#xff0c;按照数据/地址总线直接访问, 可写的次数较少&#xff0c;速度也慢&#xff0c;由于其读时序类似于SRAM&#xff0c;读地址是线性结构&…

Oracle EXP/IMP参数详解

exp/imp是Oracle自带的导入导出命令&#xff0c;运用它&#xff0c;即使不需要那结UI工具也能轻易的完成数据导出导入工作&#xff0c;下面是它们的参数&#xff1a;EXP参数详解使用的格式是&#xff1a;EXP KEYWORDvalue 或 KEYWORD(value1,value2,...,valueN)其中USERID是必须…

java每日小算法(10)

/*【程序10】 题目&#xff1a;一球从100米高度自由落下&#xff0c;每次落地后反跳回原高度的一半&#xff1b;再落下&#xff0c;求它在 第10次落地时&#xff0c;共经过多少米&#xff1f;第10次反弹多高&#xff1f; */ package test;public class test {public static vo…

C语言串口驱动程序

驱动层屏蔽了硬件细节&#xff0c;个人猜测&#xff0c;几乎所有移植好的系统的串口&#xff0c;都可以用一样的代码来操作&#xff0c;至少2440和树莓派是通用的。 分享代码如下&#xff1a; [cpp] view plaincopy #include <sys/types.h> #include <sys/stat.h>…

Windows下的Qt Creator的安装

采用Qt和Qt creator分别下载和安装的方式&#xff1a;&#xff08;需要手动设置关联Qt和Qt Creator&#xff09; 一、软件下载 从http://qt-project.org/downloads分别下载Qt和Qt Creator&#xff1a; Qt使用4.7.2版本&#xff1a;qt-win-opensource-4.7.2-mingw.exe Qt Creato…