文档库 最新最全的文档下载
当前位置:文档库 › 室分宏站RRU型号参数

室分宏站RRU型号参数

室分宏站RRU型号参数
室分宏站RRU型号参数

DRRU3168-fa 为双频段8 通道RRU,通常安装在室外高塔、桅杆等室外场所。DRRU3168-fa 可以同时支持TD-SCDMA/TD-LTE 两种制式双模工

作,最大支持的载波带宽为:

TDS 单模:27 载波(FA 频段内21 载波和A 频段内6 载波)

TDS-L 双模:20M+12 载波

TDL 单模:20M+10M+5M(F 频段)

DRRU3168-fa 工作频段:F 频段(1880MHz ~1915MHz)/A 频段(2010MHz ~2025MHz)。

DRRU3168-fa 的功耗(最大/平均):<520W/435W

DRRU3158e-fa 为双频段8 通道RRU,通常安装在室外高塔、桅杆等室外场所。DRRU3158e-fa 可以同时支持TD-SCDMA/TD-LTE 两种制式双模工

作,最大支持的载波带宽为:

TDS 单模:27 载波(FA 频段内21 载波和A 频段内6 载波)

TDS-L 双模:20M+12 载波

TDL 单模:20M+10M+5M(F 频段)

DRRU3158e-fa 工作频段:F 频段(1880MHz ~1920MHz)/A 频段(2010MHz ~2025MHz)。

DRRU3158e-fa 的功耗(最大/平均):<470W/390W。

RRU3158-fa 为双频段8 通道RRU,通常安装在室外高塔、桅杆等室外场所。DRRU3158-fa 可以同时支持TD-SCDMA/TD-LTE 两种制式双模工

作,最大支持的载波带宽为:

TDS 单模:18 载波

TDS-L 双模:20M+9 载波

DRRU3158-fa 工作频段:F 频段(1880MHz ~1910MHz)/A 频段(2010MHz ~2025MHz)。

DRRU3158-fa 的功耗(最大/平均):<470W/390W

DRRU3151-fae 为三频段1 通道RRU,通常用作室内覆盖,也可用作室外覆盖。DRRU3151-fae 可以同时支持TD-SCDMA/TD-LTE 两种制式双模工

作,最大支持的载波带宽为:

TDS 单模:30 载波(FA 频段内18 载波和E 频段内12 载波)

TDS-L 双模:20M+9 载波

DRRU3151-fae 工作频段:F 频段(1880MHz ~1915MHz)/A 频段(2010MHz ~2025MHz)/E 频段(2320MHz ~2370MHz)。

DRRU3151-fae 的功耗(最大/平均):<190W/170W

DRRU3151e-fae 为三频段1 通道RRU,通常用作室内覆盖,也可用作室外覆盖。DRRU3151e-fae 可以同时支持TD-SCDMA/TD-LTE 两种制式双模

工作,最大支持的载波带宽为:

TDS 单模:48 载波(FA 频段内27 载波和E 频段内21 载波)

TDS-L 双模:20M+12 载波(FA 频段), 2X20M+6 载波(E 频段)

TDL 单模:20M+10M+5M(F 频段),2X20M+10M(E 频段)

DRRU3151e-fae 工作频段:F 频段(1880MHz ~1915MHz)/A 频段(2010MHz ~

2025MHz)/E 频段(2320MHz ~2370MHz)。

DRRU3151e-fae 的功耗(最大/平均):<245W/210W。

DRRU3161-fae 为三频段1 通道RRU,通常用作室内覆盖,也可用作室外覆盖。

DRRU3161-fae 可以同时支持TD-SCDMA/TD-LTE 两种制式双模工

作,最大支持的载波带宽为:

TDS 单模:48 载波(FA 频段内27 载波和E 频段内21 载波)

TDS-L 双模:20M+12 载波(FA 频段), 2X20M+6 载波(E 频段)

TDL 单模:20M+10M+5M(F 频段),2X20M+10M(E 频段)

DRRU3161-fae 工作频段:F 频段(1880MHz ~1915MHz)/A 频段(2010MHz ~

2025MHz)/E 频段(2320MHz ~2370MHz)。

DRRU3161-fae 的功耗(最大/平均):<245W/210W。

3253,3257-d ,3172-fad,3152-e ,3172-fad

注意:

其中,3186-fa 3158-fa 3158e-fa 3253 3257-d 3172-fad用于宏站

3151-fae 3151e-fae 3161-fae 3152-e 3172-fad用于室分站

3172-fad也会用到室分,但主要是宏站。

3152-fa和3162-fa主要用于覆盲。

3253与3257-d都是d频段

3253用于LTE实验网。

除了d频段两个(3257-d 3172-fad)之外,其余RRU,结尾数字是1的,就是单通道,结尾是2的就是双通道,结尾是8的就是8通道。

3151-fa 3151-fae 3152-fa 需要在现场制作AC或者DC电源线的航空头。

防止小区接反措施:

必备工具:指北针,色环标签,设计图

1.安装前的规避:

施工前对照设计图用指北针确定小区方位角,天线以及RRU贴好对应标签。

做好光纤,电源线两端对应标示,贴好色环标签。

2.安装后的检查:(将BBU和RRU加电,用以下两个步骤方法排查)

