#define


#define

文章插图
#define【#define】#define是C语言中的一个预处理指令 , 其中的“#”表示这是一条预处理命令· 。凡是以“#”开头的均为预处理命令 , “define”为宏定义命令 , “标识符”为所定义的宏名 。
基本介绍外文名:define
名称:#define
类型:C语言
宏名:标识符
#define的英文版定义及解释The define DirectiveYou can use the #define directive to give a meaningful name to a constant in your program. The two forms of the syntax are:Syntaxdefine identifier token-stringoptdefine identifier[( identifieropt, ... , identifieropt )] token-stringopt__________________________________________以上是最主要的语法,说明一下,其他在运用时再理解也不迟:语法一:#define 标识符 被标识符代表的字元串 //这种用法很简单,就是一种替换.语法二:#define 标识符[(参数1,.....,参数n)] 被标识符代表的字元串 //其中,在"被标识符代表的字元串"中出现的形参将在使用时被实参替代. 就像写函式一样.补充一点: 在用#define 定义时 ,可以用斜槓("\") 续行.与vb中的下划线(" _")作用同.比如:#define add1( x, y ) ( x + y)也可以表示成 :#define add1(x,y) \(x + y )__________________________________________The #define directive substitutes token-string for all subsequent occurrences of an identifier in the source file. The identifier is replaced only when it forms a token. (SeeC++ Tokens in the C++ Language Reference.) For instance, identifier is not replaced if it appears in a comment, within a string, or as part of a longer identifier.A #define without a token-string removes occurrences of identifier from the source file. The identifier remains defined and can be tested using the #if defined and #ifdef directives.The token-string argument consists of a series of tokens, such as keywords, constants, or complete statements. One or more white-space characters must separate token-string from identifier. This white space is not considered part of the substituted text, nor is any white space following the last token of the text.Formal parameter names appear in token-string to mark the places where actual values are substituted. Each parameter name can appear more than once in token-string, and the names can appear in any order. The number of arguments in the call must match the number of parameters in the macro definition. Liberal use of parentheses ensures that complicated actual arguments are interpreted correctly.The second syntax form allows the creation of function-like macros. This form accepts an optional list of parameters that must appear in parentheses. References to the identifier after the original definition replace each occurrence of identifier( identifieropt, ..., identifieropt ) with a version of the token-string argument that has actual arguments substituted for formal parameters.The formal parameters in the list are separated by commas. Each name in the list must be unique, and the list must be enclosed in parentheses. No spaces can separate identifier and the opening parenthesis. Use line concatenation — place a backslash (\) before the newline character — for long directives on multiple source lines. The scope of a formal parameter name extends to the new line that ends token-string. When a macro has been defined in the second syntax form, subsequent textual instances followed by an argument list constitute a macro call. The actual arguments following an instance of identifier in the source file are matched to the corresponding formal parameters in the macro definition. Each formal parameter in token-string that is not preceded by a stringizing (#), charizing (#@), or token-pasting (##) operator, or not followed by a ## operator, is replaced by the corresponding actual argument. Any macros in the actual argument are expanded before the directive replaces the formal parameter. (The operators are described in Preprocessor Operators.)The following examples of macros with arguments illustrate the second form of the #define syntax:// Macro to define cursor lines#define CURSOR(top, bottom) ((top) << 8) | bottom))// Macro to get a random integer with a specified range#define getrandom(min, max) \((rand()%(int)(((max) + 1)-(min)))+ (min))Arguments with side effects sometimes cause macros to produce unexpected results. A given formal parameter may appear more than once in token-string. If that formal parameter is replaced by an expression with side effects, the expression, with its side effects, may be evaluated more than once. (See the examples under Token-Pasting Operator (##).)The #undef directive causes an identifier’s preprocessor definition to be forgotten. See The #undef Directive for more information. If the name of the macro being defined occurs in token-string (even as a result of another macro expansion), it is not expanded.A second #define for a macro with the same name generates an error unless the second token sequence is identical to the first.Microsoft SpecificMicrosoft C/C++ allows the redefinition of a macro, but generates a warning, provided the new definition is lexically identical to a previous definition. ANSI C considers macro redefinition an error. For example, these macros are equivalent for C/C++ but generate warnings:#define test( f1, f2 ) ( f1 * f2 )#define test( a1, a2 ) ( a1 * a2 )END Microsoft SpecificThis example illustrates the #define directive:#define WIDTH 80#define LENGTH ( WIDTH + 10 )The first statement defines the identifier WIDTH as the integer constant 80 and defines LENGTH in terms of WIDTH and the integer constant 10. Each occurrence of LENGTH is replaced by (WIDTH + 10). In turn, each occurrence of WIDTH + 10 is replaced by the expression (80 + 10). The parentheses around WIDTH + 10 are important because they control the interpretation in statements such as the following:var = LENGTH * 20;After the preprocessing stage the statement becomes:var = ( 80 + 10 ) * 20;which evaluates to 1800. Without parentheses, the result is:var = 80 + 10 * 20;which evaluates to 280. Microsoft SpecificDefining macros and constants with the /D compiler option has the same effect as using a #define preprocessing directive at the beginning of your file. Up to 30 macros can be defined with the /D option.END Microsoft Specific#define中的 #与###define GPEBLT_FUNCNAME(basename) (SCODE (GPE::*)(struct GPEBltParms *))&GPE::##basename在#define中 , 标準只定义了#和##两种操作 。#用来把参数转换成字元串 , ##则用来连线前后两个参数 , 把它们变成一个字元串 。#include <stdio.h>#define paster( n ) printf( "token " #n" = %d\n ", token##n )int main(){int token9=10;paster(9);return 0;}输出为[leshy@leshy src]$ ./a.outtoken 9 = 10#define 的作用在C或C++语言源程式中允许用一个标识符来表示一个字元串 , 称为“宏” 。被定义为“宏”的标识符称为“宏名” 。在编译预处理时 , 对程式中所有出现的“宏名” , 都用宏定义中的字元串去代换 , 这称为“宏代换”或“宏展开” 。宏定义是由源程式中的宏定义命令完成的 。宏代换是由预处理程式自动完成的 。在C或C++语言中 , “宏”分为有参数和无参数两种 。无参宏定义无参宏的宏名后不带参数 。其定义的一般形式为:#define 标识符 字元串其中的“#”表示这是一条预处理命令 。凡是以“#”开头的均为预处理命令 。“define”为宏定义命令 。“标识符”为所定义的宏名 。“字元串”可以是常数、表达式、格式串等 。例如:#define M (a+b)它的作用是指定标识符M来代替表达式(a+b) 。在编写源程式时 , 所有的(a+b)都可由M代替 , 而对源程式作编译时 , 将先由预处理程式进行宏代换 , 即用(a+b)表达式去置换所有的宏名M , 然后再进行编译 。程式1:#define M (a+b)main(){int a{3},b;printf("input a number: ");scanf("%d",&b); a=M*M;printf("s=%d\n",a);}上例程式中首先进行宏定义 , 定义M来替代表达式(a+b),在 s= M * M 中作了宏调用 。在预处理时经宏展开后该语句变为: S=(a+b)*(a+b)但要注意的是 , 在宏定义中表达式(a+b)两边的括弧不能少 。否则会发生错误 。如当作以下定义后:#difine M (a)+(b)在宏展开时将得到下述语句:S= (a)+(b)*(a)+(b)对于宏定义还要说明以下几点:1. 宏定义是用宏名来表示一个字元串 , 在宏展开时又以该字元串取代宏名 , 这只是一种简单的代换 , 字元串中可以含任何字元 , 可以是常数 , 也可以是表达式 , 预处理程式对它不作任何检查 。如有错误 , 只能在编译已被宏展开后的源程式时发现 。2. 宏定义不是说明或语句 , 在行末不必加分号 , 如加上分号则连分号也一起置换 。3. 宏定义必须写在函式之外 , 其作用域为宏定义命令起到源程式结束 。如要终止其作用域可使用#undef命令 。(有关#undef 请查阅其他资料)带参宏定义c语言允许宏带有参数 。在宏定义中的参数称为形式参数 , 在宏调用中的参数称为实际参数 。对带参数的宏 , 在调用中 , 不仅要宏展开 , 而且要用实参去代换形参 。带参宏定义的一般形式为:#define 宏名(形参表) 字元串在字元串中含有各个形参 。带参宏调用的一般形式为:宏名(形参表) 例如:#define M(y) ((y)*(y)+3*(y)) /*宏定义*/....k=M(5); /*宏调用*/....在宏调用时 , 用实参5去代替形参y , 经预处理宏展开后的语句为:k=5*5+3*5程式2:#define MAX(a,b) (a>b)?a:bmain(){int x,y,max;printf("input two numbers: ");scanf("%d%d",&x,&y);max=MAX(x,y);printf("max=%d\n",max);}上例程式的第一行进行带参宏定义 , 用宏名MAX表示条件表达式(a>b)?a:b , 形参a,b均条件表达式中 。程式第七行max=MAX(x,y)为宏调用 , 实参x,y , 将代换形参a,b 。宏展开后该语句为:max=(x>y)?x:y;用于计算x,y中的大数 。#define 条件编译头档案(.h)可以被头档案或C档案包含;重複包含(重複定义)由于头档案包含可以嵌套 , 那幺C档案就有可能包含多次同一个头档案 , 就可能出现重複定义的问题的 。通过条件编译开关来避免重複包含(重複定义)例如#ifndef __headerfileXXX__#define __headerfileXXX__…档案内容…#endif