c语言编译预处理程 预编预处理 这样子问题出在哪里

zyuqiang 的BLOG
用户名:zyuqiang
文章数:124
评论数:116
访问量:353315
注册日期:
阅读量:5863
阅读量:12276
阅读量:307865
阅读量:1024603
51CTO推荐博文
C语言学习笔记之 &编译预处理与宏定义 & 宏是编译预处理的重要定义,宏定义就像基本数据类型定义一样,可以看作是一种类型,与基本类型不同的是,宏与函数有着密切的相似之处,但是宏是编译时发生作用。一:不带参数的宏定义1. 一般格式: & & & &#define &标识符 &字符串
&标识符即为这个字符串的宏名2. 宏调用:程序中用宏名代替字符串。 &宏展开:预编译时将字符串代替宏名的过程。 &比如: & 这里的就是宏名,他代表的是字符串,预编译时将源程序中的所有宏名出现的位置都用字符串来替换。比如: 程序中出现5,它的结果实际上是 (1)宏名用大写,用来区分普通变量(2)宏定义不能以分号结束,否则分号将作为字符串的一部分参加宏展开。比如: & & & #define PI 3.1415; //结尾加了分号a=PI*r*r; 在编译预处理时,将宏展开: 分号将作为字符串参加运算,很明显是错误的(3)宏定义只是用来替换字符串的。 不管字符串是什么数据类型,总之就是一句话,宏名替换字符串,宏名替换的一定是字符串,即使上述中的写成了。替换后的结果依然是。(4)#define命令定义的宏名范围是从定义命令开始直到源程序文件结束,而且定义在文件开头与函数之间。 如果要想提前结束宏定义的作用域,可以通过终止宏名的作用域(5)宏定义中可以出现已经定义的宏名,可以层层置换。 & & 若宏名中 出现一个被双引号括起来的字符串中时,将不会产生宏替换。 & &比如:#include &stdio.h&
/*宏定义在文件头和函数之间*/
#define R 3.0
#define PI 3.1415926
#define L 2*PI*R
//出现了前面已经定义的PI和R
#define S PI*R*R
//出现了前面已经定义的PI和
当L和S在“”之内时将不会与宏定义产生联系,即不会发生替换
当L和S不在“”之内时,L将被替换成 2*PI*R,S将被替换成 PI*R*R
printf("L=%7.2f\nS=%7.2f\n",L,S);
} & 最后需要注意的是: 宏定义是专用于预处理的一个名词,它的作用就是替换,不分配空间 二:带参数的宏定义 &一般格式: & & & &#define &宏名(参数表) & 字符串 & 带参数的宏定义并不仅仅是宏名代换字符串,还要进行参数的替换,类似于函数的调用 &比如:#define S(a,b) a*barea=S(3,2); &S为宏名,和为形参,程序中调用(,),把实参和分别替换形参和,所以宏展开是 &比如:#include &stdio.h&
/*宏定义在文件头和函数之间*/
#define S(a,b) a*b
//需要注意的是S和()之间不能有空格
area=S(2,3);//传递给宏S(a,b),然后替换为a*b
printf("area=%d\n",area);
} ()上述程序中的参数传递应该很好理解,但是如果把程序改动一下,让实参的值变成大家肯定会认为是,但是真的是吗? 我们看一下:#include &stdio.h&
/*宏定义在文件头和函数之间*/
#define S(a,b) a*b
//需要注意的是S和()之间不能有空格
area=S(2+3,3+4);
printf("area=%d\n",area);
} &竟然是,并不是我们想象中的,怎么回事呢实际上S(2+3,3+4)传递过去后,它的红替换是 area=2+3*3+4,这下大家明白了吧。还是一句话,宏定义只是用来替换的,完完全全的原样的替换。那要怎么解决这个问题呢?很简单,在宏定义的时候加上一个括号就可以了,看程序:#include &stdio.h&
/*宏定义在文件头和函数之间*/
#define S(a,b) (a)*(b)
//需要注意的是S和()之间不能有空格
area=S(2+3,3+4);//传递给宏S(a,b),然后替换为a*b
printf("area=%d\n",area);
}(2)宏定义的宏调用与函数调用的区别 & 在学习了带参数的宏定义后,是不是觉得这个调用与函数的调用很相似,但是它们完全是不通的两个概念: & 函数调用时,先求出实参表达式的值,再将该值传递个形参,而带参数的宏调用只是进行替换,简单的字符替换 & 函数调用是在程序运行时处理,分配给形参临时内存单元,而宏展开则在编译时进行的,展开的时并不给形参分配内存单元,不进行值传递,也没有返回值本文出自 “” 博客,请务必保留此出处
了这篇文章
类别:┆阅读(0)┆评论(0)博客访问: 1888322
博文数量: 400
博客积分: 10227
博客等级: 上将
技术积分: 8401
注册时间:
认证徽章:
非淡泊无以明志,非宁静无以致远
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: C/C++
C程序的源代码中可包括各种编译指令,这些指令称为预处理命令。虽然它们实际上不是C语言的一部分,但却扩展了C程序设计的环境。本节将介绍如何应用预处理程序和注释简化程序开发过程,并提高程序的可读性。ANSI标准定义的C语言预处理程序包括下列命令:
#define,#error,#include,#if,#else,#elif,#endif,#ifdef,#ifndef,#undef,#line,#pragma等。非常明显,所有预处理命令均以符号#开头,下面分别加以介绍。
一 #define
命令#define定义了一个标识符及一个串。在源程序中每次遇到该标识符时,均以定义的串代换它。ANSI标准将标识符定义为宏名,将替换过程称为宏替换。命令的一般形式为:
#define identifier string
1该语句没有分号。在标识符和串之间可以有任意个空格,串一旦开始,仅由一新行结束。
2宏名定义后,即可成为其它宏名定义中的一部分。
3 宏替换仅仅是以文本串代替宏标识符,前提是宏标识符必须独立的识别出来,否则不进行替换。例如:
#define XYZ this is a tes
使用宏printf("XYZ");//该段不打印"this is a test"而打印"XYZ"。因为预编译器识别出的是"XYZ"
4如果串长于一行,可以在该行末尾用一反斜杠' \'续行。
#defineLONG_STRING"this is a very long\string that is used as an example"
5 C语言程序普遍使用大写字母定义标识符。
6 用宏代换代替实在的函数的一大好处是宏替换增加了代码的速度,因为不存在函数调用的开销。但增加速度也有代价:由于重复编码而增加了程序长度。
命令#error强迫编译程序停止编译,主要用于程序调试。
#error指令使预处理器发出一条错误消息,该消息包含指令中的文本.这条指令的目的就是在程序崩溃之前能够给出一定的信息。
三 #include
命令#i nclude使编译程序将另一源文件嵌入带有#include的源文件,被读入的源文件必须用双引号或尖括号括起来。例如:
#include"stdio.h"或者#include
这两行代码均使用C编译程序读入并编译用于处理磁盘文件库的子程序。
将文件嵌入#i nclude命令中的文件内是可行的,这种方式称为嵌套的嵌入文件,嵌套层次依赖于具体实现。
如果显式路径名为文件标识符的一部分,则仅在那些子目录中搜索被嵌入文件。否则,如果文件名用双引号括起来,则首先检索当前工作目录。如果未发现文件,则在命令行中说明的所有目录中搜索。如果仍未发现文件,则搜索实现时定义的标准目录。
如果没有显式路径名且文件名被尖括号括起来,则首先在编译命令行中的目录内检索。如果文件没找到,则检索标准目录,不检索当前工作目录。
四 条件编译命令
有几个命令可对程序源代码的各部分有选择地进行编译,该过程称为条件编译。商业软件公司广泛应用条件编译来提供和维护某一程序的许多顾客版本。
#if、#else,#elif及#endif
#if的一般含义是如果#if后面的常量表达式为true,则编译它与#endif之间的代码,否则跳过这些代码。命令#endif标识一个#if块的结束。
#if constant-expression
statement sequence
#define MAX 91
int main()
#if MAX > 99
&&&&&& cout<<"MAX is bigger than 99"<<
#elif MAX > 90
&&&&&& cout<<"MAX is bigger than 90"<<
&&&&&& cout<<"MAX is smaller than 90"<<
&&&&&& return 0;
跟在#if后面的表达式在编译时求值,因此它必须仅含常量及已定义过的标识符,不可使用变量。表达式不许含有操作符sizeof(sizeof也是编译时求值)。
#else命令的功能有点象C语言中的else;#else建立另一选择(在#if失败的情况下)。注意,#else属于#if块。
#elif命令意义与ELSE IF 相同,它形成一个if else-if阶梯状语句,可进行多种编译选择。#elif 后跟一个常量表达式。如果表达式为true,则编译其后的代码块,不对其它#elif表达式进行测试。否则,顺序测试下一块。
#if expression
statement sequence
#elif expression1
statement sequence
在嵌套的条件编译中#endif、#else或#elif与最近#if或#elif匹配。
# ifdef 和# ifndef
条件编译的另一种方法是用#ifdef与#ifndef命令,它们分别表示"如果有定义"及"如果无定义"。# ifdef的一般形式是:
# ifdef macroname
statement sequence
#ifdef与#ifndef可以用于#if、#else,#elif语句中,但必须与一个#endif。
#define MAX 91
int main()
#ifdef MAX
&&&&&& cout<<"hello,MAX!"<<
&&&&&& cout<<"where is MAX?"<<
#ifndef LEO
&&&&&& cout<<"LEO is not defined"<<
&&&&&& return 0;
命令#undef 取消其后那个前面已定义过有宏名定义。一般形式为:
#undef macroname
命令#line改变__LINE__与__FILE__的内容,它们是在编译程序中预先定义的标识符。命令的基本形式如下:
#line number["filename"]
其中的数字为任何正整数,可选的文件名为任意有效文件标识符。行号为源程序中当前行号,文件名为源文件的名字。命令#line主要用于调试及其它特殊应用。注意:在#line后面的数字标识从下一行开始的数字标识。
#line 100 "jia"
&&&&&& cout<<"#line change line and filename!"<< //line 100
&&&&&& cout<<__LINE__<< //101
&&&&&& cout<<__FILE__<< //jia
五 #pragma命令#pragma 为实现时定义的命令,它允许向编译程序传送各种指令。
#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。其格式一般为: #Pragma Para1 message 参数。
&Message 参数能够在编译信息输出窗口中输出相应的信息,这对于源代码信息的控制是非常重要的。其使用方法为:#pragma message(“消息文本”)当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。当我们在程序中定义了许多宏来控制源代码版本的时候,我们自己有可能都会忘记有没有正确的设置这些宏,此时我们可以用这条指令在编译的时候就进行检查。假设我们希望判断自己有没有在源代码的什么地方定义了_X86这个宏可以用下面的方法#ifdef _X86#pragma message(“_X86 macro activated!”)#endif当我们定义了_X86这个宏以后,应用程序在编译时就会在编译输出窗口里显示“_X86 macro activated!”。我们就不会因为不记得自己定义的一些特定的宏而抓耳挠腮了。2 &code_seg 参数。
格式如:#pragma code_seg( ["section-name"[,"section-class"] ] )它能够设置程序中函数代码存放的代码段,当我们开发驱动程序的时候就会使用到它。3 #pragma once (比较常用)只要在头文件的最开始加入这条指令就能够保证头文件被编译一次。这条指令实际上在VC6中就已经有了,但是考虑到兼容性并没有太多的使用它。4 #pragma hdrstop
表示预编译头文件到此为止,后面的头文件不进行预编译。BCB可以预编译头文件以加快链接的速度,但如果所有头文件都进行预编译又可能占太多磁盘空间,所以使用这个选项排除一些头文件。有时单元之间有依赖关系,比如单元A依赖单元B,所以单元B要先于单元A编译。你可以用#pragma startup指定编译优先级,如果使用了#pragma package(smart_init) ,BCB就会根据优先级的大小先后编译。5 #pragma resource "*.dfm"
表示把*.dfm文件中的资源加入工程。*.dfm中包括窗体外观的定义。6 #pragma warning( disable : 4507 34; once : 4385; error : 164 )
等价于:#pragma warning(disable:4507 34) /* 不显示4507和34号警告信息。如果编译时总是出现4507号警告和34号警告,&&而认为肯定不会有错误,可以使用这条指令。*/#pragma warning(once:4385) // 4385号警告信息仅报告一次#pragma warning(error:164) // 把164号警告信息作为一个错误。同时这个pragma warning 也支持如下格式:#pragma warning( push [ ,n ] )#pragma warning( pop )这里n代表一个警告等级(1---4)。#pragma warning( push )保存所有警告信息的现有的警告状态。#pragma warning( push, n)保存所有警告信息的现有的警告状态,并且把全局警告等级设定为n。#pragma warning( pop )向栈中弹出最后一个警告信息,在入栈和出栈之间所作的一切改动取消。例如:#pragma warning( push )#pragma warning( disable : 4705 )#pragma warning( disable : 4706 )#pragma warning( disable : 4707 )//.......#pragma warning( pop )在这段代码的最后,重新保存所有的警告信息(包括4705,4706和4707)。7 pragma comment(...)该指令将一个注释记录放入一个对象文件或可执行文件中。常用的lib关键字,可以帮我们连入一个库文件。 8 progma pack(n)
指定结构体对齐方式。#pragma pack(n)来设定变量以n字节对齐方式。
n 字节对齐就是说变量存放的起始地址的偏移量有两种情况:
第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式,
第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。
结构的总大小也有个约束条件,分下面两种情况:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数; 否则必须为n的倍数。
下面举例说明其用法。
#pragma pack(push) //保存对齐状态#pragma pack(4)//设定为4字节对齐struct test{char m1;double m4;int m3;};#pragma pack(pop)//恢复对齐状态为测试该功能,可以使用sizeof()测试结构体的长度!
阅读(13089) | 评论(1) | 转发(10) |
相关热门文章
给主人留下些什么吧!~~
( ⊙o⊙ )哇~第一次知道还有#error呀
请登录后评论。& 鸡啄米:C++编程入门系列之二十四(C++程序设计必知:多文件结构和编译预处理命令)
鸡啄米:C++编程入门系列之二十四(C++程序设计必知:多文件结构和编译预处理命令)
&&& && 鸡啄米上一讲给大家讲了,今天给大家讲下编程入门知识--多文件结构和编译预处理命令。&&&&&& 一.C++程序的多文件结构&&&&&& 之前鸡啄米给大家看了很多比较完整的C++程序的例子,大家可能发现了,它们的结构基本上可以分为三个部分:类的声明、类的成员函数的实现和主函数。因为代码比较少,所以可以把它们写在一个文件中,但是我们实际进行软件开发时,程序会比较复杂,代码量比较大,&&&&&& 一个程序按结构至少可以划分为三个文件:类的声明文件(*.h文件)、类的实现文件(*.cpp文件)和主函数文件(使用到类的文件),如果程序更复杂,我们会为每个类单独建一个声明文件和一个实现文件。这样我们要修改某个类时就直接找到它的文件修改即可,不需要其他的文件改动。&&&&& &鸡啄米在时有个时钟类的例子,现在鸡啄米给大家看下将那个程序按照上面说的结构分到三个文件里:&&&&& &// 文件1:Clock类的声明,可以起名为Clock.h&&&&&& #include &iostream&&&&&&&&&&&&&&class Clock //时钟类声明&&&&&&&{&&&&&&&public: //外部接口&&&&&&&&&&&&&&&&&& Clock();&&&&&&&&&&&&&&&&&& void SetTime(int NewH, int NewM, int NewS);&& //三个形参均具有函数原型作用域&&&&&&&&&&&&&&&&&& void ShowTime();&&&&&&&&&&&&&&&&& ~Clock(){}&&&&&&&private: //私有数据成员&&&&&&&&&&&&&&&&&& int Hour,Minute,S&&&&&&&};&&&&& &// 文件2:Clock类的实现,可以起名为Clock.cpp&&&&&&&#include &Clock.h&&&&&&& //时钟类成员函数实现&&&&&&&Clock::Clock() //构造函数&&&&&&&{ &&&&&&&&&&&&&&&&& Hour=0;&&&&&&&&&&&&&&&&& Minute=0;&&&&&&&&&&&&&&&&& Second=0;&&&&&& }&&&&&&&void Clock::SetTime(int NewH,int NewM,int NewS)&&&&&& { &&&&&&&&&&&&&&&&& Hour=NewH;&&&&&&&&&&&&&&&&& Minute=NewM;&&&&&&&&&&&&&&&&& Second=NewS;&&&&&& }&&&&&& void Clock::ShowTime()&&&&&&&{ &&&&&&&&&&&&&&&& cout&&Hour&&&:&&&Minute&&&:&&&Second&&&&&&&& }&&&&& // 文件3:主函数,可以起名为main.cpp&&&&&& #include &Clock.h&&&&&&&&//声明全局对象g_Clock,具有文件作用域,静态生存期&&&&&& Clock g_C&&&&&& int main() //主函数&&&&&& {&&&&&&&&&&&&&&&&& cout&&&文件作用域的时钟类对象:&&& &&&&&&&&&&&&&&&&& //引用具有文件作用域的对象:&&&&&&&&&&&&&&&&& g_Clock.ShowTime();&&&&&&&&&&&&&&&&& g_Clock.SetTime(10,20,30);&&&&&&&&&&&&&&&&&& Clock myClock(g_Clock);&&& //声明具有块作用域的对象myClock,并通过默认拷贝构造函数用g_Clock初始化myClock&&&&&&&&&&&&&&&&& cout&&&块作用域的时钟类对象:&&& &&&&&&&&&&&&&&&&& myClock.ShowTime(); //引用具有块作用域的对象&&&&&&&&&&&&&&&&& return 0;&&&&&& }&&&&&& 在vs2010中如何生成这三个文件呢?我们可以点菜单中Project-&Add Class,在弹出的对话框中选择c++ class,然后由弹出个对话框,在class name处填上类名点finish就可以了,这样.h文件和.cpp文件会自动生成,我们也可以点Project-&Add New Item,在弹出的对话框中选择Header File(.h)或C++ File(.cpp)来生成.h文件或.cpp文件。&&&&&&Clock.cpp和main.cpp都使用#include &Clock.h&把类Clock的头文件Clock.h包含进来。#include指令的作用就是将#include后面的文件嵌入到当前源文件该点处,被嵌入的文件可以是.h文件也可以是.cpp文件。如果不包含Clock.h,Clock.cpp和main.cpp就不知道Clock类的声明形式,就无法使用此类,所以所有使用此类的文件都应该包含声明它的头文件。关于#include指令下面鸡啄米会讲。&&&&&& 上面的程序在编译时,由Clock.cpp和Clock.h编译生成Clock.obj,由main.cpp和Clock.h编译生成main.obj,然后就是链接过程,Clock.obj和main.obj链接生成main.exe可执行文件。如果我们只修改了类的实现文件,那么只需重新编译Clock.cpp并链接就可以,别的文件不用管,这样就提高了效率。在Windows系统中的C++程序用工程来管理多文件结构,而Unix系统一般用make工具管理,如果大家从事Unix系统软件开发,就需要自己写make文件。&&&&&& 二.编译预处理程序&&&&& &编译器在编译源程序以前,要由预处理程序对源程序文件进行预处理。预处理程序提供了一些编译预处理指令和预处理操作符。预处理指令都要由&#&开头,每个预处理指令必须单独占一行,而且不能用分号结束,可以出现在程序文件中的任何位置。&&&&&& 1.#include指令&&&&&&&#include指令也叫文件包含指令,用来将另一个源文件的内容嵌入到当前源文件该点处。其实我们一般就用此指令来包含头文件。#include指令有两种写法:&&&&&& #include &文件名&&&&&&& 使用这种写法时,会在C++安装目录的include子目录下寻找&&中标明的文件,通常叫做按标准方式搜索。&&&&&& #include &文件名&&&&&&&&使用这种写法时,会先在当前目录也就是当前工程的目录中寻找&&中标明的文件,若没有找到,则按标准方式搜索。&&&&&&&2.#define和#undef指令&&&&&& 如果你学过C语言,就会知道用#define可以定义符号常量,比如,#define PI 3.14 这条指令定义了一个符号常量PI,它的值是3.14。C++也可以这样定义符号常量,但一般更常用的是在声明时用const关键字修饰。C语言还用#define定义参数宏,来实现简单的函数运算,比如,#define add(x,y) (x+y) 这条指令说明如果我们用到add(1,2)则预处理后就会用(1+2)代替,C++中一般用内联函数来实现。&&&&&& #undef用来删除由#define定义的宏,使其不再起作用。&&&&&& 3.条件编译指令&&&&&&&用条件编译指令可以实现某些代码在满足一定条件时才会参与编译,这样我们可以利用条件编译指令将同一个程序在不同的编译条件下生成不同的目标代码。例如,我们可以在调试程序时加入一些调试语句,用条件编译指令控制只有在debug模式下这些调试语句才参与编译,而在release模式下不参与编译。&&&&&& 条件编译指令有5中形式:&&&&&&&a.第一种形式:&&&&&&&#if& 常量表达式&&&&&&&& &&&&&&&&&&&&&& &程序正文&&&&&&& //当& 常量表达式&非零时本程序段参与编译&&&&& &#endif&&&&&& b.第二种形式:&&&&& &#if&& 常量表达式&&&&&&&&&&&&&&& &程序正文1&&&&&& //当& 常量表达式&非零时本程序段参与编译&&&&&& #else&&&&&&&&&&&&&&& &程序正文2&&&&&& //当& 常量表达式&为零时本程序段参与编译&&&&&& #endif&&&&&& c.第三种形式:&&&&&&&#if 常量表达式1&&&&&&&&&&&&&&& &程序正文1&&&&&&& //当& 常量表达式1&非零时本程序段参与编译&&&&& &elif 常量表达式2&&&&&&&&&&&&&& &程序正文2&&&&&&& //当&常量表达式1&为零、& 常量表达式2&非零时本程序段参与编译&&&&& & ...&&&& & elif 常量表达式n&&&&&&&&&&&&&& &程序正文n&&&&&&& //当&常量表达式1&、...、&常量表达式n-1&均为零、& 常量表达式n&非零时本程序段参与编译&&& & &#else&&&&&&&&&&&&&&& 程序正文n+1&&&&& //其他情况下本程序段参与编译&&&&& &#endif&&&&& &d.第四种形式:&&&& & #ifdef 标识符&&&&&&&&&&&&&&& 程序段1&&&&& &#else&&&&&&&&&&&&&& &程序段2&&&&& &#endif&&&&& &如果&标识符&经#defined定义过,且未经undef删除,则编译程序段1,否则编译程序段2。&&&&&& e.第五种形式:&&&&& &#ifndef 标识符&&&&&&&&&&&&&&&&& 程序段1&&&&& &#else&&&&&&&&&&&&&&&&&&程序段2&&&&& &#endif&&&& &&如果&标识符&未被定义过,则编译程序段1,否则编译程序段2。&&&&& &4.define操作符&&&&& &define是预处理操作符,不是指令,所以不能用#开头。使用形式为:define(标识符)。如果括号里的标识符用#define定义过,并且没有用#undef删除,则define(标识符)为非0,否则为0。可以这样使用:&&&&&& &#if !define(HEAD_H)&&&&&& &#define HEAD_H&&&&&& 我们在包含头文件时,有时多次重复包含同一个头文件,比如下面这种情况:&&&&&&& // main.cpp文件&&&&&& #include &file1.h&&&&&&& #include &file2.h&&&&&&& int main()&&&&&& {&&&&&&&&&&& & &&&&&&& }&&&&&& // file1.h文件&&&&&& #include &head.h&&&&&&& &&&&&&&& // file2.h文件&&&&&& #include &head.h&&&&&&& &&&&&&&& // head.h文件&&&&&& &...&&&&&& class A&&&&&& {&&&&&&&&&&&& &...&&&&&&&}&&&& & ...&&&&&& main.cpp包含了file1.h文件,file1.h又包含了head.h文件,main.cpp还包含了file2.h文件,file2.h也包含了head.h文件,那么main.cpp就包含了两次head.h文件,在编译时就会报错,说head.h中的类A重复定义了。这时我们可以在被重复包含的文件head.h中使用条件编译指令,用一个唯一的标识符来标识head.h文件是否已经编译过,如果已经编译过则不会重复编译了。鸡啄米给大家改写下上面的head.h文件:&&&&& &// head.h文件&&&&& &#ifndef HEAD_H&&&& & #define HEAD_H&&&& & ...&&&&& &class A&&&&&& {&&&&&&&&& & ...&&&&& &}&&&&&& ...&&&&& &#endif&&&&&& 在这个改好的head.h文件中,上来会先判断HEAD_H是否被定义过,如果没有被定义过,则head.h文件还没参与过编译,就编译此文件中的源代码,同时定义HEAD_H,标记head.h文件已经参与过编译。如果HEAD_H已经被定义过,则说明此文件已经参与过编译,编译器会跳过本文件左右内容编译其他部分,类A也不会有重复定义的错误了。&&&&&&&鸡啄米今天给大家讲的内容比较多,大家慢慢看吧,其实并不难。编程入门学习中难免有问题,如果有什么问题大家可以在鸡啄米博客上留言讨论,谢谢大家。&
除非特别注明,文章均为原创
转载请标明本文地址:
作者:鸡啄米
&&( 22:16:32)&&( 21:29:34)&&( 20:24:37)&&( 20:52:10)&&( 20:41:52)&&( 22:56:59)&&( 22:11:31)&&( 20:29:27)&&( 23:16:46)&&( 22:9:51)
这个没有学过,难吗?鸡啄米 于
23:31:47 回复用心学就没什么难的
那只猫咪好萌哦!!!鸡啄米 于
23:33:17 回复呵呵,可爱吧
好高深的C+,我上学只学了tuboC鸡啄米 于
23:38:42 回复大学时候我也是学的tubur c
代码的种种,各种的头大鸡啄米 于
23:41:08 回复看看那可爱的小猫放松放松,呵呵
都是编程一看就头晕了
后面的还有吗?有点贪心了,呵呵鸡啄米 于
09:20:27 回复关于多文件结构和编译预处理命令就讲这么多了,更多C++的知识可以看看鸡啄米的这个教程的其他文章。欢迎常来交流。
我们现在正在学习C++,可我们老师总用方言讲,听的我郁闷啊,简直是折磨,来你这里学习学习鸡啄米 于
20:56:48 回复呵呵,我也有过这样的老师,欢迎常来啊
还是讲得挺详细的,非常感谢!
麻烦加我一下QQ
以前学的c,现在学c++还有点转不过来呢
对于预编译不是很理解 感觉挺难的 平时写代码也没用到预编译 难啊
您好 请问vs2010中targetver.h和stdafx.cpp这两个自动生成的文件有什么作用? 谢谢
给博主赞一个
要是贴几个
条件编译指令
示例程序就好了
初学用C++Builder编程,在类声明文件中要有#ifdef #define #endif这样的形式保存后重新打开,.cpp文件才会和.h文件能够在同一组标签页下,只知道能这样用,但看到这里其实才明白一点为什么。猫咪好萌!
完全随机文章}

我要回帖

更多关于 c语言编译预处理 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信