1.直接拔对应小区光纤。让施工队注意观察BBU端Ir口指示灯是否变成红色,此

方法可以用来检测RRU光纤,扇区是否接反。

2.通过掉电检查。拔DCDU端对应RRU小区的电源,检查RRU,电源扇区是否接反。

3.若无法进机房检测。那么需要致电后台配合,方法同上两个步骤,只是BBU换成

后台了。

RRU上塔与不上塔:

RRU不上塔,通过16mm^2接地线接到塔体或者地排上,线长越短越好;

RRU上塔,接地线长不超过5m。(如果塔上没有接地排,用馈线固定夹固定在塔体做接地点)

第十五讲 宏定义

第十五讲宏定义、文件包含和条件编译 ?C语言提供的预处理功能主要有三种: 宏定义 文件包含 条件编译 ?为了区别预处理命令和C语句、定义和说明语句,规定: 预处理命令行必须在一行的开头; 必须以#开始; 每行末尾不能加分号。 1、宏定义 宏定义 1.1不带参数的宏定义 不带参数的宏定义命令形式为: #define 宏名字符串 或#define 宏名 #define的作用是用指定的标识符(宏名)来代表字符串。其中#define是宏定义命令,宏名是一个标识符。 【例】输入一个圆的半径,计算并输出圆的面积和周长 #define PI 3.14159 main( ) {float l,s,r; /*l:周长,s:面积,r:半径*/ printf("Please input radius: "); scanf("%f",&r); /*输入半径*/ l=2.0*r*PI; /*计算周长*/ s=PI*r*r; /*计算面积*/ printf("l=%10.4f\ns=%10.4f\n",l,s); } 说明: 为了与变量名区别,建议宏名一般用大写字母。使用宏名代替一个 字符串,目的一是减少程序中某些重复使用字符串的书写量,其二 是增加程序的可读性。在编译预处理过程中会进行宏展开。 当宏定义在一行中写不下,需要在下一行继续时,只需在最后一个 字符后紧接一个反斜线“\”。注意在第二行开始不要有空格,否则空 格会一起被替换。 例如:#define LEAP_YEAR year % 4==0\ && year %100!=0 || year % 400==0 在C语言中,宏定义一般写在程序开头。宏名的有效范围为定义命 令之后到本源文件结束,除非用#undef命令终止宏名的作用域。 对程序中用双引号括起来的字符串内的子串和用户标识符中的成分 不做替换。例如已定义: 同一个宏名不能重复定义,除非两个宏定义命令行完全一致。 1.2带参数的宏定义 形参表中的不同形参之间用逗号隔开,字符串中包含形参表中的参数,带参

宏定义的优缺点

宏定义的优缺点 其实在用VC编程的时候就会遇到很多宏定义,尤其是类似LONG,LPCTSTR等等之类的,它们属于微软的自定义类型,但其本质上还是属于C/C++里面的那几个标准类型。那用宏定义到底有什么好处呢? 先来看一下宏的定义:用#define命令将一个指定的标识符(即宏名)来代表一个字符串。它的一般型式为: #define 表示符字符串 #define命令属于“预处理命令”中的一种。它是由C++统一规定的,但非C++语言本身的组成部分,由于编译器无法识别他们,不能对其直接进行编译。预处理过程必须在对程序进行词法与语义分析、代码生成与优化等通常的编译过程之前进行,经过预处理后的程序不再包含之前的预处理命令。 C++提供的预处理功能除了宏定义之外,还有以下两个: 文件包含(#include命令) 条件编译(#ifdef …. #def …. #endif命令) #define命令还可以定义带参数的宏定义,用于实现某种特定的功能,其定义型式为: #define 宏名(参数列表) 字符串 例如:#define Sum(a,b) a+b 不过,由于C++增加了内联函数(inline),实现起来比带参数的宏更方便,这样的宏在C++中已经很少使用了。 接下来看看宏都有什么好处: 提高了程序的可读性,同时也方便进行修改; 提高程序的运行效率:使用带参的宏定义既可完成函数调用的功能,又能避免函数的出栈与入栈操作,减少系统开销,提高运行效率; 宏是由预处理器处理的,通过字符串操作可以完成很多编译器无法实现的功能。比如##连接符。 但是它也有自己的缺点: 由于是直接嵌入的,所以代码可能相对多一点;

define宏定义中的#,##,@#及符号

d efine宏定义中的#,##,@#及\符号(ZT) C++ STL学习2011-04-24 18:04:03 阅读19 评论0 字号:大中小订阅 1、# (stringizing)字符串化操作符。其作用是:将宏定义中的传入参数名转换成用一对双引号括起来参数名字符串。其只能用于有传入参数的宏定义中,且必须置于宏定义体中的参数名前。 如: #define example(instr) printf("the input string is:\t%s\n",#instr) #define example1(instr) #instr 当使用该宏定义时: example(abc);在编译时将会展开成:printf("the input string is:\t%s\n","abc"); string str=example1(abc);将会展成:string str="abc"; 注意: 对空格的处理 a。忽略传入参数名前面和后面的空格。 如:str=example1( abc );将会被扩展成str="abc"; b.当传入参数名间存在空格时,编译器将会自动连接各个子字符串,用每个子字符串中只以一个空格连接,忽略其中多余一个的空格。

