当前位置:首页 » 编程软件 » 头文件预编译指令

头文件预编译指令

发布时间: 2022-05-29 12:00:30

1. 在C++语言中,包含头文件的预处理命令以什么开头


预处理指令
总是占用源代码中的单独一行,并且
总是以
#
字符和预处理指令名称开头
。#
字符的前面以及
#
字符与指令名称之间可以出现空白符。

包含
#define

#undef
、#if、#elif、#else、
#endif

#line
指令的源代码行可以用
单行注释
结束。在包含预处理指令的源行上不允许使用带
分隔符
的注释(/*
*/
样式的注释)。

预处理指令既不是标记,也不是
C#
句法文法的组成部分。但是,可以用预处理指令包含或排除标记序列,并且可以以这种方式影响
C#
程序的含义。

2. 关于c语言头文件编译和运行的问题

1、只要在程序开头加入#include<头文件名>,在编译过程当中,头文件自动会被添加到源文件当中一起进行编译。
2、编译,编译程序读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,再由汇编程序转换为机器语言,并且按照操作系统对可执行文件格式的要求链接生成可执行程序。
C源程序头文件-->预编译处理(cpp)-->编译程序本身-->优化程序-->汇编程序-->链接程序-->可执行文件。

3. C++ 中stdafx.h是什么意思

C++中stdafx.h的英文全称为:Standard Application Fram Extend,中文名为:头文件预编译。

stdafx.h在C++中起到的作用是:把C++工程中使用的MFC头文件预先编译,以后该工程编译时,直接使用预编译的结果,这样可以加快编译速度。

C++编译器通过一个头文件stdafx.h来使用预编译头文件。stdafx.h这个头文件名可以在project的编译设置里指定。

编译器默认所有在指令"stdafx.h"前的代码都是预编译,它跳过 "stdafx. h"指令,使用projectname.pch编译这条指令之后的代码。

(3)头文件预编译指令扩展阅读

Windows和MFC的include文件都非常大,即使有一个快速的处理程序,编译程序也要花费相当长的时间来完成工作。

由于每个.CPP文件都包含相同的include文件,为每个.CPP文件都重复处理这些文件就显得很傻了。为避免这种浪费,AppWizard和VisualC++编译程序一起进行工作,如下所示:

1、AppWizard建立了文件stdafx.h,该文件包含了所有当前工程文件需要MFCinclude 文件。且这一文件可以随被选择的选项而变化。

2、AppWizard然后就建立stdafx.cpp。这个文件通常都是一样的。

3、然后AppWizard就建立起工程文件,这样第一个被编译的文件就是stdafx.cpp。

4当VisualC++编译stdafx.cpp文件时,它将结果保存在一个名为stdafx.pch的文件里。(扩展名pch表示预编译头文件。)

5、当VisualC++编译随后的每个.cpp文件时,它阅读并使用它刚生成的.pch文件。VisualC++不再分析Windowsinclude文件,除非你又编缉了stdafx.cpp或stdafx.h。

4. 头文件中的 ifndef/define/endif 干什么用可以用什么编译命令

这个是预编译的命令,是用来防止头文件重复包含的。大部分系统的头文件重复包含是没有问题的,但是有时自己编写的头文件重复包含会出现变量或者是函数或者类的重定义,这样编译不会通过。

5. 预处理指令#pragma db code是什么意思

一、作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma指令对每个编译器给出了一个方法,在保持与C和 C++语言完全兼容的情况下,给出主机或操作系统专有的特征。依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。

