预解决器标识#error的定义和经常使用 举个繁难例子
本文目录导航:
预解决器标识#error的定义和经常使用,举个繁难例子
配置:指令用于报告编译时失误信息的;假设预解决方面有失误,那么就会打印#error指令前面的文本内容。用法: #error文本举个例子:#ifdef XXX...#error XXX has been defined...#else...#endif这样,假设编译时发生失误,输入了XXX has been defined,标明宏XXX曾经被定义了
关于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。
由于预编译器识别出的是XYZ4假设串善于一行,可以在该行末尾用一反斜杠 \续行。
#defineLONG_STRINGthis is a very long\string that is used as an example5 C言语程序普遍经常使用大写字母定义标识符。
6 用宏代换替代真实的函数的一大好处是宏交流参与了代码的速度,由于不存在函数调用的开支。
但参与速度也有代价:由于重复编码而参与了程序长度。
二 #error命令#error强制编译程序中止编译,关键用于程序调试。
#error指令使预解决器收回一条失误信息,该信息蕴含指令中的文本.这条指令的目标就是在程序解体之前能够给出必定的信息。
三 #include命令#i nclude使编译程序将另一源文件嵌入带有#include的源文件,被读入的源文件必需用双引号或尖括号括起来。
例如:#includestdio.h或许#include<stdio.h>这两行代码均经常使用C编译程序读入并编译用于解决磁盘文件库的子程序。
将文件嵌入#i nclude命令中的文件内是可行的,这种方式称为嵌套的嵌入文件,嵌套档次依赖于详细成功。
假设显式门路名为文件标识符的一部分,则仅在那些子目录中搜查被嵌入文件。
否则,假设文件名用双引号括起来,则首先检索以后上班目录。
假设未发现文件,则在命令行中说明的一切目录中搜查。
假设仍未发现文件,则搜查成功时定义的规范目录。
假设没有显式门路名且文件名被尖括号括起来,则首先在编译命令行中的目录内检索。
假设文件没找到,则检索规范目录,不检索以后上班目录。
四 条件编译命令有几个命令可对程序源代码的各部分有选用地启动编译,该环节称为条件编译。
商业软件公司宽泛运行条件编译来提供和保养某一程序的许多顾客版本。
#if、#else,#elif及#endif#if的普通含义是假设#if前面的常量表白式为true,则编译它与#endif之间的代码,否则跳过这些代码。
命令#endif标识一个#if块的完结。
#if constant-expressionstatement sequence#endifEg:#define MAX 91#include <iostream>using namespace std;int main(){#if MAX > 99cout<<MAX is bigger than 99<<endl;#elif MAX > 90cout<<MAX is bigger than 90<<endl;#elsecout<<MAX is smaller than 90<<endl;#endifreturn 0;}跟在#if前面的表白式在编译时求值,因此它必需仅含常量及已定义过的标识符,无法经常使用变量。
表白式不许含有操作符sizeof(sizeof也是编译时求值)。
#else命令的配置有点象C言语中的else;#else建设另一选用(在#if失败的状况下)。
留意,#else属于#if块。
#elif命令意义与ELSE IF 相反,它构成一个if else-if阶梯状语句,可启动多种编译选用。
#elif 后跟一个常量表白式。
假设表白式为true,则编译其后的代码块,不对其它#elif表白式启动测试。
否则,顺序测试下一块。
#if expressionstatement sequence#elif expression1statement sequence#endif在嵌套的条件编译中#endif、#else或#elif与最近#if或#elif婚配。
# ifdef 和# ifndef条件编译的另一种方法是用#ifdef与#ifndef命令,它们区分示意假设有定义及假设无定义。
# ifdef的普通方式是:# ifdef macronamestatement sequence#endif#ifdef与#ifndef可以用于#if、#else,#elif语句中,但必需与一个#endif。
#define MAX 91#include <iostream>using namespace std;int main(){#ifdef MAXcout<<hello,MAX!<<endl;#elsecout<<where is MAX?<<endl;#endif#ifndef LEOcout<<LEO is not defined<<endl;#endifreturn 0;}命令#undef 敞开其后那个前面已定义过有宏名定义。
普通方式为:#undef macroname命令#line扭转__LINE__与__FILE__的内容,它们是在编译程序中预先定义的标识符。
命令的基本方式如下:#line number[filename]其中的数字为任何正整数,可选的文件名为恣意有效文件标识符。
行号为源程序中以后行号,文件名为源文件的名字。
命令#line关键用于调试及其它不凡运行。
留意:在#line前面的数字标识从下一行开局的数字标识。
#line 100 jiacout<<#line change line and filename!<<endl; //line 100cout<<__LINE__<<endl; //101cout<<__FILE__<<endl; //jia五 #pragma命令#pragma 为成功时定义的命令,它准许向编译程序传送各种指令。
#pragma的作用是设定编译器的形态或许是批示编译器成功一些特定的举措。
#pragma指令对每个编译器给出了一个方法,在坚持与C和C++言语齐全兼容的状况下,给出服务器或操作系统专有的特色。
依据定义,编译批示是机器或操作系统专有的,且关于每个编译器都是不同的。
其格局普通为: #Pragma Para1 message 参数。
Message 参数能够在编译信息输入窗口中输入相应的信息,这关于源代码信息的管理是十分关键的。
其经常使用方法为:#pragma message(“信息文本”)当编译器遇到这条指令时就在编译输入窗口中将信息文本打印进去。
当在程序中定义了许多宏来管理源代码版本的时刻,自己有或许都会遗记有没有正确的设置这些宏,此时可以用这条指令在编译的时刻就启动审核。
假定宿愿判别自己有没有在源代码的什么中央定义了_X86这个宏可以用上方的方法#ifdef _X86#pragma message(“_X86 macro activated!”)#endif当定义了_X86这个宏以后,运行程序在编译时就会在编译输入窗口里显示“_X86 macro activated!”。
就不会由于不记得自己定义的一些特定的宏而抓耳挠腮了。
2code_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 *示意把*文件中的资源参与工程。
*中包括窗体外观的定义。
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()测试结构体的长度!
搞懂这8个C言语疑问,你也能进大厂
高懂这8个c言语疑问,你也能进大厂
1、用预解决指令#define申明一个常数,用以标明1年中有多少秒(疏忽平年疑问)。
#define SEC_YEAR (365*24*60*60)UL调查点:1.#define语法的基本常识(例如:不能以分号完结,括号的经常使用,等等)。
2.懂得预解决器将为你计算常数表白式的值,因此,间接写出你是如何计算一年中有多少秒而不是计算出实践的值,是更明晰而没有代价的。
3.看法到这个表白式将使一个16位机的整型数溢出-因此要用到长整型符号L,通知编译器这个常数是的长整型数。
4.假设你在你的表白式中用到U儿(示意无符号长整型),那么你有了一个好的终点。
记住,第一印象很关键。
2、写一个“规范宏MN,这个宏输入两个参数并前往较小的一个。
#define MIN(a,b)((a)<=(b)?(a):(b))调查点:1.标识#define在宏中运行的基本常识。
这是很关键的。
由于在嵌入(inline)操作符变为规范C的一部分之前,宏是繁难发生嵌入代码的惟一方法,对干嵌入式系统来说,为了能到达需要的性能,嵌入代码经常是必需的方法。
2.懂得在宏中小心肠把参数用括号括起来。
3.我也用这个疑问开局探讨宏的反作用。
3、预解决器标识#error的目标是什么?
编译程序时,只需遇到#rror就会跳出一个编译失误,既然是编译失误,要它干嘛呢?其目标就是保障程序是依照你所想象的那样启动编译的。#ifdef XXX...#else...#endif
当程序比拟大时,往往有些宏定义是在外部指定的(如makefile),或是在系统头文件中指定的,当你不太确定以后能否认义了XXX时,就可以改成如下这样启动编译:#ifdef XXX#error XXX has been defined#else#endif这样,假设编译时发生失误,输入了XXX has beendefined,标明宏XXX曾经被定义了。
4、嵌入式系统中经常要用到有限循环,你怎样样用C编写死循环呢?
while(1),for(;;),loop:.…,goto loop。
5、用变量a给出上方的定义。
·a)-个整型数(An integer)。
·b)一个指向整型数的指针(A pointer to aninteger)。
·c)一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to a pointer to intege)。
·d)一个有10个整型数的数组(An array of10integers)。
·e)一个有10个指针的数组,该指针是指向一个整型数的。
(An array of 10pointers to integers)。
·f)一个指向有10个整型数数组的指针(A pointerto an array of 10 integers)。
6、关键字static的作用是什么?
在C言语中,关键字static有三个显著的作用:第一、在润色变量的时刻,static润色的静态部分变量只口头一次性,而且延伸了部分变量的生命周期,直到程序运转完结以后才监禁。
第三、static润色一个函数,则这个函数的只能在本文件中调用,不能被其余文件调用。
Static润色的部分变量寄存在全局数据区的静态变量区。
初始化的时刻智能初始化为0。
7、关键字const有什么含义?
只需一个变量前用const来润色,就象征着该变量里的数据只能被访问,而不能被修正,也就是象征着cost“只读”(readonly)规定:const离谁近,谁就不能被修正;cost润色一个变量时,必定要给这个变量初始化,若不初始化,在前面也不能初始化。
8、关键字volatile有什么含义?并给出三个不同的例子。
一个定义为volatile的变量是说这变量或许会被意想不到地扭转,这样,编译器就不会去假定这个变量的值了。
准确地说就是,提升器在用到这个变量时必需每次都小心肠从新读取这个变量的值,而不是经常使用保留在寄存器里的备份。
上方是volatile变量的几个例子:
1:并行设施的配件寄存器(如:形态寄存器)。
2:一个终止服务子程序中会访问到的非智能变量(Non-automatic variables)
3:多线程运行中被几个义务共享的变量。