如:str=exapme( abc def); 将会被扩展成str="abc def"; 2、## (token-pasting)符号连接操作符 宏定义中:参数名,即为形参,如#define sum(a,b) (a+b);中a和b 均为某一参数的代表符号,即形式参数。 而##的作用则是将宏定义的多个形参成一个实际参数名。 如: #define exampleNum(n) num##n int num9=9; 使用: int num=exampleNum(9); 将会扩展成int num=num9; 注意: 1.当用##连接形参时,##前后的空格可有可无。 如:#define exampleNum(n) num ## n 相当于#define exampleNum(n) num##n 2.连接后的实际参数名,必须为实际存在的参数名或是编译器已知的宏定义 // preprocessor_token_pasting.cpp

宏定义的作用

宏定义的作用 宏定义是C提供的三种预处理功能的其中一种,这三种预处理包括:宏定义、文件包含、 条件编译 编辑本段1.不带参数的宏定义: 宏定义又称为宏代换、宏替换,简称“宏”。 格式: #define 标识符字符串 其中的标识符就是所谓的符号常量,也称为“宏名”。 预处理(预编译)工作也叫做宏展开:将宏名替换为字符串。 掌握"宏"概念的关键是“换”。一切以换为前提、做任何事情之前先要换,准确理解之前就要 “换”。 即在对相关命令或语句的含义和功能作具体分析之前就要换: 例: #define PI 3.1415926 把程序中出现的PI全部换成3.1415926 说明: (1)宏名一般用大写 (2)使用宏可提高程序的通用性和易读性,减少不一致性,减少输入错误和便于修改。例 如:数组大小常用宏定义 (3)预处理是在编译之前的处理,而编译工作的任务之一就是语法检查,预处理不做语法 检查。 (4)宏定义末尾不加分号; (5)宏定义写在函数的花括号外边,作用域为其后的程序,通常在文件的最开头。 (6)可以用#undef命令终止宏定义的作用域 (7)宏定义可以嵌套 (8)字符串" "中永远不包含宏 (9)宏定义不分配内存,变量定义分配内存。 编辑本段2.带参数的宏定义: 除了一般的字符串替换,还要做参数代换 格式: #define 宏名(参数表)字符串 例如:#define S(a,b) a*b area=S(3,2);第一步被换为area=a*b; ,第二步被换为area=3*2; 类似于函数调用,有一个哑实结合的过程: (1)实参如果是表达式容易出问题 #define S(r) r*r area=S(a+b);第一步换为area=r*r;,第二步被换为area=a+b*a+b; 正确的宏定义是#define S(r) ((r)*(r)) (2)宏名和参数的括号间不能有空格 (3)宏替换只作替换,不做计算,不做表达式求解 (4)函数调用在编译后程序运行时进行,并且分配内存。宏替换在编译前进行,不分配内 存 (5)宏的哑实结合不存在类型,也没有类型转换。

宏定义中#等的用法

C语言宏定义中"#","#@"和"##"的用法一、引言 #define macro(a)#a #define macro2(a,b)a##b #define macro3(a,b,c)a##b##c #a,表示a不再是一个变量,而变成了字符串"a" ##表示连接,a##b,表示输入的参数名为ab,a##b##c同理,代表变量名为:abc 测试例子: int x=3; int y=4; int xy=10; int xyz=20; CString str; OutputDebugString(macro(x)); str.Format("%d",macro2(x,y)); OutputDebugString(str); str.Format("%d",macro3(x,y,z)); OutputDebugString(str); 输出结果为: x 10 20 第一个为x,marco(x),x变成了"x"字符串 第二个为10,macro(x,y),就是变量xy 第三个为20,macro(x,y,z),就是变量xyz 二、一般用法 #把宏参数变为一个字符串,#@把宏参数变为一个字符,##把两个宏参数贴合在一起。

#include #include #define STR(s)#s//#与参数之间可以有空格 #define TOCHAR(c)#@c #define CONS(a,b)int(a##e##b)//##与参数之间可以有空格 int main(void) { printf(STR(pele));//输出字符串"pele" printf("%c\n",TOCHAR(z));//输出字符z printf("%d\n",CONS(2,3));//2e3输出:2000 return0; } 三、当宏参数是另一个宏的时候 需要注意的是凡宏定义里有用'#'或'##'的地方宏参数是不会再展开的。 #define A(2) #define STR(s)#s #define CONS(a,b)int(a##e##b) printf("int max:%s\n",STR(INT_MAX)); 这行会被展开为: printf("int max:%s\n","INT_MAX"); printf("%s\n",CONS(A,A)); 这一行被展开为: printf("%s\n",int(AeA)); INT_MAX和A都不会再被展开,然而解决这个问题的方法很简单,多加一层中间转换宏。加这层宏的用意是把所有宏的参数在这层里全部展开,那么在转换宏里的那一个宏(_STR)就能得到正确的宏参数。 #define A(2) #define_STR(s)#s #define STR(s)_STR(s)//转换宏 #define_CONS(a,b)int(a##e##b) #define CONS(a,b)_CONS(a,b)//转换宏 printf("int max:%s\n",STR(INT_MAX)); 输出为:int max:0x7fffffff STR(INT_MAX)-->_STR(0x7fffffff)-->"0x7fffffff"