二、常用的pragma指令的详细解释。
1.#pragma once。保证所在文件只会被包含一次,它是基于磁盘文件的,而#ifndef则是基于宏的。
2.#pragma warning。允许有选择性的修改编译器的警告消息的行为。有如下用法:
#pragma warning(disable:4507 34; once:4385; error:164) 等价于:
#pragma warning(disable:4507 34) // 不显示4507和34号警告信息
#pragma warning(once:4385) // 4385号警告信息仅报告一次
#pragma warning(error:164) // 把164号警告信息作为一个错误
#pragma warning(default:176) // 重置编译器的176号警告行为到默认状态
同时这个pragma warning也支持如下格式,其中n代表一个警告等级(1---4):
#pragma warning(push) // 保存所有警告信息的现有的警告状态
#pragma warning(push,n) // 保存所有警告信息的现有的警告状态,并设置全局报警级别为n
#pragma warning(pop) // 恢丛 鹊木 孀刺 趐ush和pop之间所做的一切改动将取消
例如:
#pragma warning(push)
#pragma warning(disable:4705)
#pragma warning(disable:4706)
#pragma warning(disable:4707)
#pragma warning(pop)
在这段代码后,恢复所有的警告信息(包括4705,4706和4707)。
3.#pragma hdrstop。表示预编译头文件到此为止,后面的头文件不进行预编译。BCB可以预编译头文件以 加快链接的速度,但如果所有头文件都进行预编译又可能占太多磁盘空间,所以使用这个选项排除一些头文 件。
4.#pragma message。在标准输出设备中输出指定文本信息而不结束程序运行。用法如下:
#pragma message("消息文本")。当编译器遇到这条指令时就在编译输出窗口中将“消息文本”打印出来。
5.#pragma data_seg。一般用于DLL中,它能够设置程序中的初始化变量在obj文件中所在的数据段。如果未指定参数,初始化变量将放置在默认数据段.data中,有如下用法:
#pragma data_seg("Shared") // 定义了数据段"Shared",其中有两个变量a和b
int a = 0; // 存储在数据段"Shared"中
int b; // 存储在数据段".bss"中,因为没有初始化
#pragma data_seg() // 表示数据段"Shared"结束,该行代码为可选的
对变量进行专门的初始化是很重要的,否则编译器将把它们放在普通的未初始化数据段中而不是放在shared中。如上述的变量b其实是放在了未初始化数据段.bss中。
#pragma data_seg("Shared")
int j = 0; // 存储在数据段"Shared"中
#pragma data_seg(push, stack1, "Shared2") //定义数据段Shared2,并将该记录赋予别名stack1,然后放入内部编译器栈中
int l = 0; // 存储在数据段"Shared2"中
#pragma data_seg(pop, stack1) // 从内部编译器栈中弹出记录,直到弹出stack1,如果没有stack1,则不做任何操作
int m = 0; // 存储在数据段"Shared"中,如果没有上述pop段,则该变量将储在数据段"Shared2"中
6.#pragma code_seg。它能够设置程序中的函数在obj文件中所在的代码段。如果未指定参数,函数将放置在默认代码段.text中,有如下用法:
void func1() { // 默认存储在代码段.text中
}
#pragma code_seg(".my_data1")
void func2() { // 存储在代码段.my_data1中
}
#pragma code_seg(push, r1, ".my_data2")
void func3() { // 存储在代码段.my_data2中
}
#pragma code_seg(pop, r1)
void func4() { // 存储在代码段.my_data1中
}
7.#pragma pack。用来改变编译器的字节对齐方式。常规用法为:
#pragma pack(n) //将编译器的字节对齐方式设为n,n的取值一般为1、2、4、8、16,一般默认为8
#pragma pack(show) //以警告信息的方式将当前的字节对齐方式输出
#pragma pack(push) //将当前的字节对齐方式放入到内部编译器栈中
#pragma pack(push,4) //将字节对齐方式4放入到内部编译器栈中,并将当前的内存对齐方式设置为4
#pragma pack(pop) //将内部编译器栈顶的记录弹出,并将其作为当前的内存对齐方式
#pragma pack(pop,4) //将内部编译器栈顶的记录弹出,并将4作为当前的内存对齐方式
#pragma pack(pop,r1) //r1为自定义的标识符,将内部编译器中的记录弹出,直到弹出r1,并将r1的值作为当前的内存对齐方式;如果r1不存在,当不做任何操作
8.#pragma comment。将一个注释记录放置到对象文件或可执行文件中。
其格式为:#pragma comment( comment-type [,"commentstring"] )。其中,comment-type是一个预定义的标识符,指定注释的类型,应该是compiler,exestr,lib,linker,user之一。
compiler:放置编译器的版本或者名字到一个对象文件,该选项是被linker忽略的。
exestr:在以后的版本将被取消。
lib:放置一个库搜索记录到对象文件中,这个类型应该与commentstring(指定Linker要搜索的lib的名称和路径)所指定的库类型一致。在对象文件中,库的名字跟在默认搜索记录后面;linker搜索这个这个库就像你在命令行输入这个命令一样。你可以在一个源文件中设置多个库搜索记录,它们在obj文件中出现的顺序与在源文件中出现的顺序一样。
如果默认库和附加库的次序是需要区别的,使用/Zl编译开关可防止默认库放到object模块中。
linker:指定一个连接选项,这样就不用在命令行输入或者在开发环境中设置了。只有下面的linker选项能被传给Linker:
/DEFAULTLIB
/EXPORT
/INCLUDE
/MANIFESTDEPENDENCY
/MERGE
/SECTION
(1)/DEFAULTLIB:library
/DEFAULTLIB选项将一个library添加到LINK在解析引用时搜索的库列表。用/DEFAULTLIB指定的库在命令行上指定的库之后和obj文件中指定的默认库之前被搜索。
忽略所有默认库(/NODEFAULTLIB)选项重写/DEFAULTLIB:library。如果在两者中指定了相同的library名称,忽略库(/NODEFAULTLIB:library)选项将重写/DEFAULTLIB:library。
(2)/EXPORT:entryname[,@ordinal[,NONAME]][,DATA]
使用该选项,可以从程序导出函数以便其他程序可以调用该函数,也可以导出数据。通常在DLL中定义导出。
entryname是调用程序要使用的函数或数据项的名称。ordinal为导出表的索引,取值范围在1至65535;如果没有指定ordinal,则LINK将分配一个。NONAME关键字只将函数导出为序号,没有entryname。DATA 关键字指定导出项为数据项。客户程序中的数据项必须用extern __declspec(dllimport)来声明。
有三种导出定义的方法,按照建议的使用顺序依次为:
源代码中的__declspec(dllexport)
.def文件中的EXPORTS语句
LINK命令中的/EXPORT规范
所有这三种方法可以用在同一个程序中。LINK在生成包含导出的程序时还要创建导入库,除非在生成过程中使用了.exp 文件。
LINK使用标识符的修饰形式。编译器在创建obj文件时修饰标识符。如果entryname以其未修饰的形式指定给链接器(与其在源代码中一样),则LINK将试图匹配该名称。如果无法找到唯一的匹配名称,则LINK发出错误信息。当需要将标识符指定给链接器时,请使用Dumpbin工具获取该标识符的修饰名形式。
(3)/INCLUDE:symbol
/INCLUDE选项通知链接器将指定的符号添加到符号表。若要指定多个符号,请在符号名称之间键入逗号(,)、分号(;)或空格。在命令行上,对每个符号需指定一次/INCLUDE:symbol。
链接器通过将包含符号定义的对象添加到程序来解析symbol。该功能对于添加不会链接到程序的库对象非常有用。
用该选项所指定的符号将覆盖通过/OPT:REF对该符号进行的移除操作。
(4)/MANIFESTDEPENDENCY:manifest_dependency
/MANIFESTDEPENDENCY允许你指定位于manifest文件的段的属性。/MANIFESTDEPENDENCY信息可以通过下面两种方式传递给LINK:
直接在命令行运行/MANIFESTDEPENDENCY
通过#pragma comment
(5)/MERGE:from=to
/MERGE选项将第一个段(from)与第二个段(to)进行联合,并将联合后的段命名为to的名称。
如果第二个段不存在,LINK将段(from)重命名为to的名称。
/MERGE选项对于创建VxDs和重写编译器生成的段名非常有用。
(6)/SECTION:name,[[!]{DEKPRSW}][,ALIGN=#]
/SECTION选项用来改变段的属性,当指定段所在的obj文件编译的时候重写段的属性集。
可移植的可执行文件(PE)中的段(section)与新可执行文件(NE)中的节区(segment)或资源大致相同。
段(section)中包含代码或数据。与节区(segment)不同的是,段(section)是没有大小限制的连续内存块。有些段中的代码或数据是你的程序直接定义和使用的,而有些数据段是链接器和库管理器(lib.exe)创建的,并且包含了对操作系统来说很重要的信息。
/SECTION选项中的name是大小写敏感的。
不要使用以下名称,因为它们与标准名称会冲突,例如,.sdata是RISC平台使用的。
.arch
.bss
.data
.edata
.idata
.pdata
.rdata
.reloc
.rsrc
.sbss
.sdata
.srdata
.text
.xdata
为段指定一个或多个属性。属性不是大小写敏感的。对于一个段,你必须将希望它具有的属性都进行指定;如果某个属性未指定,则认为是不具备这个属性。如果你未指定R,W或E,则已存在的读,写或可执行状态将不发生改变。
要对某个属性取否定意义,只需要在属性前加感叹号(!)。
E:可执行的
R:可读取的
W:可写的
S:对于载入该段的镜像的所有进程是共享的
D:可废弃的
K:不可缓存
P:不可分页的
注意K和P是表示否定含义的。
PE文件中的段如果没有E,R或W属性集,则该段是无效的。
ALIGN=#选项让你为一个具体的段指定对齐值。
user:放置一个常规注释到一个对象文件中,该选项是被linker忽略的。
9.#pragma section。创建一个段。
其格式为:#pragma section( "section-name" [, attributes] )
section-name是必选项,用于指定段的名字。该名字不能与标准段的名字想冲突。可用/SECTION查看标准段的名称列表。
attributes是可选项,用于指定段的属性。可用属性如下,多个属性间用逗号(,)隔开:
read:可读取的
write:可写的
execute:可执行的
shared:对于载入该段的镜像的所有进程是共享的
nopage:不可分页的,主要用于Win32的设备驱动程序中
nocache:不可缓存的,主要用于Win32的设备驱动程序中
discard:可废弃的,主要用于Win32的设备驱动程序中
remove:非内存常驻的,仅用于虚拟设备驱动(VxD)中
如果未指定属性,默认属性为read和write。
在创建了段之后,还要使用__declspec(allocate)将代码或数据放入段中。
例如:
//pragma_section.cpp
#pragma section("mysec",read,write)
int j = 0;
__declspec(allocate("mysec"))
int i = 0;
int main(){}
该例中, 创建了段"mysec",设置了read,write属性。但是j没有放入到该段中,而是放入了默认的数据段中,因为它没有使用__declspec(allocate)进行声明;而i放入了该段中,因为使用__declspec(allocate)进行了声明。
10.#pragma push_macro与#pragma pop_macro。前者将指定的宏压入栈中,相当于暂时存储,以备以后使用;后者将栈顶的宏出栈,弹出的宏将覆盖当前名称相同的宏。例如:
#include
#define X 1
#define Y 2
int main() {
printf("%d",X);
printf("\n%d",Y);
#define Y 3 // C4005
#pragma push_macro("Y")
#pragma push_macro("X")
printf("\n%d",X);
#define X 2 // C4005
printf("\n%d",X);
#pragma pop_macro("X")
printf("\n%d",X);
#pragma pop_macro("Y")
printf("\n%d",Y);
}
输出结果:
1
2
1
2
1
3

6. 头文件预编译用什么

#号是官方定义的,用于和其他类型区别的,不用多考虑,你就看看我给你的链接看看官方的说法
条件编译符号#define ???
#if、#elif、#else 和 #endif 指令提供的条件编译功能是通过预处理表达式和条件编译符号来控制的。
conditional-symbol:(条件符号:)
除 true 和 false 外的任何标识符或关键字
条件编译符号有两种可能的状态:已定义的或未定义的。在源文件词法处理开始时,条件编译符号除非已由外部机制(如命令行编译器选项)显式定义,否则是未定义的。当处理 #define 指令时,在指令中指定的条件编译符号在那个源文件中成为已定义的。此后,该符号就一直保持已定义的状态,直到处理一条关于同一符号的 #undef 指令,或者到达源文件的结尾。这意味着一个源文件中的 #define 和 #undef 指令对同一程序中的其他源文件没有任何影响。
当在预处理表达式中引用时,已定义的条件编译符号具有布尔值 true,未定义的条件编译符号具有布尔值 false。不要求在预处理表达式中引用条件编译符号之前显式声明它们。相反,未声明的符号只是未定义的,因此具有值 false。
条件编译符号的命名空间与 C# 程序中的所有其他命名实体截然不同。只能在 #define 和 #undef 指令以及预处理表达式中引用条件编译符号。
1

7. 什么是预编译,何时需要预编译

预编译又称为预处理,是做些代码文本的替换工作

预编译又称为预处理,是做些代码文本的替换工作

处理#开头的指令,比如拷贝#include包含的文件代码,#define宏定义的替换,条件编译等

就是为编译做的预备工作的阶段

主要处理#开始的预编译指令

预编译指令指示了在程序正式编译前就由编译器进行的操作,可以放在程序中的任何位置。常见的预编译指令有:

(1)#include 指令

该指令指示编译器将xxx.xxx文件的全部内容插入此处。若用<>括起文件则在系统的INCLUDE目录中寻找文件,若用" "括起文件则在当前目录中寻找文件。一般来说,该文件是后缀名为"h"或"cpp"的头文件。

注意:<>不会在当前目录下搜索头文件,如果我们不用<>而用""把头文件名扩起,其意义为在先在当前目录下搜索头文件,再在系统默认目录下搜索。

(2)#define指令

该指令有三种用法:

第一种是定义标识,标识有效范围为整个程序,形如#define XXX,常与#if配合使用;

第二种是定义常数,如#define max 100,则max代表100(这种情况下使用const定义常数更好,原因见注1);

第三种是定义"函数",如#define get_max(a, b) ((a)>(b)?(a):(b)) 则以后使用get_max(x,y)就可以得到x和y中较大的数(这种方法存在一些弊病,见注2)。

第四种是定义"宏函数",如#define GEN_FUN(type) type max_##type(type a,type b){return a>b?a:b;} ,使用时,用GEN_FUN(int),则此处预编译后就变成了 max_int(int a,int b){return a>b?a:b;},以后就可以使用max_int(x,y)就可以得到x和y中较大的数.比第三种,增加了类型的说明。

(3)#if、#else和#endif指令

这些指令一般这样配合使用:

#if defined(标识) //如果定义了标识

要执行的指令

#else

要执行的指令

#endif

在头文件中为了避免重复调用(比如说两个头文件互相包含对方),常采用这样的结构:

#if !(defined XXX) //XXX为一个在你的程序中唯一的标识符,

//每个头文件的标识符都不应相同。

//起标识符的常见方法是若头文件名为"abc.h"

//则标识为"abc_h"

#define XXX

真正的内容,如函数声明之类

#endif

8. c++头文件中的开头代码是啥意思

if
!defined
xxx
#define
xxxx
这是预编译指令,是说,如果代码中没有定义xxx,则定义xxx,目的是,在引用文件时,防止重复定义
比如:在aaa.h中定义了AAA变量,
而在main.cpp
中#include
“AAA.h”,main.cpp也同时要使用fun.cpp.
并且在fun.cpp
中也#include“AAA.h”
那么如果没有预编译指令的话
两个文件都定义了AAA这个变量.那么就造成了AAA的多次定义。
/*****************************/
/***文件一***main.cpp***********/
#include
"AAA.h"
int
main()
.....
/**文件二*****AAA.h************/
const
int
AAA
=
123;
/**文件三*****fun.cpp**************/
#include
"AAA.h"
.....
这样,main文件包含了AAA变量的定义,由于main文件中会调用的fun.cpp,而fun.cpp文件包含了AAA.h也就是定义了AAA,
所以就会造成main文件定义了两次AAA变量。
如果使用了预编译指令,
则可以在定义了一次之后
不知道我说清楚了没有,清楚了就请加分吧
不再定义第二次
由于

9. C语言含有包含自定义头文件的程序怎么编译

1、只要在程序开头加入#include
“自定义头文件名”,在编译过程当中,头文件自动会被添加到源文件当中一起进行编译。
2、编译,编译程序读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,再由汇编程序转换为机器语言,并且按照操作系统对可执行文件格式的要求链接生成可执行程序。C源程序头文件-->预编译处理(cpp)-->编译程序本身-->优化程序-->汇编程序-->链接程序-->可执行文件。

热点内容
更改服务器地址有问题吗 发布:2024-05-22 02:17:58 浏览:41
宏定义的编译顺序 发布:2024-05-22 02:15:38 浏览:36
存储类的概念重要吗 发布:2024-05-22 02:14:43 浏览:201
axios文件上传 发布:2024-05-22 02:13:30 浏览:274
sql服务器如何调试 发布:2024-05-22 02:06:13 浏览:625
c语言编译库文件 发布:2024-05-22 01:33:46 浏览:563
调音里的压缩 发布:2024-05-22 01:33:39 浏览:569
android红外遥控 发布:2024-05-22 01:31:47 浏览:872
服务器分区如何分两个主机 发布:2024-05-22 01:30:02 浏览:412
什么软件可以查电脑配置牌子 发布:2024-05-22 01:19:54 浏览:373