预处理指令
C语言中的预处理指令
C语言中的预处理指令在C语言编程中,预处理指令是一种特殊的指令,用于在编译阶段之前对源代码进行处理。
预处理指令以井号(#)开头,并且不是被编译器执行的实际指令,而是由预处理器处理的。
本文将详细介绍C语言中的预处理指令,并探讨其在程序开发中的作用和用法。
一、什么是预处理指令预处理指令是在编译阶段之前对源代码进行处理的指令。
它的作用是在编译之前对源文件进行一些文本替换、条件编译或者简单的文本粘贴工作。
预处理指令以井号(#)开头,且位于编译单位(源文件或头文件)的最开始位置。
二、预处理指令的作用1. 宏定义宏定义是预处理指令中使用最广泛的功能之一。
通过宏定义,可以为一段代码或者一个常量起一个易于记忆和使用的名字,从而提高代码的可读性和维护性。
下面是一个宏定义的示例:```c#define MAX_NUM 100```在这个例子中,宏定义了一个名为MAX_NUM的常量,它的值为100。
在后续的代码中,可以使用MAX_NUM来代表100,避免了重复书写代码的问题。
2. 文件包含预处理指令还可以使用#include指令将其他文件的内容包含到当前文件中。
这种方式可以在不同的源文件中共享代码,提高代码的复用性。
下面是一个文件包含的示例:```c#include <stdio.h>```通过#include指令,可以将系统库文件stdio.h中的代码包含到当前文件中,以便后续代码可以使用stdio.h中定义的函数和类型。
3.条件编译条件编译是预处理指令中非常重要的概念。
通过条件编译,可以根据条件的真假选择性地编译代码。
这在不同的操作系统、不同的编译器或者不同的编译选项下具有重要的意义。
下面是一个条件编译的示例:```c#ifdef DEBUGprintf("Debug mode\n");#endif```在这个例子中,只有在编译时定义了DEBUG宏的情况下,才会编译并执行printf语句。
程序文件和预处理指令PPT课件
到源文件中。
头文件和源文件之间的主要区别是它们的使用方式不同。根据约定,
在头文件可以包含下面的内容:
类型声明
函数声明
常量定义
数据声明
预处理指令
注释
但头文件不宜包含:
函数定义
.
2
7.2 外部名称
关键字extern可以置于变量或者函数前,以标识变量或者函数的定 义在别的文件中,提示编译器遇到此变量和函数时在其他文件中寻找其 定义。
第7章 程序文件和预处理指令
C++程序是从main函数开始运行,其间可能调用若干函数,这些函数 又调用了另外的函数。函数的层层调用构成了C++程序的结构。然而,当 多个人合作开发时,就会涉及到程序文件的组合。 在Visual C++ 2008中,一个解决方案可以容纳多个程序文件,这些程序 文件共同构成了一个完整的程序。本章将介绍多个程序文件之间如何交 互,以及如何管理和控制程序文件的内容。
在程序中我们可以通过条件判断语句决定执行某部分代 码,或者根据条件执行不同的代码,在预处理器中提也提供 了类似的功能——条件编译。通过条件编译可注释掉一些指 定的代码,以达到版本控制、防止对文件重复包含的功能。
条件编译指令#if的使用方式有两种。第一种是测试某个 标识符以前是否使用#define宏定义过。第二种方式是测试某 个常Leabharlann 表达式是否为真。.8
7.4.2 宏定义
在C语言中,宏定义#define常用于定义符号常量、函数 功能、重新命名、字符串的拼接等,但在C++中宏定义 #define主要用于条件编译指令中,因此我们还需要对宏定义 #define有所了解。
最简单的宏定义是指定一系列字符,以代替程序文件中 的特定符号。
预处理指令——精选推荐
预处理指令预处理命令1 . 基本介绍使⽤库函数之前,应该⽤#include引⼊对应的头⽂件,这种以#开头的命令称为预处理命令这些在编译之前对源⽂件进⾏简单加⼯的过程,就称为预处理(即预先处理,提前处理)预处理主要是处理以#开头的命令。
例如#include<stdio.h>,预处理命令要放在所有函数之外,⽽且⼀般都放在源⽂件的前⾯预处理是C语⾔的⼀个重要功能,由预处理程序完成,当对⼀个源⽂件进⾏编译时,系统将⾃动调⽤预处理程序对源程序中的预处理部分做处理,处理完毕⾃动进⼊对源程序的编译C语⾔提供了多种预处理功能,如宏定义,⽂件包含,条件编译,合理的使⽤会使编写的程序便于阅读,修改,移植和调试,也有利于程序模块化设计2 . 快速⼊门2.1 具体要求开发⼀个C语⾔程序,让它暂停5秒以后再输出内容“hello 尚硅⾕”,并且要求跨平台,在Windows和Linux下都能运⾏2.2 提⽰Windows平台下的暂停函数的原型是void Sleep(DWORD dwMilliseconds),参数的单位是“毫秒”,位于<windows.h>头⽂件linux平台下暂停函数的原型是unsigned int sleep(unsigned int second),参数的单位是“秒”,位于<unistd.h>头⽂件if ,#endif ,就是预处理命令,他们都是在编译之前由预处理程序来执⾏的2.3 代码实现#include<stdio.h>//说明:在Windows操作系统和Linux操作系统下,⽣成源码不⼀样#incLude<windows.h>int main(){Sleep(5000);puts("hello ,尚硅⾕");getchar();rerurn 0;}#if_WIN32 //如果是windows平台,就执⾏#include<windows.h>#include<windows.h>#elif_linux_//否则判断是不是linux,如果是linux就引⼊<unistd.h>#include<unistd.h>#endifint main(){//不同的平台调⽤不同的函数#if_WIN32Sleep(5000);#elif_linux_sleep(5);#endifputs("hello,尚硅⾕");getchar();return 0;}3 . 宏定义3.1 基本介绍define叫做宏定义命令,它⼜是C语⾔预处理命令的⼀种。
预处理指令
预处理指令,宏和运算符当编译程序时,它做的第一件事是进行预处理。
这一阶段中,甚至可以人为地将编译器视为一个不同的实体——预处理器。
该阶段中,编译器读入头文件、决定编译哪些行的源代码并执行文本替换。
预编译阶段的优越性在于它的编译及运行之前执行了某些特定的操作。
这些操作并不添加额外的程序执行时间。
同时,这些命令也不与程序运行时所发出的任何指令相对应。
所以,在使用预处理指令时就需要兼顾实际的运行情况。
预处理的三个基本元素:指令:在程序编译前执行的特定命令。
预定义宏:在编译前所执行的特定命令。
预处理运算符:在#if和#define中使用。
预处理指令语法与C++的其它语法有所不同。
指令以行末结束,而不需要分号。
但你可以用续行符(\)来摆脱物理行的限制。
另外,指令必须从第一行开始。
指令:有一半预处理指令提供了对条件编译的支持,条件编译的作用是用来维护同一程序的不同版本。
这些指令包括:#if #ifdef #elif #ifndef #else #end其余的预处理指令提供了对其它功能的支持,例如包括头文件和宏定义:#define #include #pragma #error #line #undef详解:★#define [定义符号或宏]目的:一:提供了创建符号常量的有效信息途径。
二:使编写人员能写宏指令,这些宏指令看上去像函数调用,但实际上是通过文本替换来实现。
三:简单地定义某些符号作为#ifdef指令的开关。
语法格式:#define标识符替代值#define 标识符[(参数1,.....,参数n)] 替代值其中,在”替代值”中出现的形参将在使用时被实参替代. 就象写函数一样.#define 标识符◆用法一:符号常量有些程序用到了一些很重要但又非常难忘或难以输入的数字。
最好事先将它们转化成为符号常量。
在转化时,通常是以大写形式表示,以便将它们与变量名区分开来。
例:#define E 2.718281828459这条指令的意思是每当程序中出现E时,预处理器就会将E替换成2.718281828459。
C语言的预处理指令与宏定义优化
C语言的预处理指令与宏定义优化概述C语言是一种广泛使用的编程语言,其灵活性和高效性使得它成为许多开发者的首选语言。
在C语言中,预处理指令和宏定义是两个重要的概念,可用于优化代码和增加代码的可读性。
本文将介绍C语言的预处理指令和宏定义,并探讨如何利用它们进行代码优化。
什么是预处理指令?预处理指令是在编译之前执行的一系列指令,它们用于对源代码进行一些处理,以产生最终的编译代码。
预处理指令以“#”字符开头,并且在一行中独立存在。
预处理指令是在编译器编译源代码之前,由预处理器(preprocessor)负责处理的。
预处理指令的作用预处理指令有多种作用,主要包括以下几个方面:1.宏定义(Macro definition):通过宏定义,可以将一组代码片段用一个名字代替,从而减少重复编码,提高代码的可读性。
宏定义可以带有参数,使得代码更加灵活。
2.文件包含(File inclusion):通过预处理指令“#include”,可以在源代码中插入其他文件的内容,这样可以将代码模块化,提高代码的易读性和可维护性。
3.条件编译(Conditional compilation):通过预处理指令“#ifdef”、“#ifndef”、“#endif”等,可以根据条件来选择性地编译一部分代码,从而实现不同的功能组合。
4.符号替换(Symbol substitution):通过预处理指令“#define”,可以将一个符号替换为另一个符号,从而可以在源代码中使用更加易懂的符合语义的名称。
什么是宏定义?宏定义是一种在代码中定义一个标识符的方法,它可以被替换为一段代码或一个值。
宏定义以“#define”关键字开头,后面是宏的名称和它所代表的值或代码。
宏定义以“#define”关键字开头,后面是宏的名称和它所代表的值或代码。
在程序中,当遇到该宏的名称时,预处理器会将其替换为宏的值或代码。
宏定义的优化技巧使用宏定义可以提高代码的可读性和可维护性,同时也可以优化代码的性能和减少代码的长度。
08_预处理命令
本章主要内容:宏定义文件包含条件编译1.1编译预处理编译预处理是在对源程序正式编译之前的处理,以“#”开头,如文件包含“#include”、宏定义“#define”等。
预处理命令不是C语言本身的组成部分,不能直接对它进行编译。
所有的预处理指令都是在编译之前完成的,不占用程序运行时间。
C语言提供了3中预处理功能,即宏定义、文件包含、条件编译。
以“#”开头,占用一个单独的书写行,语句结尾不适用分号。
宏定义:#define文件包含:#include条件编译:#ifndef…#if…#else…#endif等1.2宏定义1.2.1不带参数的宏定义语法格式:#define 宏名[宏体](宏体可省略,如果没有则作为一个标识用于#if语句中)功能:用指定标识符(宏名)代替字符序列(宏体)说明:宏名要是一个合法的标识符,通常采用大写字母表示;宏体可以是常数、表达式和语句,甚至可以是多条语句。
举例:#define PI 3.1415926 //定义π的值为3.1415926,以后要用到π,就可以直接用PI #define OUT printf(“Hello World!\n”); //定义宏OUT替换后面的函数用#undef可以终止宏名作用域,格式为:#undef 宏名举例:void main(){#define YES 1 //定义宏YESprintf("%d\n",YES);#undef YES //结束宏YES的作用域#define YES 0 //重新定义宏YESprintf("%d\n",YES);}有关宏定义的使用,需注意以下几点:1宏名习惯采用大写,以便与普通变量区分;2宏定义不是C语句,所以不能在行尾加分号;否则,宏展开时,会将分号也算在内3在宏展开时,预处理程序仅按宏定义简单替换宏名,不做任何检查。
如果有错误,只能由编译器在编译宏展开后的源程序时发现。
4宏定义的位置是任意的,宏名的有效范围是从定义命令处到本模块结束。
预处理命令
10.2预处理指令主要有三种类型:1、宏定义:#define和#undef指令2、文件包含:#include指令3、条件编译:#if、#ifdef、#ifndef、#elif、#else和#endif指令宏定义包含带参数的宏和不带参数的宏两种;带参数的宏定义格式为:#define 标识符(X1,X2,X3…)替换列表其与函数调用的结果完全不同,详见12/22程序macro with parameter通过程序实例得出,为了避免宏名参与的运算结果不混淆,一般采用如下两种形式的定义方式:1、#define AREA(X)(X)*(X)2、#define AREA(X)(X*X)替代#define AREA(X)X*X避免在宏定义中使用自增符号,如对于宏定义#define AREA(X)(X*X),AREA(++X),被展开为++X*++X,假如X初值为5,则其运算结果可能为42或者49,由于未规定运算顺序,编译器可能会出现不同的结果宏定义与函数有类似的地方,宏代替函数有以下优点:1、从效率角度考虑,程序执行起来会更快些,在调用函数时总会有些额外的开销,如保存调用点的信息以便函数调用结束后能正确返回调用点,而宏调用则没有这些运行时的开销;2、宏更加通用。
与函数不同,宏的参数是没有类型的,因此,宏可以接收任何类型的参数,因此它的使用范围更加广泛同时,也会以下缺点:1、源程序编译后代码量会增加,预处理过程中会在每一处宏调用的地方插入宏的替换列表,显然会使源程序的代码增加;2、预处理器不会检查宏参数的类型,也不会进行类型转换,这样采用宏调用可能会产生错误的结果3、自增、自减运算不能在宏中进行,可能会导致错误的结果;#运算符和##运算符只能出现在带参数宏的替换列表中,例如x为一个宏的参数,那么#x就可以将参数名转化为相应的字符串,该过程称为字符串化(stringization),程序实例详见12.23 stringization##运算符,如果##连接的两个操作数中其中一个为宏的参数,那么会先进行参数替换,然后再执行##运算符的操作。
预处理指令
9.1.2 有参宏定义
1.带参宏定义的一般格式 . #define 宏名 形参表 语言符号字符串 宏名(形参表 形参表) 2.带参宏的调用和宏展开 . 实参表) (1)调用格式:宏名 实参表 )调用格式:宏名(实参表 (2)宏展开:用宏调用提供的实参字符串,直接置换 )宏展开:用宏调用提供的实参字符串, 宏定义命令行中、相应形参字符串,非形参字符保持不变。 宏定义命令行中、相应形参字符串,非形参字符保持不变。 3.说明 . (1)定义有参宏时,宏名与左圆括号之间不能留有空 )定义有参宏时, 否则, 格。否则,C编译系统将空格以后的所有字符均作为替代 字符串,而将该宏视为无参宏。 字符串,而将该宏视为无参宏。 (2)有参宏的展开,只是将实参作为字符串,简单地 )有参宏的展开,只是将实参作为字符串, 置换形参字符串,而不做任何语法检查。在定义有参宏时, 置换形参字符串, 而不做任何语法检查。在定义有参宏时, 在所有形参外和整个字符串外,均加一对圆括号。 在所有形参外和整个字符串外,均加一对圆括号。
第9章
预处理命令
ห้องสมุดไป่ตู้
所谓预处理命令是指,在对源程序进行编译之前, 所谓预处理命令是指,在对源程序进行编译之前,先 对源程序中的编译预处理命令进行处理; 对源程序中的编译预处理命令进行处理;然后再将处理的 结果,和源程序一起进行编译,以得到目标代码。 结果,和源程序一起进行编译,以得到目标代码。 9.1 宏定义 9.2 文件包含 9.3 条件编译
9.3 条件编译
条件编译可有效地提高程序的可移植性, 条件编译可有效地提高程序的可移植性,并广泛地应 用在商业软件中,为一个程序提供各种不同的版本。 用在商业软件中,为一个程序提供各种不同的版本。 1.一般格式 . #if 常量表达式 程序段1; 程序段 ; [#else # 程序段2; 程序段 ;] #endif 2.功能:当表达式为非0(“逻辑真”)时,编译程序 .功能:当表达式为非 ( 逻辑真” 段1,否则编译程序段 。 ,否则编译程序段2。
预处理命令——精选推荐
预处理命令1,所有的预处理指令都是以#号开头的
2,预处理指令分3种:
1>宏定义:#define COUNT 4 //后边没有任何符号 #undef COUNT结束宏定义
2>条件编译
#define A 5
#if (A==5)
printf("A是5");
#elif
printf("A是10");
#else
printf("A是其他");
#endif
return 0;
#if defined(A)//如果A是宏定义
3>⽂件包含
#include "lisi.h"
为了减少过多次的引⼊⽂件造成的编译效率的降低,建议在每个被引⼊⽂件内都加⼊#ifndef LISI_H //以⽂件名定义宏变量
#define LISI_H 123
int sum(int a,int b);
#endif
3.1 <>表⽰系统⾃带的⽂件,""表⽰⾃定义⽂件
3.2 不允许循环包含,⽐如说a.h包含b.h ,⽽b.h⼜包含a.h
3,预处理指令在代码翻译晨0和1之前执⾏
4,预处理指令的位置是随便写的
5,预处理指令的作⽤范围:从编写指令的那⼀⾏开始,⼀直到⽂件的结尾
6,宏名⼀般⽤⼤写或者以k开头,变量名⼀般⼩写
带参数的宏定义效率⽐函数⾼:
#define sum(v1,v2) ((v1)+(v2))
#define pingfang(v1,v2) ((v1)*(v2))。
C语言程序的基本结构
C语言程序的基本结构一、预处理指令预处理指令以“#”符号开头,用于提供指示器供编译器使用。
预处理指令可以包括文件包含、宏定义和条件编译等。
1. 文件包含:使用预处理指令“#include”可以将其他头文件包含到当前源文件中,以便可以使用其中定义的函数和变量。
```c#include <stdio.h>```2. 宏定义:使用预处理指令“#define”可以定义宏,宏会在编译前被展开为相应的代码。
```c```3. 条件编译:使用预处理指令“#ifdef”、“#ifndef”、“#if”等可以根据条件选择是否编译段代码。
```c#ifdef DEBUGprintf("Debugging mode\n");#endif```二、全局变量全局变量是在函数外部定义的变量,可以在整个程序中被访问和使用。
全局变量必须在使用之前进行声明或定义。
```c#include <stdio.h>int globalVariable;int mai// do somethingreturn 0;```三、函数声明函数声明用于告诉编译器有一个函数存在,它的名称、参数和返回类型等信息。
函数声明一般放在头文件中,可以被多个源文件共享。
```c#include <stdio.h>int add(int a, int b);int maiint result = add(3, 5);printf("Result: %d\n", result);return 0;int add(int a, int b)return a + b;```四、函数定义函数定义包含了函数的具体实现,函数定义一般放在源文件中,用于实现函数的功能。
```c#include <stdio.h>int add(int a, int b)return a + b;int maiint result = add(3, 5);printf("Result: %d\n", result);return 0;```五、函数调用函数调用是通过函数名和参数列表来调用函数,可以将函数的返回值赋给变量或直接输出结果。
c11标准 预处理
C11标准预处理是指在C语言编程中,使用预处理指令来对源代码进行一些预处理操作。
预处理指令是在编译之前由预处理器处理的指令,它们不是实际的编程语言代码,而是在编译过程中执行的指令。
在C11标准中,常见的预处理指令包括:
1. 宏定义(#define):用于定义宏常量或宏函数。
宏定义可以替换源代码中的标识符为指定的值或代码片段。
2. 头文件包含(#include):用于将一个头文件的内容插入到当前源文件中。
头文件通常包含了一些常用的函数声明、宏定义和类型定义等。
3. 条件编译(#if、#elif、#else、#endif):用于根据条件选择性地编译代码。
通过条件编译指令,可以根据不同的编译选项或编译器设置,选择是否编译特定的代码块。
4. 预定义宏(#defined、#ifdef、#ifndef、#if defined):用于检查某个宏是否被定义或未定义。
这些指令可以用于条件判断和条件编译。
5. 空指令(#pragma):用于向编译器发送特定指令或参数,以控制编译器的行为。
不同的编译器可能支持不同的pragma指令。
预处理指令在编译过程中会被预处理器解析和处理,生成对应的中间代码或目标代码。
预处理指令的使用可以提高代码的可读性、可维护性和可重用性,但也需要谨慎使用,避免出现潜在的问题和错误。
c语言程序的基本结构
c语言程序的基本结构C语言是一种广泛应用于计算机编程的高级编程语言,被广泛应用于系统软件、应用软件、嵌入式系统等领域。
了解C语言程序的基本结构对于学习和理解C语言的编程技巧以及写出高效、稳定、易于维护的代码至关重要。
本文将介绍C语言程序的基本结构,以便读者快速上手和编写C语言程序。
一、预处理指令C语言程序通常以预处理指令开始,预处理器会根据这些指令对代码进行预处理,例如移除注释、插入文件等操作。
预处理指令以"#"开头,常见的预处理指令包括:1. #include:用于包含文件,将指定的文件内容插入到当前位置。
例如:`#include <stdio.h>`表示包含标准输入输出头文件。
2. #define:用于定义宏,将一段代码标识为一个宏,并在后续代码中使用。
例如:`#define PI3.14159`定义了一个名为PI的宏,它的值是3.14159。
二、函数声明在C语言程序中,函数是代码的基本组织单元。
函数声明用于向编译器说明函数的名称、参数个数和类型以及返回值类型。
函数声明的语法如下:```返回值类型函数名(参数列表);```例如,以下是一个函数声明的例子:```int add(int a, int b);```三、主函数C语言程序必须包含一个特殊的函数,称为主函数(main函数)。
主函数是程序的入口点,程序在运行时会从主函数开始执行。
主函数的基本结构如下:```返回值类型 main(参数列表) {// 函数体return 0;}```其中,返回值类型通常为int,表示函数执行完成后返回的结果。
参数列表是通过命令行传递给程序的参数,可以为空。
函数体中编写程序的具体逻辑,return语句用于返回结果并结束函数的执行。
```int main() {printf("Hello, World!");return 0;}```四、函数定义函数定义用于给出函数的具体实现。
C语言-预处理命令
我们可以在C源程序中插入传给编译程序的各中指令,这些指令被称为预处理器指令,它们扩充了程序设计的环境。
现把常用的预处理命令总结如下:1. 预处理程序按照ANSI标准的定义,预处理程序应该处理以下指令:#if #ifdef #ifndef #else #elif#endif#define#undef#line#error#pragma#include显然,上述所有的12个预处理指令都以符号#开始,,每条预处理指令必须独占一行。
2. #define#define指令定义一个标识符和一个串(也就是字符集),在源程序中发现该标识符时,都用该串替换之。
这种标识符称为宏名字,相应的替换称为宏代换。
一般形式如下:#define macro-name char-sequence这种语句不用分号结尾。
宏名字和串之间可以有多个空白符,但串开始后只能以新行终止。
例如:我们使用LEFT代表1,用RIGHT代表0,我们使用两个#define指令:#define LEFT 1#define RIGHT 0每当在源程序中遇到LEFT或RIGHT时,编译程序都用1或0替换。
定义一个宏名字之后,可以在其他宏定义中使用,例如:#define ONE 1#define TWO ONE+ONE#define THREE ONE+TWO宏代换就是用相关的串替代标识符。
因此,如果希望定义一条标准错误信息时,可以如下定义:#define ERROR_MS “Standard error on input \n”如果一个串长于一行,可在行尾用反斜线”\”续行,如下:#define LONG_STRING “This is a very very long \String that i s used as an example”3. #error#error指令强制编译程序停止编译,它主要用于程序调试。
#error指令的一般形式是:#error error-message注意,宏串error-message不用双引号包围。
预处理命令
3 条件编译 条件编译指令有:#if、#elif、#else、#ifdef、#ifndef,例子如下: #define URMD 0 #if URMD == 0
程序块 1 #elif URMD == 1
程序块 2 #else
预处理命令
C 语言的预处理指令有三类,一是宏定义,二是文件包含,三是条件编译。 预处理命令以符号“#”开头
1 宏定义 宏定义主要是#define,其又分为带参数定义和不带参数定义,例子如下 带参数定义 #define PI 3.14 不带参数定义 #define ST STR 在一些头文件定义中常使用 #define EXAMPLE(标识符) 其把 EXAMPLE 定义为空值,目的是为了防止头文件被多次包含,虽然可 以省略,但是一般不能省略 此外,#undef 可以终止宏名的定义 宏展开只是简单的字符串替换,简单宏常用于定义常量,宏没有类型,也没 有优先级的概念,使用定义常量主要用于指定数组长度 #define ayyLength 256 ,建 议尽量使用 const 或 enum 代替宏定义常量 constint arrLen 256; 。建议不使用宏定 义类型 #define Status int 而是用 typedef 关键字 typedef Statusint; 。
ห้องสมุดไป่ตู้
程序块 3 #endif 上述条件编译例子,是在宏条件符合时,编译器就编译这段代码,否则不编
译,它跟不带“#”的区别就在于一般的条件语句使所有条件的代码都会被编译 生成执行代码,而预处理条件语句则是只编译符合条件的那部分代码,其它不合 条件的不会生成执行代码。
因此,一般条件在编译前就确定了,那么就使用预处理条件,如果需要在程 序运行过程中才能判断,则使用一般的条件语句
C语言预处理指令的使用方法
C语言预处理指令的使用方法C语言中的预处理指令是在源代码编译之前由预处理器进行处理的。
预处理指令主要用于定义宏、包含头文件、条件编译等操作,能够在编译之前完成一些预处理任务。
本文将介绍C语言预处理指令的使用方法。
一、宏定义宏定义是C语言预处理指令中最常见的一种形式。
通过宏定义,我们可以将一段代码或者常量定义为一个宏,在代码中使用宏来代替实际的代码或者值。
宏定义的格式如下:```c#define MACRO_NAME replacement```其中,MACRO_NAME为宏的名称,replacement为宏的替换内容。
在代码中使用宏时,预处理器会将所有的MACRO_NAME替换为replacement。
例如,我们可以定义一个将两个数相加的宏:```c#define ADD(a, b) ((a) + (b))```在使用该宏时,我们只需要使用宏名称和参数即可,如:```cint result = ADD(2, 3);```预处理器将会将ADD(2, 3)替换为((2) + (3)),最终result的值为5。
二、头文件包含头文件包含是另一种常见的预处理指令,它用于引入其他文件中定义的函数和变量。
通过头文件包含,我们可以在当前文件中使用其他文件中定义的代码。
有两种形式的头文件包含指令:```c#include <header_file>#include "header_file"```使用尖括号<>包围的是系统头文件,而使用双引号""包围的是用户自定义的头文件。
例如,我们可以在代码中包含一个名为stdio.h的系统头文件:```c#include <stdio.h>```这样,我们就可以在代码中使用stdio.h中定义的输入输出函数,如printf和scanf。
另外,我们也可以包含自己编写的头文件。
假设我们在项目中有一个名为utilities.h的头文件,我们可以通过以下方式进行包含:```c#include "utilities.h"```三、条件编译条件编译是一种根据条件选择编译代码的方式。
c++预处理指令
c++预处理指令 预处理是在编译之前的处理,⽽编译⼯作的任务之⼀就是语法检查,预处理不做语法检查。
预处理命令以符号“#”开头。
常⽤的预处理指令包括:宏定义:#define⽂件包含:#include条件编译:#if、#elif、#ifndef、#ifdef、#endif、#undef错误信息指令:#error#line指令布局控制:#pragma宏定义 宏定义⼜称为宏代换、宏替换,简称“宏”。
宏替换只作替换,不做计算,不做表达式求解。
宏定义分带参数的宏定义和不带参数的宏定义。
在带参数的宏定义,宏名和参数的括号间不能有空格。
宏定义不分配内存,变量定义分配内存。
宏展开不占运⾏时间,只占编译时间;函数调⽤占运⾏时间(分配内存、保留现场、值传递、返回值)。
出现在宏定义中的#运算符把跟在其后的参数转换成⼀个字符串,有时把这种⽤法的#称为字符串化运算符。
例如:#include<iostream>using namespace std;#define STR(n)"abcd"#nint main(){cout<<STR(6)<<endl;system("pause");return 0;} ##运算符⽤于把参数连接到⼀起,预处理程序把出现在##两侧的参数合并成⼀个符号。
例如:#include<iostream>using namespace std;#define STR(a,b,c) a##b##cint main(){cout<<STR(1,2,3)<<endl;system("pause");return 0;} 输出结果为:⽂件包含 #include<⽂件名>称为标准⽅式,到系统头⽂件⽬录查找⽂件,#include"⽂件名"则先在当前⽬录(⽤户路径)查找,⽽后到系统头⽂件⽬录查找。
5.2 预处理指令
2、条件指令
条件预处理指令指的是以判断条件表达式的计算结果作为 是否执行包含在条件指令之间的代码段的依据。条件预处 理指令包含一组预处理指令,分别是if预处理指令、elif预 处理指令、else预处理指令和endif预处理指令。 if预处理指令与endif预处理指令必须成对出现。 elif预处理指令和else预处理指令,必须位于一对if预处理 指令和endif预处理指令之间,而且elif预处理指令必须在 else预处理指令之前出现。 条件预处理指令是最常用的预处理指令,除了region以外 的其他预处理指令都与条件预处理指令相关。常用的方法 是根据define和undef预处理指令定义的符号,使用条件指 令判断符号的定义情况,当定义有冲突或者不符合规则的 时候,根据实际需要提供警告信息,或者禁止编译程序代 码。
Remarks
#if, along with the #else, #elif, #endif, #define, and #undef directives, lets you include or exclude code based on the condition of one or more symbols. This can be most useful when compiling code for a debug build or when compiling for a specific configuration. A conditional directive beginning with a #if directive must explicitly be terminated with a #endif directive. #define lets you define a symbol, such that, by using the symbol as the expression passed to the #if directive, the expression will evaluate to true. You can also define a symbol with the /define compiler option. You can undefine a symbol with #undef. A symbol that you define with /define or with #define does not conflict with a variable of the same name. That is, a variable name should not be passed to a preprocessor directive and a symbol can only be evaluated by a preprocessor directive. The scope of a symbol created with #define is the file in which it was defined.
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include 指令
#include 指令的作用是指示编译器将该指令所指出的另一个源文件嵌入#include指令所在 的程序中, 文件应使用双引号或尖括号括起来. C 库函数的头文件一般用#include指令在程序开关说明. 例如: #include <stdio.h> 程序中也允许嵌入其它文件, 例如: main() { #include <help.c> } 其中help.c为另一个文件, 内容可为 printf("Glad to meet you here!"); 处理命令的格式 #include "包含文件名" 或 #include <包含文件名 包含文件名" 包含文件名> 包含文件名 包含文件名 两种格式的区别仅在于: (1)使用双引号:系统首先到当前目录下查找被包含文件,如果没找到,再到系统指定 的"包含文件目录"(由用户在配置环境时设置)去查找. (2)使用尖括号:直接到系统指定的"包含文件目录"去查找.一般地说,使用双引号 比较保险.
可变参数的函数
我们在C语言编程中会遇到一些参数个数可变的函数, 例如printf()这个函数,它的定义是这样的: int printf( const char* format, ...); 它除了有一个参数format固定以外,后面跟的参数的个数 和类型是可变的,例如我们可以有以下不同的调用方法: printf("%d",i); printf("%s",s); printf("the number is %d ,string is:%s", i, s); 究竟如何写可变参数的C函数以及这些可变参数的函数 编译器是如何实现的呢?现在就这个问题进行一些探讨,希望 能对大家有些帮助.
#error指令
该指令用于程序的调试, 当编译中遇到#error指令就停止编译.其一般形式为: #error 出错信息 出错信息加不加引号都可, 当编译器遇到这个指令时, 显示下列信息并停止编译. Fatal: filename linename error directive 例如:malloc.h定义如下: /* $FreeBSD: src/include/malloc.h,v 1.5 2001/11/07 23:14:31 obrien Exp $ */ #if __STDC__ #error "<malloc.h> has been replaced by <stdlib.h>" #else #include <stdlib.h> #endif 我写一个程序test.c: #include <malloc.h> Main() { Printf("test\n"); } gcc -D__STDC__ -o test test.c In file included from test.c:1: /usr/include/malloc.h:3:2: #error "<malloc.h> has been replaced by <stdlib.h>"
一般格式 #ifdef 标识符 程序段1; [#else 程序段2;] #endif 功能:当"标识符"已经被#define命令定义过,则 功能 编译程序段1,否则编译程序段2. #ifndef ~ #endif命令 命令 格式与#ifdef ~ #endif命令一样,功能正好与之相反.
#pragma
使用宏时,不允许参数发生变化
示例:如下用法可能导致错误. 定义: #define SQUARE( a ) ((a) * (a)) 使用: int a = 5; int b; b = SQUARE( a++ ); // 结果:a = 7,即执行了两次增1. 正确的用法是: b = SQUARE( a ); a++; // 结果:a = 6,即只执行了一次增1.
使用断言来发现软件问题,提高代码可测性
说明:断言是对某种假设条件进行检查(可理解为 若条件成立则无动作,否则应报告), 作用:它可以快速发现并定位软件问题,同时对系 统错误进行自动报警, 好处:断言可以对在系统中隐藏很深,用其它手段 极难发现的问题进行定位,从而缩短软件问题定位 时间,提高系统的可测性. 示例:下面是C语言中的一个断言,用宏来设计的. (其中NULL为0L)
怎样用宏定义多条表达式
示例:下面的语句只有宏的第一条表达式被执行.为了说明问题,for语句的书写稍不符规范. 定义: #define INTI_RECT_VALUE( a, b )\ a = 0;\ b = 0; 使用: for (index = 0; index < RECT_TOTAL_NUM; index++) INTI_RECT_VALUE( rect.a, rect.b ); 正确的用法应为: 定义: #define INTI_RECT_VALUE( a, b )\ do {\ a = 0;\ b = 0;\ } while(0) 使用: for (index = 0; index < RECT_TOTAL_NUM; index++) { INTI_RECT_VALUE( rect[index].a, rect[index].b ); }
用宏定义表达式时,要使用完备的括号
示例:如下定义的宏都存在一定的风险. #define RECTANGLE_AREA( a, b ) a * b #define RECTANGLE_AREA( a, b ) (a * b) #define RECTANGLE_AREA( a, b ) (a) * (b) 正确的定义应为: #define RECTANGLE_AREA( a, b ) ((a) * (b))
用法
#ifdef _EXAM_ASSERT_TEST_ // 若使用断言测试 void exam_assert( char * file_name, unsigned int line_no ) { printf( "\n[EXAM]Assert failed: %s, line %u\n", file_name, line_no ); abort( ); } #define EXAM_ASSERT( condition ) do{if (condition) // 若条件成立,则无动作 NULL; else // 否则报告 exam_assert( __FILE__, __LINE__ )}while(0) #else // 若不使用断言测试 #define EXAM_ASSERT(condition) NULL #endif /* end of ASSERT */ 用断言确认函数的参数. 示例:假设某函数参数中有一个指针,那么使用指针前可对它检查,如下. int exam_fun( unsigned char *str ) { EXAM_ASSERT( str != NULL ); // 用断言检查"假设指针不为空"这个条件 ... //other program code } gcc -D_EXAM_ASSERT_TEST_ -o 目标程序 源程序 gcc -U_EXAM_ASSERT_TEST_ -o 目标程序 源程序
预 处 理 指 令
2006.4.4
Hale Waihona Puke 介预处理指令主要包括 #define #error #if #else #elif #endif #ifdef #ifndef #undef #pragma 由上述指令可以看出, 每个预处理指令均带有符号"#".
#define 指令
定义的一般形式是: #define 宏替换名字符串(或数值) 由#define指令定义后, 在程序中每次遇到该宏替换名时就用所定义的字 符串(或数值)代替它. 例如: 可用下面语句定义TRUE表示数值1, FALSE表示0. #define TRUE 1 #define FALSE 0 一旦在源程序中使用了TRUE和FALSE, 编译时会自动的用1和0代替. 注意: 1. 在宏定义语名后没有";" 2. 在 C程序中习惯上用大写字符作为宏替换名, 而且常放在程序开头.
先来认识一些宏
va_list void va_start( va_list arg_ptr, prev_param ); type va_arg( va_list arg_ptr, type ); void va_end( va_list arg_ptr ); va在这里是variable-argument(可变参数) 的意思.这些宏定义在stdarg.h中,所以用到可 变参数的程序应该包含这个头文件.
#undef指令
#undef指令用来删除事先定义的宏定义, 其一般形 式为: #undef 宏替换名 例如: #define TRUE 1 ... #undef TURE #undef主要用来使宏替换名只限定在需要使用它 们的程序段中.
#ifdef ~ #endif和#ifndef ~ #endif命令
pragma pack(n)
#pragma pack(n) n=1, 2, 4, 8, or 16 内存对齐问题 typedef struct ms1 { char a; int b; } MS1; 如果#pragma pack(1) 则sizeof(MS1)的值是5; 如果#pragma pack(2) 则sizeof(MS1)的值是6; 如果#pragma pack(4) 则sizeof(MS1)的值是8; 如果#pragma pack(8) 则sizeof(MS1)的值是8; gcc编译器默认值是 编译器默认值是4. 编译器默认值是
在所有的预处理指令中,#Pragma指令可能是最复杂的了 作用:是设定编译器的状态或者是指示编译器完成一些特定 作用 的动作. 但是,我们只了解就可以,尽量别去使用. 但是 C和C++编译器认可如下pragmas: alloc_text,comment //注释,auto_inline component //组成部件,inline_depth,pack //包 bss_seg,data_seg,inline_recursion //内嵌递归 pointers_to_members1,check_stack,function intrinsic //内在的,setlocale,code_seg hdrstop,message,vtordisp1,const_seg,warning include_alias,once,init_seg1,optimize //最优化