对VC中自己有疑惑的做下总结:
1.串化是什么意思
#include "stdafx.h" #define chSTR2(x) #x #define intSTR2(x) x //这个是串化,chSTR2(1+1==2)替换成"1+1==2" int main(int argc, char *argv[]) { char *buf = chSTR2(1 + 1 == 3); printf("%s\n", buf); int nRet = intSTR2(1 + 1 == 3); printf("%d\n", nRet); return 0; } |
1 + 1 == 3
0
也就是说,如果是串化的话,返回的是字符串本身;
而这种格式的int型的话,返回的是括号里面的表达式的逻辑值。
如果输入为1 + 1 == 2的话,输出就为:
1 + 1 == 2
1
2.预编译prama的意思:
#pragma warning(push)是保存当前的编译器警告状态;#pragma warning( push ) #pragma warning( disable : 4705 ) #pragma warning( disable : 4706 ) #pragma warning( disable : 4707 ) // Some code #pragma warning( pop ) |
这样在编译Some code部分的代码时,4705、4706、4707三个警告将不会出现。
#pragma warning(push, 3) // 3 级警告设置入栈 #pragma warning(pop) // 警告设置出栈 #pragma warning(push, 4) // 4 级警告设置入栈 #pragma message( "???? ") // 编译时输出消息???? #pragma warning(disable:4001) // 忽略4001号警告.. |
进一步的,网上有篇prama命令详解,写的可以
====================================================================================
虽然我用VC用了有段时间,但好像对其中的#pragma预处理指令并不是很了解。这两天由于做WINCE的课程设计遇到太多太多的问题,其中就有关于#pragma的使用。下面我就引用一牛人对#pragma的评论做个小结,顺便也给自己加强记忆:
1. 在VC6.0中定义类CXMLError的头文件中起始处有如下#include语句
#include <comdef.h>
#include <string>
class CXMLError
{
…
}
在使用Level 4编译时,报告C4100,C4511,C4512,C4663,C4245,C4018几种Warning
2. 修改为如下:
#pragma warning( push )
#pragma warning( disable : 4100 4511 4512 4663 4245 4018)
#include <comdef.h>
#include <string>
#pragma warning( pop )
这时产生了大量C4514警告。
3. 再修改为
#pragma warning( push )
#pragma warning( disable : 4100 4511 4512 4663 4245 4018 4514)
#include <comdef.h>
#include <string>
#pragma warning( pop )
结果依然如上,有大量C4514警告,少量4663,4245,4108。
4. 再修改如下:
#pragma warning( disable : 4100 4511 4512 4663 4245 4018 4514)
#pragma warning( push )
#include <comdef.h>
#include <string>
#pragma warning( pop )
结果只余下4663, 4245, 4108
由于不能去除4663, 4245, 4108三种警告
5. 又对包含头文件修改为在Level 3编译,如下:
#pragma warning( disable:4514)
#pragma warning( push,3 )
#include <comdef.h>
#include <string>
#pragma warning( pop)
结果无警告产生。
6. 又尝试如下修改:
#include <comdef.h>
#pragma warning( push,3 )
#include <string>
#pragma warning( pop)
结果无警告产生。
1. 在防止包含头文件引起的Warning而使用#pragma warning时,应只针对产生警告的头文件进行处理,在这个问题中是<string>,这时应该在#include <string>上面加#pragma warning(push),否则可能增加其它警告,如此处产生的大量C4514
2. 在使用#pragma warning(push)后使用#pragma warning(disable: xxxx)可能无效时,可以尝试交换两个语句的顺序,这可能是VC6.0中的#pragma warning的Bug。
3. 在VC6.0中存在一些不能diable掉的Warning,如4663, 4245, 4108等。这可能是VC6.0的Bug,如已知的C4786在VC6.0中不能disable掉,使用#pragma warning(disable : 4786)之后仍然会显示警告。
3.预编译:
一、预编译头文件说明
所谓头文件预编译,就是把一个工程(Project)中使用的一些MFC标准头文件(如Windows.H、Afxwin.H)预先编译,以后该工程编译时,不再编译这部分头文件,仅仅使用预编译的结果。这样可以加快编译速度,节省时间。
预编译头文件通过编译stdafx.cpp生成,以工程名命名,由于预编译的头文件的后缀是“pch”,所以编译结果文件是projectname.pch。
编译器通过一个头文件stdafx.h来使用预编译头文件。stdafx.h这个头文件名是可以在project的编译设置里指定的。编译器认为,所有在指令#include "stdafx.h"前的代码都是预编译的,它跳过#include "stdafx. h"指令,使用projectname.pch编译这条指令之后的所有代码。
因此,所有的CPP实现文件第一条语句都是:#include "stdafx.h"。
另外,每一个实现文件CPP都包含了如下语句:
#ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif |
这是表示,如果生成调试版本,要指示当前文件的名称。__FILE__是一个宏,在编译器编译过程中给它赋值为当前正在编译的文件名称。
VC.NET默认情况下使用预编译头(/Yu),不明白的在加入新.h文件后编译时总出现fatal error C1010: 在查找预编译头指令时遇到意外的文件结尾的错误。解决方法是在include头文件的地方加上#include "stdafx.h",或者打项目属性,找到“C/C++”文件夹,单击“预编译头”属性页。修改“创建/使用预编译头”属性为“不使用预编译头”。
二、预处理的由来
在C++的历史发展中,有很多的语言特征(特别是语言的晦涩之处)来自于C语言,预处理就是其中的一个。C++从C语言那里把C语言预处理器继承过来(C语言预处理器,被Bjarne博士简称为Cpp,不知道是不是C Program Preprocessor的简称)。
三、常见的预处理功能
预处理器的主要作用就是把通过预处理的内建功能对一个资源进行等价替换,最常见的预处理有:文件包含,条件编译、布局控制和宏替换4种。
文件包含:#include 是一种最为常见的预处理,主要是做为文件的引用组合源程序正文。
条件编译:#if,#ifndef,#ifdef,#endif,#undef等也是比较常见的预处理,主要是进行编译时进行有选择的挑选,注释掉一些指定的代码,以达到版本控制、防止对文件重复包含的功能。
布局控制:#pragma,这也是我们应用预处理的一个重要方面,主要功能是为编译程序提供非常规的控制流信息。
宏替换:#define,这是最常见的用法,它可以定义符号常量、函数功能、重新命名、字符串的拼接等各种功能。
4.头文件及其作用:
C、传统 C++ #include <assert.h> //设定插入点 #include <ctype.h> //字符处理 #include <errno.h> //定义错误码 #include <float.h> //浮点数处理 #include <fstream.h> //文件输入/输出 #include <iomanip.h> //参数化输入/输出 #include <iostream.h> //数据流输入/输出 #include <limits.h> //定义各种数据类型最值常量 #include <locale.h> //定义本地化函数 #include <math.h> //定义数学函数 #include <stdio.h> //定义输入/输出函数 #include <stdlib.h> //定义杂项函数及内存分配函数 #include <string.h> //字符串处理 #include <strstrea.h> //基于数组的输入/输出 #include <time.h> //定义关于时间的函数 #include <wchar.h> //宽字符处理及输入/输出 #include <wctype.h> //宽字符分类 标准 C++ (同上的不再注释) #include <algorithm> //STL 通用算法 #include <bitset> //STL 位集容器 #include <cctype> #include <cerrno> #include <clocale> #include <cmath> #include <complex> //复数类 #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <deque> //STL 双端队列容器 #include <exception> //异常处理类 #include <fstream> #include <functional> //STL 定义运算函数(代替运算符) #include <limits> #include <list> //STL 线性列表容器 #include <map> //STL 映射容器 #include <iomanip> #include <ios> //基本输入/输出支持 #include <iosfwd> //输入/输出系统使用的前置声明 #include <iostream> #include <istream> //基本输入流 #include <ostream> //基本输出流 #include <queue> //STL 队列容器 #include <set> //STL 集合容器 #include <sstream> //基于字符串的流 #include <stack> //STL 堆栈容器 #include <stdexcept> //标准异常类 #include <streambuf> //底层输入/输出支持 #include <string> //字符串类 #include <utility> //STL 通用模板类 #include <vector> //STL 动态数组容器 #include <cwchar> #include <cwctype> using namespace std; C99 增加 #include <complex.h> //复数处理 #include <fenv.h> //浮点环境 #include <inttypes.h> //整数格式转换 #include <stdbool.h> //布尔环境 #include <stdint.h> //整型环境 #include <tgmath.h> //通用类型数学宏 |