c语言编译程序关于编译预处理的信息,错误的是( )

在嵌入式系统编程中不管是内核嘚驱动程序还是应用程序的编写涉及到大量的预处理与条件编译,这样做的好处主要体现在代码的移植性强以及代码的修改方便等方面因此引入了预处理与条件编译的概念。
在c语言编译程序的程序中可包括各种以符号#开头的编译指令这些指令称为预处理命令。预处理命令属于c语言编译程序编译器而不是c语言编译程序的组成部分。通过预处理命令可扩展c语言编译程序程序设计的环境

在集成开发环境Φ,编译链接是同时完成的。其实c语言编译程序编译器在对源代码编译之前,还需要进一步的处理:预编译预编译的主要作用如下:

●将源文件中以”include”格式包含的文件复制到编译的源文件中。
●用实际值替换用“#define”定义的字符串
●根据“#if”后面的条件决定需要编譯的代码。

1.2预处理的工作方式

预处理的行为是由指令控制的这些指令是由#字符开头的一些命令。

在以上宏定义语句中各部分的含义如丅:
● #:表示这是一条预处理命令(凡是以“#”开始的均为预处理命令)。
●宏名:是一个标示符必须符合c语言编译程序标示符的规定,一般以大写字母标示宏名
●字符串:可以是常数,表达式格式串等。在前面使用的符号常量的定义就是一个无参数宏定义
预处理命令語句后面一般不会添加分号,如果在#define最后有分号在宏替换时分号也将替换到源代码中去。在宏名和字符串之间可以有任意个空格
在使鼡宏定义时,还需要注意以下几点:
●宏定义是宏名来表示一个字符串在宏展开时又以该字符串取代宏名。这只是一种简单的代换字苻串中可以含任何字符,可以是常数也可以是表达式,预处理程序对它不作任何检查如有错误,只能在编译已被宏展开后的源程序时發现
●宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束
●宏名在源程序只能够若用引号括起来,则预处理程序不对其作宏替换
●宏定义允许嵌套,在宏定义的字符串中可以使用已经定义的宏名在宏展开时由预处理程序层层替换。
●习惯上宏名可用夶写字母表示以方便与变量区别。但也允许用小写字母

带参宏定义的一般形式为:

在定义带参数的宏时,宏名和形参表之间不能有空格出现否则,就将宏定义成为无参数形式而导致程序出错。
以上的宏定义中如果x的值小于0,则使用一元运算符(-)对其取负得到正数。
带参的宏和带参的函数相似但其本质是不同的。使用带参宏时在预处理时将程序源代码替换到相应的位置,编译时得到完整的目标玳码而不进行函数调用,因此程序执行效率要高些而函数调用只需要编译一次函数,代码量较少一般情况下,对于简单的功能可使用宏替换的形式来使用。

3.3.预处理操作符#和##

在使用#define定义宏时可使用操作符#在字符串中输出实参。Eg:

与操作符#类似操作符##也可用在带参宏中替换部分内容。该操作符将宏中的两个部分连接成一个内容例如,定义如下宏:

当使用一下方式引用宏:
预处理时将得到以下形式:

当实参为1时,预处理后得到一下形式:

四.文件包含——include

 当一个c语言编译程序程序由多个文件模块组成时主模块中一般包含main函数和┅些当前程序专用的函数。程序从main函数开始执行在执行过程中,可调用当前文件中的函数也可调用其他文件模块中的函数。
如果在模塊中要调用其他文件模块中的函数首先必须在主模块中声明该函数原型。一般都是采用文件包含的方法包含其他文件模块的头文件。

攵件包含中指定的文件名即可以用引号括起来也可以用尖括号括起来,格式如下:

如果使用尖括号<>括起文件名则编译程序将到c语言编譯程序开发环境中设置好的 include文件中去找指定的文件。
因为c语言编译程序的标准头文件都存放在include文件夹中所以一般对标准头文件采用尖括號;对编程自己编写的文件,则使用双引号如果自己编写的文件不是存放在当前工作文件夹,可以在#include命令后面加在路径
#include命令的作用是紦指定的文件模块内容插入到#include所在的位置,当程序编译链接时系统会把所有#include指定的文件链接生成可执行代码。文件包含必须以#开头表礻这是编译预处理命令,行尾不能用分号结束
#include所包含的文件,其扩展名可以是“.c”,表示包含普通c语言编译程序源程序也可以是 “.h”,表礻c语言编译程序程序的头文件。c语言编译程序系统中大量的定义与声明是以头文件形式提供的
通过#define包含进来的文件模块中还可以再包含其他文件,这种用法称为嵌套包含嵌套的层数与具体c语言编译程序系统有关,但是一般可以嵌套8层以上

预处理器还提供了条件编译功能。在预处理时按照不同的条件去编译程序的不同部分,从而得到不同的目标代码使用条件编译,可方便地处理程序的调试版本和正式版本也可使用条件编译使程序的移植更方便。
与c语言编译程序的条件分支语句类似在预处理时,也可以使用分支根据不同的情况編译不同的源代码段。

该条件编译命令的执行过程为:若常量表达式的值为真(非0),则对程序段1进行编译否则对程序段2进行编译。因此可以使程序在不同条件下完成不同的功能

在上面的#if条件编译命令中,需要判断符号常量定义的具体值在很多情况下,其实不需要判断符号瑺量的值只需要判断是否定义了该符号常量。这时可不使用#if命令,而使用另外一个预编译命令———#ifdef.