含参数的宏与函数的优缺点

1.函数调用时,先求出实参表达式的值,然后带入形参。而使用带参的宏只是进行简单的字符替换。 2.函数调用是在程序运行时处理的,分配临时的内存单元;而宏展开则是在编译时进行的,在展开时并不分配内存单元,不进行值的传递处理,也没有“返回值”的概念。 3.对函数中的实参和形参都要定义类型,二者的类型要求一致,如不一致,应进行类型转换;而宏不存在类型问题,宏名无类型,它的参数也无类型,只是一个符号代表,展开时带入指定的字符即可。宏定义时,字符串可以是任何类型的数据。 4.调用函数只可得到一个返回值,而用宏可以设法得到几个结果。 5.使用宏次数多时,宏展开后源程序长,因为每展开一次都使程序增长,而函数调用不使源程序变长。 6.宏替换不占运行时间,只占编译时间;而函数调用则占运行时间(分配单元、保留现场、值传递、返回)。 一般来说,用宏来代表简短的表达式比较合适。 内联函数和宏很类似,而区别在于,宏是由预处理器对宏进行替代,而内联函数是通过编译器控制来实现的。而且内联函数是真正的函数,只是在需要用到的时候,内联函数像宏一样的展开,所以取消了函数的参数压栈,减少了调用的开销。你可以象调用函数一样来调用内联函数,而不必担心会产生于处理宏的一些问题。 当然,内联函数也有一定的局限性。就是函数中的执行代码不能太多了,如果,内联函数的函数体过大,一般的编译器会放弃内联方式,而采用普通的方式调用函数。这样,内联函数就和普通函数执行效率一样了。内联函数是不能为虚函数的,但样子上写成了内联的,即隐含的内联方式。在某种情况下,虽然有些函数我们声明为了所谓“内联”方式,但有时系统也会把它当作普通的函数来处理,这里的虚函数也一样,虽然同样被声明为了所谓“内联”方式,但系统会把它当然非内联的方式来处理。

C宏定义

C/C++中宏使用总结 .C/C++中宏总结C程序的源代码中可包括各种编译指令,这些指令称为预处理命令。虽然它们实际上不是C语言的一部分,但却扩展了C程 序设计的环境。本节将介绍如何应用预处理程序和注释简化程序开发过程,并提高程序的可读性。ANSI标准定义的C语言预处理程序包括下列命令: #define,#error,#i nclude,#if,#else,#elif,#endif,#ifdef,#ifndef,#undef,#line,#pragma等。非常明显,所有预处理命令均以符号#开头,下面分别加以介绍。 1、#define 命令#define定义了一个标识符及一个串。在源程序中每次遇到该标识符时,均以定义的串代换它。ANSI标准将标识符定义为宏名,将替换过程称为宏 替换。命令的一般形式为: #define identifier string 注意: ? 该语句没有分号。在标识符和串之间可以有任意个空格,串一旦开始,仅由一新行结束。 ? 宏名定义后,即可成为其它宏名定义中的一部分。 ? 宏替换仅仅是以文本串代替宏标识符,前提是宏标识符必须独立的识别出来,否则不进行替换。例如:#define XYZ this is a test,使用宏printf("XYZ");//该段不打印"this is a test"而打印"XYZ"。因为预编译器识 别出的是"XYZ" ? 如果串长于一行,可以在该行末尾用一反斜杠' \'续行。

2、#error 处理器命令#error强迫编译程序停止编译,主要用于程序调试。 3、#i nclude 命令#i nclude使编译程序将另一源文件嵌入带有#i nclude的源文件,被读入的源文件必须用双引号或尖括号括起来。例如: #i nclude"stdio.h"或者#i nclude 这两行代码均使用C编译程序读入并编译用于处理磁盘文件库的子程序。 将文件嵌入#i nclude命令中的文件内是可行的,这种方式称为嵌套的嵌入文件,嵌套层次依赖于具体实现。 如果显式路径名为文件标识符的一部分,则仅在哪些子目录中搜索被嵌入文件。否则,如果文件名用双引号括起来,则首先检索当前工作目录。如果未发现文件, 则在命令行中说明的所有目录中搜索。如果仍未发现文件,则搜索实现时定义的标准目录。 如果没有显式路径名且文件名被尖括号括起来,则首先在编译命令行中的目录内检索。 如果文件没找到,则检索标准目录,不检索当前工作目录。 4、条件编译命令 有几个命令可对程序源代码的各部分有选择地进行编译,该过程称为条件编译。商业软件公司广泛应用条件编译来提供和维护某一程序的许多顾客版本。 #if、#else,#elif及#endif

宏定义

