`

c/c++基础知识:预处理指令汇总

    博客分类:
  • c++
阅读更多
预处理指令提供按条件跳过源文件中的节、报告错误和警告条件,以及描绘源代码的不同区域的能力。使用术语“预处理指令”只是为了与 C 和 C++ 编程语言保持一致。
预处理器的主要作用就是把通过预处理的内建功能对一个资源进行等价替换,最常见的预处理有:文件包含,条件编译、布局控制和宏替换4种。
文件包含
#include 是一种最为常见的预处理,主要是做为文件的引用组合源程序正文。
条件编译
#if,#ifndef,#ifdef,#endif,#undef等也是比较常见的预处理,主要是进行编译时进行有选择的挑选,注释掉一些指定的代码,以达到版本控制、防止对文件重复包含的功能。
布局控制
#progma,这也是我们应用预处理的一个重要方面,主要功能是为编译程序提供非常规的控制流信息。
宏替换
#define,这是最常见的用法,它可以定义符号常量、函数功能、重新命名、字符串的拼接等各种功能。
下面我们看一下常见的预处理指令
#define 宏定义
#undef 未定义宏
#include 文本包含
#ifdef 如果宏被定义就进行编译
#ifndef 如果宏未被定义就进行编译
#endif 结束编译块的控制
#if 表达式非零就对代码进行编译
#else 作为其他预处理的剩余选项进行编译
#elif 这是一种#else和#if的组合选项
#line 改变当前的行数和文件名称
#error 输出一个错误信息
#pragma 为编译程序提供非常规的控制流信息
下面我们对这些预处理进行一一的说明,考虑到宏的重要性和繁琐性,我们把它放到最后讲。
文件包含指令
这种预处理使用方式是最为常见的,平时我们编写程序都会用到,最常见的用法是:
#include <iostream> //标准库头文件
#include <iostream.h> //旧式的标准库头文件
#include "IO.h" //用户自定义的头文件
#include "../file.h" //UNIX下的父目录下的头文件
#include "/usr/local/file.h" //UNIX下的完整路径
#include "..\file.h" //Dos下的父目录下的头文件
#include "\usr\local\file.h" //Dos下的完整路径
这里面有2个地方要注意:
1、我们用<iostream>还是<iostream.h>?
我们主张使用<iostream>,而不是<iostream.h>,为什么呢?我想你可能还记得我曾经给出过几点理由,这里我大致的说一下:首先,.h格式的头文件早在98年9月份就被标准委员会抛弃了,我们应该紧跟标准,以适合时代的发展。其次,iostream.h只支持窄字符集,iostream则支持窄/宽字符集。
还有,标准对iostream作了很多的改动,接口和实现都有了变化。最后,iostream组件全部放入namespace std中,防止了名字污染。
2、<io.h>和"io.h"的区别?
其实他们唯一的区别就是搜索路径不同:
对于#include <io.h> ,编译器从标准库路径开始搜索
对于#include "io.h" ,编译器从用户的工作路径开始搜索
编译控制指令

这些指令的主要目的是进行编译时进行有选择的挑选,注释掉一些指定的代码,以达到版本控制、防止对文件重复包含的功能。
使用格式,如下:
1、
1.             #ifdef identifier 
2.             your code 
3.             #endif
如果identifier为一个定义了的符号,your code就会被编译,否则剔除
2、
1.             #ifndef identifier 
2.             your code 
3.             #endif
如果identifier为一个未定义的符号,your code就会被编译,否则剔除
3、
1.             #if expression 
2.             your code 
3.             #endif
如果expression非零,your code就会被编译,否则剔除
4、
1.             #ifdef identifier 
2.             your code1 
3.             #else 
4.             your code2 
5.             #endif
如果identifier为一个定义了的符号,your code1就会被编译,否则yourcode2就会被编译
5、
1.             #if expressin1 
2.             your code1 
3.             #elif expression2 //呵呵,elif 
4.             your code2 
5.             #else 
6.             your code3 
7.             #enif
如果epression1非零,就编译your code1,否则,如果expression2非零,就编译your code2,否则,就编译your code3
其他预编译指令

除了上面我们说的集中常用的编译指令,还有3种不太常见的编译指令:#line、#error、#pragma,我们接下来就简单的谈一下。
#line的语法如下:
1.             #line number filename
例如:#line 30 a.h 其中,文件名a.h可以省略不写。
这条指令可以改变当前的行号和文件名,例如上面的这条预处理指令就可以改变当前的行号为30,文件名是a.h。初看起来似乎没有什么用,不过,他还是有点用的,那就是用在编译器的编写中,我们知道编译器对C++源码编译过程中会产生一些中间文件,通过这条指令,可以保证文件名是固定的,不会被这些中间文件代替,有利于进行分析。
#error语法如下:
1.             #error info
例如:
1.             #ifndef UNIX 
2.             #error This software requires the UNIX OS. 
3.             #endif
这条指令主要是给出错误信息,上面的这个例子就是,如果没有在UNIX环境下,就会输出This software requires the UNIX OS.然后诱发编译器终止。所以总的来说,这条指令的目的就是在程序崩溃之前能够给出一定的信息。
#pragma是非统一的,他要依靠各个编译器生产者,例如,在SUN C++编译器中:
1.             // 把name和val的起始地址调整为8个字节的倍数 
2.             #progma align 8 (name, val) 
3.             char name[9]; 
4.             double val; 
5.             //在程序执行开始,调用函数MyFunction 
6.             #progma init (MyFunction)
预定义标识符
为了处理一些有用的信息,预处理定义了一些预处理标识符,虽然各种编译器的预处理标识符不尽相同,但是他们都会处理下面的4种:
1.      __FILE__ 正在编译的文件的名字
2.      __LINE__ 正在编译的文件的行号
3.      __DATE__ 编译时刻的日期字符串,例如: "25 Dec 2000"
4.      __TIME__ 编译时刻的时间字符串,例如: "12:30:55"
例如:cout<<"The file is :"<<__FILE__"<<"! The lines is:"<<__LINE__<<endl;
预处理何去何从

如何取代#include预处理指令,我们在这里就不再一一讨论了。
C++并没有为#include提供替代形式,但是namespace提供了一种作用域机制,它能以某种方式支持组合,利用它可以改善#include的行为方式,但是我们还是无法取代#include。
#progma应该算是一个可有可无的预处理指令,按照C++之父Bjarne的话说,就是:"#progma被过分的经常的用于将语言语义的变形隐藏到编译系统里,或者被用于提供带有特殊语义和笨拙语法的语言扩充。”
对于#ifdef,我们仍然束手无策,就算是我们利用if语句和常量表达式,仍然不足以替代她,因为一个if语句的正文必须在语法上正确,满足类检查,即使他处在一个绝不会被执行的分支里面。
声明:本文内容来自网络!
分享到:
评论

相关推荐

    程序员笔试题汇总(C/C++,智力题)

    这些知识点是C/C++程序设计的基础,要求考生能够熟练编写和理解代码。 2. **数据结构**:链表、栈、队列、树(如二叉树、平衡树)、图等。数据结构的选择和操作直接影响程序的效率和可读性,考生需要熟悉它们的操作...

    c/c++笔试题目汇总

    【C/C++笔试题目解析】 1. 表达式判断: 在C/C++中,自增自减运算符有前缀和后缀两种形式,它们会影响运算的顺序。题目中给出了四个表达式,...这些内容对于理解和解决问题至关重要,也是C/C++程序员必备的基础知识。

    程序员C/C++面试题汇总(Intel英特尔面试题.微软亚洲技术中心的面试题,Cisco思科面试题,华为C/C++笔试题,慧通面试题)

    1. **基础知识**:面试通常会涵盖C/C++的基础语法,如变量、数据类型、运算符、流程控制语句(如if-else、switch-case、循环)、函数、指针等。理解这些概念是任何C/C++程序员的基础。 2. **内存管理**:面试中常...

    C/C++,Java面试题汇总

    本资料包“C/C++,Java面试题汇总”包含了这三个语言的面试常见问题,旨在帮助求职者充分准备,提升面试成功的概率。 对于C语言面试题,以下是一些可能涉及到的知识点: 1. **基本语法**:指针、数组、结构体、...

    C/C++面试题大汇总 收藏

    面试中,这些问题旨在考察面试者的基础知识、代码风格和对C/C++特性的理解。对于嵌入式程序员来说,了解预处理器、宏的使用及其潜在问题、无限循环的编写以及数据类型的声明至关重要,因为这些是构建高效、可靠代码...

    C/C++笔试题汇总

    在C/C++编程领域,掌握扎实的基础和熟练的算法应用是至关重要的。这份"**C/C++笔试题汇总**"正是一个集大成者,它包含了大量的编程题目,旨在帮助无论是初学者还是经验丰富的程序员提升自己的技能。这些题目来源于...

    C/C++编程面试题大总结

    在C/C++编程领域,面试通常会涉及到许多关键知识点,这些知识点不仅测试候选人的基础知识,还考察其实际问题解决能力和编程技巧。以下是对"标题"和"描述"中提到的面试题大总结的详细解析: 1. **基础语法**:C/C++...

    C/C++嵌入式面试汇总

    这份“C、C++笔试题汇总”涵盖了基础理论、编程实践、系统级理解等多个方面,旨在帮助面试者全面提升自身技能。 首先,C语言是嵌入式开发的基础,它以其简洁、高效而被广泛应用于硬件控制和底层系统开发。面试中...

    C_C++面试题大汇总

    总之,成为一名合格的嵌入式程序员,需要扎实的C/C++基础,深入理解预处理器、指针、数据结构以及内存管理。面试中,这些问题不仅测试技术能力,也评估了候选人的思考方式和解决问题的能力。在准备面试时,应确保...

    C++基础知识全面汇总

    ### C++基础知识全面汇总 #### 一、字符串与字符处理 1. **字符串与字符的存储**:在C++中,字符串是由多个字符组成的数组,其中每个字符占用一个字节的空间。例如,字符串`"abc\0"`实际上占用4个字节的空间,包括...

    最全的C和C++语言笔试面试题汇总

    《C和C++语言笔试面试题汇总》是针对C++开发者和求职者的重要参考资料,它涵盖了C语言和C++的基础概念、语法特性以及面试常见问题。以下是对这些知识点的详细解读: 1. 关键字`static`的作用: - 在函数内部,`...

    TMS320C28x Optimizing C_C++ Compiler v6.2.4

    - **C文件处理方式**:更改编译器处理C文件的方法,如预处理指令的行为。 - **目录指定**:允许指定包含头文件和其他资源的目录。 - **汇编器选项**:控制汇编器的行为。 - **动态链接**:支持动态链接库的使用。 - ...

    c与c++面试题汇总.pdf

    在处理这些知识点时,读者应重点关注C和C++语言的基础语法、内存管理、控制结构、函数编程、预处理指令、类型转换以及面向对象编程的基本概念。同时,了解计算机网络基础知识,特别是IP和TCP/IP协议栈的相关内容,...

    C++ 笔试基础题

    这份资料集合包含了多个文档,分别命名为“c,c++基础知识.doc”、“C_C++笔试基础题.doc”和“最全的C和C++语言笔试面试题汇总.doc”,它们将帮助你深入理解C++的核心概念,提高解决实际问题的能力。 首先,C++的...

    面试题汇总(java c c++)

    在IT行业中,面试是检验求职者技能和知识的关键环节,特别是在Java、C和C++这三个广泛使用的编程语言中。这份“面试题汇总”涵盖了这些语言的核心概念和技术,旨在帮助求职者准备并理解面试官可能提出的问题。下面...

    数据结构算法类笔试常考题

    根据给定文件的信息,我们可以总结出以下几个重要...以上知识点覆盖了数据结构与算法的基础概念、算法设计与分析、计算机硬件基础知识以及C/C++语言编程等方面的内容,对于准备笔试的同学来说是非常实用的知识点汇总。

Global site tag (gtag.js) - Google Analytics