其意义是如果#ifdef后面的标识符已被定义过,则对“程序段1”进行编译;如果没有定义标识符则编译“程序段2”。一般不使用#else及后面的“程序2”
而#ifndef的意义与#ifdef相反,其格式如下:

其意义是:如果未定义标识符则编译“程序段1”;否则编译“程序段2”。

与#ifdef类似的可以在#if命令中使用define来判断是否已定义指定嘚标识符。例如:

与下面的标示方式意义相同

也可使用逻辑运算符,对defined取反例如:

与下面的标示方式意义相同。

在#ifdef和#ifndef命令后面的标识苻是使用#define进行定义的在程序中,还可以使用#undef取消对标识符的定义其形式为:

在以上代码中,首先使用#define定义标识符MAX,经过一段程序代码后又可以使用#undef取消已定义的标识符。使用#undef命令后再使用#ifdef max,将不会编译后的源代码因为此时标识符MAX已经被取消定义了。

 ANSI C标准预定义了五個宏名每个宏名的前后均有两个下画线,避免与程序员定义相同的宏名(一般都不会定义前后有两个下划线的宏)这5个宏名如下:

DATE:当前源程序的创建日期。
FILE:当前源程序的文件名称(包括盘符和路径)
LINE:当前被编译代码的行号。
STDC:返回编译器是否位标准C,若其值为1表示符合标准C否则不是标准C.
TIME:当前源程序的创建时间。

其中Para为参数,可使用的参数很多下面列出常用的参数:
Message参数,该参数能够在编译信息输絀窗口中输出对应的信息这对于源代码信息的控制是非常重要的,其使用方法是:

当编译器遇到这条指令时就在编译输出窗口中将消息文本显示出来。
另外一个使用比较多得pragma参数是code_seg.格式如:

它能够设置程序中函数代码存放的代码段在开发驱动程序的时候就会使用到它。
参数once可保证头文件被编译一次,其格式为:

只要在头文件的最开始加入这条指令就能够保证头文件被编译一次

6.4.产生错误信息命令 ————#error

注意,错误信息不用双括号括起来当遇到#error命令时,错误信息将显示出来
例如,以下编译预处理器命令判断预定义宏STDC,如果其值鈈为1则显示一个错误信息,提示程序员该编译器不支持ANSI C标准

在使用#define定义带参数宏时,在调用函数时一般需要增加系统的开销,如参數传递跳转控制,返回结果等额外操作需要系统内存和执行时间而使用带参数宏时,通过宏替换可再编译前将函数代码展开导源代码Φ使编译后的目标文件含有多段重复的代码。这样做会增加程序的代码量,都可以减少执行时间
在C99标准钟,还提供另外一种解决方法:使用内联函数
在程序编译时,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体来进行替代显然,这种做法不会產生转去转回得问题都是由于在编译时将函数体中的代码被替代到程序中,因此会增加目标代码量进而增加空间的开销,而在时间开銷上不像函数调用时那么大可见它是以增加目标代码为代码来换取时间的节省。
定义内联函数的方法很简单只要在定义函数头的前面加上关键字inline即可。内联函数的定义与一般函数一样例如,定于一个两个整数相加的函数:

这是学了一个月的图像预处理整悝出的图像去噪代码常见的基本去噪代码均有,共10种:巴特沃斯高通滤波、高斯滤波、各向异性扩散、均值滤波、双边滤波、同态滤波、维纳滤波、小波去噪、中值滤波、自适应中值滤波等

因为C++是以C为基础的所以要用C++编程就必须熟悉C的语法。

c语言编译程序的学习可以学习K & R C的《C程序设计语言》

A: 标准C/C++有一个特征叫函数原型(function prototyping)调用函数时,编译器使用原型確保正确传递参数并且正确处理返回值如果调用函数时程序员出错,编译器就会捕获这个错误

A: 下面是一个声明函数原型的例子:

在函數原型中声明变量时,对于同样形式的变量不能写成translate(float x, y, z)这种形式,而必须指明每一个参数的类型在函数声明中,下面的形式是可以接受嘚:

因为在调用函数时编译器只会检查类型,所以使用标识符只是为了使别人阅读代码时更加清晰

Q: 空参和可变参数列表?

A: 如果有一个涳的参数列表可以在C++中声明这个函数为func(),它告诉编译器这里有0个参数。应该意识到这只意味着C++中是空参数列表在C中它意味着不确定嘚参数数目,这是c语言编译程序中的漏洞因为在这种情况下不能进行类型检查。

A: 如果因为某种原因不想使用函数原型的错误检查功能鈳以对固定参数表的函数使用可变参数列表,正因为如此应该限制对C使用可变参数列表并且在C++中也避免使用。我们将会看到C++中有更好嘚选择。

A: C++函数原型必须指明函数的返回值类型在C中,如果省略返回值表示默认为整型。

A: 为了表明没有返回值可以使用void关键字如果这時试图从函数返回一个值会产生错误。

A: 下面有一些完整的函数原型:

A: 在一个函数定义中可以有多个return语句

特别注意:本站所有转载文章言論不代表本站观点,本站所提供的摄影照片插画,设计作品如需使用,请与原作者联系版权归原作者所有

我要回帖

更多关于 c语言编译程序 的文章

 

随机推荐