一、#define的基本用法 #define是C语言中提供的宏定义命令,其主要目的是为程序员在编程时提供一定的方便,并能在一定程度上提高程序的运行效率,但学生在学习时往往不能理解该命令的本质,总是在此处产生一些困惑,在编程时误用该命令,使得程序的运行与预期的目的不一致,或者在读别人写的程序时,把运行结果理解错误,这对 C语言的学习很不利。 1 #define命令剖析 1.1 #define的概念 #define命令是C语言中的一个宏定义命令,它用来将一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本。 该命令有两种格式:一种是简单的宏定义,另一种是带参数的宏定义。 (1)简单的宏定义: #define<宏名><字符串> 例:#define PI 3.1415926 (2) 带参数的宏定义 #define<宏名>(<参数表>)<宏体> 例:#define A(x) x 一个标识符被宏定义后,该标识符便是一个宏名。这时,在程序中出现的是宏名,在该程序被编译前,先将宏名用被定义的字符串替换,这称为宏替换,替换后才进行编译,宏替换是简单的替换。 1.2 宏替换发生的时机 为了能够真正理解#define的作用,让我们来了解一下对C语言源程序的处理过程。当我们在一个集成的开发环境如Turbo C中将编写好的源程序进行编译时,实际经过了预处理、编译、汇编和连接几个过程。其中预处理器产生编译器的输出,它实现以下的功能: (1)文件包含 可以把源程序中的#include 扩展为文件正文,即把包含的.h文件找到并展开到#include 所在处。 (2)条件编译 预处理器根据#if和#ifdef等编译命令及其后的条件,将源程序中的某部分包含进来或排除在外,通常把排除在外的语句转换成空行。 (3)宏展开 预处理器将源程序文件中出现的对宏的引用展开成相应的宏定义,即本文所说的#define的功能,由预处理器来完成。

C语言宏定义##连接符和#符的使用

C语言宏定义##连接符和#符的使用 C语言中如何使用宏C(和C++)中的宏(Macro)属于编译器预处理的范畴,属于编译期概念(而非运行期概念)。下面对常遇到的宏的使用问题做了简单总结。 关于#和## 在C语言的宏中,#的功能是将其后面的宏参数进行字符串化操作(Stringfication),简单说就是在对它所引用的宏变量通过替换后在其左右各加上一个双引号。比如下面代码中的宏: #define WARN_IF(EXP) do{ if (EXP) fprintf(stderr, "Warning: " #EXP "/n"); } while(0) 那么实际使用中会出现下面所示的替换过程: WARN_IF (divider == 0); 被替换为 do { if (divider == 0) fprintf(stderr, "Warning" "divider == 0" "/n"); } while(0); 这样每次divider(除数)为0的时候便会在标准错误流上输出一个提示信息。 而##被称为连接符(concatenator),用来将两个T oken连接为一个Token。注意这里连接的对象是T oken就行,而不一定是宏的变量。比如你要做一个菜单项命令名和函数指针组成的结构体的数组,并且希望在函数名和菜单项命令名之间有直观的、名字上的关系。那么下面的代码就非常实用: struct command { char * name; void (*function) (void); }; #define COMMAND(NAME) { NAME, NAME ## _command }

宏定义有参数跟没参数的区别

宏定义有无参数宏定义和带参数宏定义两种。 无参数的宏定义的一般形式为 # define 标识符字符序列 其中# define之后的标识符称为宏定义名(简称宏名),要求宏名与字符序列之间用空格符分隔。这种宏定义要求编译预处理程序将源程序中随后所有的定名的出现(注释与字符串常量中的除外)均用字符序列替换之。前面经常使用的定义符号常量是宏定义的最简单应用。如有:# define TRUE 1 # define FALSE 0 则在定义它们的源程序文件中,凡定义之后出现的单词TRUE将用1替代之;出现单词FALSE 将用0替代之。 在宏定义的#之前可以有若干个空格、制表符,但不允许有其它字符。宏定义在源程序中单独另起一行,换行符是宏定义的结束标志。如果一个宏定义太长,一行不够时,可采用续行的方法。续行是在键人回车符之前先键入符号"\"。注意回车要紧接在符号"\"之后,中间不能插入其它符号。 宏定义的有效范围称为宏定义名的辖域,辖域从宏定义的定义结束处开始到其所在的源程序文件末尾。宏定义名的辖域不受分程序结构的影响。可以用预处理命令#undef终止宏定义名的辖域。 在新的宏定义中,可以使用前面已定义的宏名。例如, # define R 2.5 # define PI 3.1415926 # define Circle 2*PI*R # define Area PI* R * R 程序中的Circle被展开为2*3.1415926* 2.5,Area被展开为3.1415926*2.5*2.5。 如有必要,宏名可被重复定义。被重复定义后,宏名原先的意义被新意义所代替。 通常,无参数的宏定义多用于定义常量。程序中统一用宏名表示常量值,便于程序前后统一,不易出错,也便于修改,能提高程序的可读性和可移植性。特别是给数组元素个数一个宏定义,并用宏名定义数组元素个数能部分弥补数组元素个数固定的不足。 注意:预处理程序在处理宏定义时,只作字符序列的替换工作,不作任何语法的检查。如果宏定义不当,错误要到预处理之后的编译阶段才能发现。宏定义以换行结束,不需要分号等符号作分隔符。如有以下定定义: # define PI 3.1415926; 原希望用PI求圆的周长的语句 c=2*PI*r; 经宏展开后,变成 c=2*3.1415926*r; 这就不能达到希望的要求。 带参数宏定义进一步扩充了无参数宏定义的能力,在字符序列替换同时还能进行参数替

C语言中的宏定义

https://www.wendangku.net/doc/5416257407.html,/24994073_d.html C语言中的宏定义 14.3 宏定义 我们从第2章以来使用的宏被称为简单的宏,它们没有参数。预编译器也支持带参数的宏。本节会先讨论简单的宏,然后再讨论带参数的宏。在分别讨论它们之后,我们会研究一下二者共同的特性。 14.3.1 简单的宏 简单的宏定义有如下格式: [#define指令(简单的宏)] #define 标识符替换列表 替换列表是一系列的C语言记号,包括标识符、关键字、数、字符常量、字符串字面量、运算符和标点符号。当预处理器遇到一个宏定义时,会做一个“标识符”代表“替换列表”的记录。在文件后面的内容中,不管标识符在任何位置出现,预处理器都会用替换列表代替它。 不要在宏定义中放置任何额外的符号,否则它们会被作为替换列表的一部分。一种常见的错误是在宏定义中使用 = : #define N = 100 /*** WRONG ***/ int a[N]; /* 会成为 int a[= 100]; */ 在上面的例子中,我们(错误地)把N定义成一对记号(= 和100)。 在宏定义的末尾使用分号结尾是另一个常见错误: #define N 100; /*** WRONG ***/ int a[N]; /* become int a[100;]; */ 这里N被定义为100和;两个记号。 在一个宏定义中,编译器可以检测到绝大多数由多余符号所导致的错误。但不幸的是,编译器会将每一处使用这个宏的地方标为错误, 而不会直接找到错误的根源——宏定义本身,因为宏定义已经被预处

理器删除了。 简单的宏主要用来定义那些被Kernighan和Ritchie称为“明示常量”(manifest constant)的东西。使用宏,我们可以给数值、字符和字符串命名。 #define STE_LEN 80 #define TRUE 1 #define FALSE 0 #define PI 3.14159 #define CR '\r' #define EOS '\0' 使用#define来为常量命名有许多显著的优点: l 程序会更易读。一个认真选择的名字可以帮助读者理解常量的意义。否则,程序将包含大量的“魔法数”,使读者难以理解。 l 程序会更易于修改。我们仅需要改变一个宏定义,就可以改变整个程序中出现的所有该常量的值。“硬编码的”常量会更难于修改,特别是有时候当他们以稍微不同的形式出现时。(例如,如果一个程序包含一个长度为100的数组,它可能会包含一个从0到99的循环。如果我们只是试图找到所有程序中出现的100,那么就会漏掉99。) l 可以帮助避免前后不一致或键盘输入错误。假如数值常量3.14159在程序中大量出现,它可能会被意外地写成3.1416或3.14195。 虽然简单的宏常用于定义常量名,但是它们还有其他应用。 l 可以对C语法做小的修改。实际上,我们可以通过定义宏的方式给C语言符号添加别名,从而改变C语言的语法。例如,对于习惯使用Pascal的begin和end (而不是C语言的{和})的程序员,可以定义下面的宏: #define BEGIN { #define END } 我们甚至可以发明自己的语言。例如,我们可以创建一个LOOP“语句”,来实现一个无限循环: #define LOOP for (;;) 当然,改变C语言的语法通常不是个好主意,因为它会使程序很难被其他程序员所理解。 l 对类型重命名。在5.2节中,我们通过重命名int创建了一个Boolean类型:#define BOOL int

第九章编译预处理与带参数的主函数

第九章编译预处理与带参数的主函数 一、单项选择题 1.C程序中,以#号带头的行是预编译(A)。 A.命令 B.语句 C.函数 D.字符串 2.下列正确的预编译命令是(B)。 A.define PI 3.14159 B.#define p(a,b) strcpy(a,b) C. #include stdio.h D. # define PI3.14159 3.下列命令或语句中,正确的是(C)。 A.#define MYNAME= “ABC” B.#include stdio.h C. for(i=0;i<10;i++); D.struct int stu{int name}; 4.下列命令或语句中,正确的是(A)。 A.#define PI 3.14159 B. include “stdio.h” C.for(i=0,i<10,i++)a++ D.static struct {int i;}b={2}; 5.下列命令或语句中,错误的是(B)。 A. #define PI 3.14159 B.#include C.if(2); D.for(; ;) if(1) break; 6.定义带参数的宏计算两式乘积(如x2+3x-5与x-6),下列定义中哪个是正确的(C)。 A.#define muit(u,v)u*v B.#define muit(u,v)u*v; C.#define muit(u,v)(u)*(v) D.#define muit(u,v)=(u)*(v) 7.宏定义#define div(a,b) a/b的引用div(x+5,y-5)替换展开后是(A)。 A.x+5/y-5 B.x+5/y-5; C.(x+5)/(y-5) D.(x+5)/(y-5); 8.定义带参数的宏“#define jh(a,b,t)t=a;a=b;b=t”,使两个参数a、b的值交换,下列表述中哪个是正确的(D)。 A.不定义参数a和b将导致编译错误 B.不定义参数a、b、t将导致编译错误 C.不定义参数t将导致运行错误 D.不必定义参数a、b、t类型 9.设有宏定义#define AREA(a,b) a*b,则正确的“宏调用”是(D)。 A.s=AREA(r*r) B.s=AREA(x*y) C.s=AREA D.s=c*AREA((x+3.5),(y+4.1)) 10.设有以下宏定义,则执行语句z=2*(N+Y(5+1));后,z的值为(C)。 #define N 3 #define Y(n) ((N+1)*n) A.出错 B.42 C.48 D.54 11.设有以下宏定义,int x,m=5, n=1时,执行语句IFABC(m+n,m,x);后,x的值为(B)。 #define IFABC(a,b,c) c=a>b?a:b A.5 B.6 C.11 D.出错 12.以下程序中的for循环执行的次数是(C)。 #include “stdio.h” #define N 2 #define M N+1 # define NUM (M+1)*M/2 void main( ) { int i,n=0;

C语言里常用的宏定义

01: 防止一个头文件被重复包含 #ifndef COMDEF_H #define COMDEF_H //头文件内容 #endif 02: 重新定义一些类型 防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植。 typedef unsigned char boolean; /* Boolean value type. */ typedef unsigned long int uint32; /* Unsigned 32 bit value */ typedef unsigned short uint16; /* Unsigned 16 bit value */ typedef unsigned char uint8; /* Unsigned 8 bit value */ typedef signed long int int32; /* Signed 32 bit value */ typedef signed short int16; /* Signed 16 bit value */ typedef signed char int8; /* Signed 8 bit value */ //下面的不建议使用 typedef unsigned char byte; /* Unsigned 8 bit value type. */ typedef unsigned short word; /* Unsinged 16 bit value type. */ typedef unsigned long dword; /* Unsigned 32 bit value type. */ typedef unsigned char uint1; /* Unsigned 8 bit value type. */ typedef unsigned short uint2; /* Unsigned 16 bit value type. */ typedef unsigned long uint4; /* Unsigned 32 bit value type. */ typedef signed char int1; /* Signed 8 bit value type. */ typedef signed short int2; /* Signed 16 bit value type. */ typedef long int int4; /* Signed 32 bit value type. */ typedef signed long sint31; /* Signed 32 bit value */ typedef signed short sint15; /* Signed 16 bit value */ typedef signed char sint7; /* Signed 8 bit value */ 03: 得到指定地址上的一个字节或字 #define MEM_B(x) (*((byte *)(x))) #define MEM_W(x) (*((word *)(x))) 04: 求最大值和最小值 #define MAX(x,y) (((x)>(y)) ? (x) : (y)) #define MIN(x,y) (((x) < (y)) ? (x) : (y)) 05: 得到一个field在结构体(struct)中的偏移量 #define FPOS(type,field) ((dword)&((type *)0)->field) 06: 得到一个结构体中field所占用的字节数

关于宏定义带参数可能会出现的分号错误问题

关于带参宏定义 By: T7 Date:20170917 (看此文章需要明白#define 的基础“替代”功能) #define add(A) (A)+(A) Int s; S = add(30); //s = (30)+(30) = 60 带参宏,是起到替代的作用 观察下列定义: 第一处: #define LED(a) if (a) \ GPIO_ResetBits(GPIOC, GPIO_Pin_13) \ else \ GPIO_SetBits(GPIOC, GPIO_Pin_13) 第二处: #define LED0(a) if (a) \ GPIO_SetBits(GPIOC,GPIO_Pin_0);\ else \ GPIO_ResetBits(GPIOC,GP IO_Pin_0) 当在函数中调用: LED(1); //此处将会出错,如下图

LED0(1); //不会出错 原因: 第一句:LED(1); 在程序中展开为: If(1) GPIO_ResetBits(GPIOC,GPIO_Pin_13) //此处被执行 Else GPIO_SetBits(GPIOC,GPIO_Pin_13) LED(1);相当于语句GPIO_ResetBits(GPIOC,GPIO_Pin_13) 第二句:LED0(1); If(1) GPIO_SetBits(GPIOC,GPIO_Pin_0); //此处被执行 Else GPIO_SetBits(GPIOC,GPIO_Pin_13) LED0(1);相当于语句GPIO_ResetBits(GPIOC,GPIO_Pin_13); 观察上述展开后的标红被执行的语句,可以看到第一句少了一个分号,故出错“expected a “;””而第二句则正常。 同理当调用 第一句:LED(0); 在程序中展开为: If(0) GPIO_ResetBits(GPIOC,GPIO_Pin_13) Else GPIO_SetBits(GPIOC,GPIO_Pin_13) //此处被执行 “LED(0)”相当于语句GPIO_ResetBits(GPIOC,GPIO_Pin_13) 同时又由于#defien 的替代作用,“LED(0);”会被替代为“GPIO_ResetBits(GPIOC,GPIO_Pin_13);”,故不会出现分号的问题。

C语言宏定义

写好C语言,漂亮的宏定义很重要,使用宏定义可以防止出错,提高可移植性,可读性,方便性等等。下面列举一些成熟软件中常用得宏定义。。。。。。 1,防止一个头文件被重复包含 #ifndef COMDEF_H #define COMDEF_H //头文件内容 #endif 2,重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植。 typedef unsigned char boolean; /* Boolean value type. */ typedef unsigned long int uint32; /* Unsigned 32 bit value */ typedef unsigned short uint16; /* Unsigned 16 bit value */ typedef unsigned char uint8; /* Unsigned 8 bit value */ typedef signed long int int32; /* Signed 32 bit value */ typedef signed short int16; /* Signed 16 bit value */ typedef signed char int8; /* Signed 8 bit value */ //下面的不建议使用 typedef unsigned char byte; /* Unsigned 8 bit value type. */ typedef unsigned short word; /* Unsinged 16 bit value type. */ typedef unsigned long dword; /* Unsigned 32 bit value type. */ typedef unsigned char uint1; /* Unsigned 8 bit value type. */ typedef unsigned short uint2; /* Unsigned 16 bit value type. */ typedef unsigned long uint4; /* Unsigned 32 bit value type. */ typedef signed char int1; /* Signed 8 bit value type. */ typedef signed short int2; /* Signed 16 bit value type. */ typedef long int int4; /* Signed 32 bit value type. */ typedef signed long sint31; /* Signed 32 bit value */ typedef signed short sint15; /* Signed 16 bit value */ typedef signed char sint7; /* Signed 8 bit value */ 3,得到指定地址上的一个字节或字 #define MEM_B( x ) ( *( (byte *) (x) ) ) #define MEM_W( x ) ( *( (word *) (x) ) ) 4,求最大值和最小值 #define MAX( x, y ) ( ((x) > (y)) ? (x) : (y) ) #define MIN( x, y ) ( ((x) < (y)) ? (x) : (y) ) 5,得到一个field在结构体(struct)中的偏移量 #define FPOS( type, field ) \ /*lint -e545 */ ( (dword) &(( type *) 0)-> field ) /*lint +e545 */ 6,得到一个结构体中field所占用的字节数 #define FSIZ( type, field ) sizeof( ((type *) 0)->field ) 7,按照LSB格式把两个字节转化为一个Word #define FLIPW( ray ) ( (((word) (ray)[0]) * 256) + (ray)[1] ) 8,按照LSB格式把一个Word转化为两个字节 #define FLOPW( ray, val ) \

51单片机的C语言宏定义应用

1、预编译处理是单片机C语言程序设计中经常用到的一种方法。通过一些预处理命令可以为C语言本身提供许多功能和符号的扩充,增强C语言程序的灵活性和方便性。 常用的预处理命令有:宏定义、文件包含、条件编译等。在C语言程序中,预编译命令一般以”#“开头。 2、在本实例中,我们将对宏定义命令做一个简单的了解。 C语言中允许用一个标识符来表示一个字符串,称为宏。标识符称为宏名,进行过宏定义后,宏定义语句以下的程序里面,都可以用该标识符来代替被定义的字符串。 宏定义语句以”define“关键字来定义,宏定义分为带参数的宏定义和不带参数的宏定义。1)不带参数的宏定义的格式如下: #define 标识符字符串 例如:在程序中定义了如下宏语句#define PI 3.1415926,那么在这一行的后面的程序中,都可以用PI来代替3.1415926这个数值。 ?宏定义不是C语言中的语句,所以不能在行末加分号 ?宏名的有效范围为该宏名定义之后到程序结束。 ?通常#define命令写在整个程序文件的开头,在函数声明部分之前,这样可以使该宏定义在整个程序文件内有效 ?可以用#undef命令种植宏的作用域,如下所示: ?#define r 5600 .... main() {

..... } ..... #undef r four() { .... } 由于#undef的作用,在函数four()中,r将不再代表5600这个数。这样可以灵活控制宏的应用范围 宏名一般采用大写字母 2)带参数宏定义格式如下 #define 宏名(参数)字符串 在这里,不再只是简单的字符串替换了,而是包括了参数的替换。 3、下面以一个实例来演示带参数的宏定义和不带参数的宏定义 本里仍然使用我们前面学过的流水灯实例的原理图。

带参数的宏定义#define

9.1.2 带参数的宏定义 带参数的宏定义的一般形式如下: #define <宏名>(<参数表>) <宏体> 其中, <宏名>是一个标识符,<参数表>中的参数可以是一个,也可以是多个,视具体情况而定,当有多个参数的时候,每个参数之间用逗号分隔。<宏体>是被替换用的字符串,宏体中的字符串是由参数表中的各个参数组成的表达式。例如: #define SUB(a,b) a-b 如果在程序中出现如下语句: result=SUB(2, 3) 则被替换为: result=2-3; 如果程序中出现如下语句: result= SUB(x+1, y+2); 则被替换为: result=x+1-y+2; 在这样的宏替换过程中,其实只是将参数表中的参数代入到宏体的表达式中去,上述例子中,即是将表达式中的a和b分别用2和3代入。 我们可以发现:带参的宏定义与函数类似。如果我们把宏定义时出现的参数视为形参,而在程序中引用宏定义时出现的参数视为实参。那么上例中的a和b就是形参,而2和3以及x+1和y+2都为实参。在宏替换时,就是用实参来替换<宏体>中的形参。 下面是带参数的宏定义的例子: 例9-4 #include #define SUB(a,b) a-b void main () { int x,y,result; x=2; y=3; result=SUB(x+2,y-1); cout<< "result="<

相关文档