c语言中define的用法

c语言中define的用法,第1张

C语言是计算机软件领域非常经典的编程语言,unix、linux等众多 *** 作系统均是由C语言编写而成。而在硬件控制、底层驱动等应用领域,C语言更是具有不可替代的作用。下面我就跟你们详细介绍下c语言中define的用法,希望对你们有用。

c语言中define的用法如下:

#define是C语言中提供的宏定义命令,其主要目的是为程序员在编程时提供一定的方便,并能在一定程度上提高程序的运行效率,但学生在学习时往往不能 理解该命令的本质,总是在此处产生一些困惑,在编程时误用该命令,使得程序的运行与预期的目的不一致,或者在读别人写的程序时,把运行结果理解错误,这对 C语言的学习很不利。

1 #define命令剖析

11 #define的概念

#define命令是C语言中的一个宏定义命令,它用来将一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本。

该命令有两种格式:一种是简单的宏定义,另一种是带参数的宏定义。

(1) 简单的宏定义:

#define <宏名><字符串>

例: #define PI 31415926

(2) 带参数的宏定义

#define <宏名> (<参数表>) <宏体>

例: #define A(x) x

一个标识符被宏定义后,该标识符便是一个宏名。这时,在程序中出现的是宏名,在该程序被编译前,先将宏名用被定义的字符串替换,这称为宏替换,替换后才进行编译,宏替换是简单的替换。

12 宏替换发生的时机

为了能够真正理解#define的作用,让我们来了解一下对C语言源程序的处理过程。当我们在一个集成的开发环境如Turbo C中将编写好的源程序进行编译时,实际经过了预处理、编译、汇编和连接几个过程,见图1。

源程序预处理器修改后的源程序编译器汇编程序汇编器可重定位的目标程序连接器可执行的目标程序图1 C语言的编译过程

其中预处理器产生编译器的输出,它实现以下的功能:

(1) 文件包含

可以把源程序中的#include 扩展为文件正文,即把包含的h文件找到并展开到#include 所在处。

(2) 条件编译

预处理器根据#if和#ifdef等编译命令及其后的条件,将源程序中的某部分包含进来或排除在外,通常把排除在外的语句转换成空行。

(3) 宏展开

预处理器将源程序文件中出现的对宏的引用展开成相应的宏 定义,即本文所说的#define的功能,由预处理器来完成。

经过预处理器处理的源程序与之前的源程序有所有不同,在这个阶段所进行的工作只是纯粹的替换与展开,没有任何计算功能,所以在学习#define命令时只要能真正理解这一点,这样才不会对此命令引起误解并误用。

2 #define使用中的常见问题解析

21 简单宏定义使用中出现的问题

在简单宏定义的使用中,当替换文本所表示的字符串为一个表达式时,容易引起误解和误用。如下例:

例1 #define N 2+2

void main()

{

int a=NN;

printf(“%d”,a);

}

(1) 出现问题:在此程序中存在着宏定义命令,宏N代表的字符串是2+2,在程序中有对宏N的使用,一般同学在读该程序时,容易产生的问题是先求解N为2+2=4,然后在程序中计算a时使用乘法,即NN=44=16,其实该题的结果为8,为什么结果有这么大的偏差

(2)问题解析:如1节所述,宏展开是在预处理阶段完成的,这个阶段把替换文本只是看作一个字符串,并不会有任何的计算发生,在展开时是在宏N出现的地方 只是简单地使用串2+2来代替N,并不会增添任何的符号,所以对该程序展开后的结果是a=2+22+2,计算后=8,这就是宏替换的实质,如何写程序才 能完成结果为16的运算呢?

(3)解决办法:将宏定义写成如下形式

#define N (2+2)

这样就可替换成(2+2)(2+2)=16

22 带参数的宏定义出现的问题

在带参数的宏定义的使用中,极易引起误解。例如我们需要做个宏替换能求任何数的平方,这就需要使用参数,以便在程序中用实际参数来替换宏定义中的参数。一般学生容易写成如下形式:

#define area(x) xx

这在使用中是很容易出现问题的,看如下的程序

void main()

{

int y=area(2+2);

printf(“%d”,y);

}

按理说给的参数是2+2,所得的结果应该为44=16,但是错了,因为该程序的实际结果为8,仍然是没能遵循纯粹的简单替换的规则,又是先计算再替换 了,在这道程序里,2+2即为area宏中的参数,应该由它来替换宏定义中的x,即替换成2+22+2=8了。那如果遵循(1)中的解决办法,把2+2 括起来,即把宏体中的x括起来,是否可以呢?#define area(x) (x)(x),对于area(2+2),替换为(2+2)(2+2)=16,可以解决,但是对于area(2+2)/area(2+2)又会怎么样 呢,有的学生一看到这道题马上给出结果,因为分子分母一样,又错了,还是忘了遵循先替换再计算的规则了,这道题替换后会变为 (2+2)(2+2)/(2+2)(2+2)即44/44按照乘除运算规则,结果为16/44=44=16,那应该怎么呢?解决方法是在整个 宏体上再加一个括号,即#define area(x) ((x)(x)),不要觉得这没必要,没有它,是不行的。

要想能够真正使用好宏定义,那么在读别人的程序时,一定要记住先将程序中对宏的使用全部替换成它所代表的字符串,不要自作主张地添加任何其他符号,完全展 开后再进行相应的计算,就不会写错运行结果。如果是自己编程使用宏替换,则在使用简单宏定义时,当字符串中不只一个符号时,加上括号表现出优先级,如果是 带参数的宏定义,则要给宏体中的每个参数加上括号,并在整个宏体上再加一个括号。看到这里,不禁要问,用宏定义这么麻烦,这么容易出错,可不可以摒弃它, 那让我们来看一下在C语言中用宏定义的好处吧。

3 宏定义的优点

(1) 方便程序的修改

使用简单宏定义可用宏代替一个在程序中经常使用的常量,这样在将该常量改变时,不用对整个程序进行修改,只修改宏定义的字符串即可,而且当常量比较长时, 我们可以用较短的有意义的标识符来写程序,这样更方便一些。我们所说的常量改变不是在程序运行期间改变,而是在编程期间的修改,举一个大家比较熟悉的例 子,圆周率π是在数学上常用的一个值,有时我们会用314来表示,有时也会用31415926等,这要看计算所需要的精度,如果我们编制的一个程序中 要多次使用它,那么需要确定一个数值,在本次运行中不改变,但也许后来发现程序所表现的精度有变化,需要改变它的值, 这就需要修改程序中所有的相关数值,这会给我们带来一定的不便,但如果使用宏定义,使用一个标识符来代替,则在修改时只修改宏定义即可,还可以减少输入 31415926这样长的数值多次的情况,我们可以如此定义 #define pi 31415926,既减少了输入又便于修改,何乐而不为呢?

(2) 提高程序的运行效率

使用带参数的宏定义可完成函数调用的功能,又能减少系统开 销,提高运行效率。正如C语言中所讲,函数的使用可以使程序更加模块化,便于组织,而且可重复利用,但在发生函数调用时,需要保留调用函数的现场,以便子 函数执行结束后能返回继续执行,同样在子函数执行完后要恢复调用函数的现场,这都需要一定的时间,如果子函数执行的 *** 作比较多,这种转换时间开销可以忽 略,但如果子函数完成的功能比较少,甚至于只完成一点 *** 作,如一个乘法语句的 *** 作,则这部分转换开销就相对较大了,但使用带参数的宏定义就不会出现这个问 题,因为它是在预处理阶段即进行了宏展开,在执行时不需要转换,即在当地执行。宏定义可完成简单的 *** 作,但复杂的 *** 作还是要由函数调用来完成,而且宏定义 所占用的目标代码空间相对较大。所以在使用时要依据具体情况来决定是否使用宏定义。

形式参数不能用带引号的字符串替换。

但是,如果在替换文本中,参数名以#作为前缀则结果将被扩展为 由 实际参数 替换 此实际参数的带引号的字符串。

例如,可以将它与字符串连接运算结合起来编写一个调试打印宏:

#define dprint(expr) printf(#expr “ = %\n”,expr)

使用语句 dprint(x/y);

调用宏时,该宏将被扩展为:printf(“x/y”“ = %\n”,x/y);

其中的字符串被连接起来了,这样便等价于printf(“x/y = %\n”,x/y);

在实际参数中,每个双引号 “ 将被替换为 \” ;反斜杠\将被替换为\\,因此替换后的字符串是合法的字符串常量。

预处理运算符 ## 为宏扩展提供了一种连接实际参数的手段。如果替换文本中的参数与 ## 相邻,则该参数将被实际参数替换,##与前后的空白符将被删除,并对替换后的结果重新扫描。

例如,下面定义的宏paste用于连接两个参数

#define paste(front, back) front ## back

因此,宏调用past(name,1)的结果将建立记号name1

c语言中没有swap这个函数,C语言不支持重载,也没有模版的概念,所以对于每一种类型,都要写出相应的swap,如

intSwap (int , int );

longSwap (long , long );

stringSwap (char , char );

宏定义swap(t,x,y)以交换t类型的两个参数(要使用程序块结构)。

程序如下:

#include <iostreamh>

#define SWAP(t,x,y) \

{\

t temp = y;\

y = x;\

x = temp;\

}

main()

{

int a = 10, b = 5;

SWAP(int,&a,&b)

cout << a << endl << b<<endl;

}

用\换行,\的意思是说把下一行看作和这行是同一行换行必须要反斜杠,而且\後面直接回车,不能有空格。

电脑与外部设备的通讯可以通过串口、并口、USB等接口实现。其实用单片机做要简单。

首先要知道什么是RS232和RS485吧

典型的串行通讯标准是RS232和RS485它们定义了电压,阻抗等但不对软件协议给予定义

区别于RS232, RS485的特性包括:

1 RS-485的电气特性:逻辑“1”以两线间的电压差为+(2—6) V表示;逻辑“0”以两线间的电压差为-(2—6)V表示。接口信号电平比RS -232-C降低了,就不易损坏接口电路的芯片,且该电平与TTL电平兼容,可方便与TTL 电路连接。

2 RS-485的数据最高传输速率为10Mbps

3 RS-485接口是采用平衡驱动器和差分接收器的组合,抗共模干能力增强,即抗噪声干扰性好。

4 RS-485接口的最大传输距离标准值为4000英尺,实际上可达 3000米,另外RS-232-C接口在总线上只允许连接1个收发器,即单站能力。而 RS-485接口在总线上是允许连接多达128个收发器。即具有多站能力,这样用户可以利用单一的RS-485接口方便地建立起设备网络。 因RS-485接口具有良好的抗噪声干扰性,长的传输距离和多站能力等上述优点就使其成为首选的串行接口。因为RS485接口组成的半双工网络 ,一般只需二根连线,所以RS485接口均采用屏蔽双绞线传输。 RS485接口连接器采用DB-9的9芯插头座,与智能终端RS485接口采用DB-9(孔) ,与键盘连接的键盘接口RS485采用DB-9(针)。

RS485编程

串口协议只是定义了传输的电压,阻抗等,编程方式和普通的串口编程一样!!

RS-232与RS-422之间转换原理和接法

通常我们对于视频服务器、录像机、切换台等直接播出、切换控制主要使用串口进行,主要使用到RS-232、RS-422与RS-485三种接口控制。下面就串口的接口标准以及使用和外部插件和电缆进行探讨。

RS-232、RS-422与RS-485标准只对接口的电气特性做出规定,而不涉及接插件、电缆或协议,在此基础上用户可以建立自己的高层通信协议。例如:视频服务器都带有多个RS422串行通讯接口,每个接口均可通过RS422通讯线由外部计算机控制实现记录与播放。 视频服务器除提供各种控制硬件接口外,还提供协议接口,如RS422接口除支持RS422的Profile协议外,还支持 Louth、Odetics 、BVW等通过RS422控制的协议。

RS-232、RS-422与RS-485都是串行数据接口标准,都是由电子工业协会(EIA)制订并发布的,RS-232在1962年发布。RS-422由RS-232发展而来,为改进RS-232通信距离短、速率低的缺点,RS-422定义了一种平衡通信接口,将传输速率提高到10Mbps,传输距离延长到4000英尺(速率低于100Kbps时),并允许在一条平衡总线上连接最多10个接收器。RS-422是一种单机发送、多机接收的单向、平衡传输规范,被命名为TIA/EIA-422-A标准。为扩展应用范围,EIA又于1983年在RS-422基础上制定了RS-485标准,增加了多点、双向通信能力,即允许多个发送器连接到同一条总线上,同时增加了发送器的驱动能力和冲突保护特性,扩展了总线共模范围,后命名为TIA/EIA-485-A标准。

1 S-232串行接口标准

目前RS-232是PC机与通信工业中应用最广泛的一种串行接口。RS-232被定义为一种在低速率串行通讯中增加通讯距离的单端标准。RS-232采取不平衡传输方式,即所谓单端通讯。收、发端的数据信号是相对于信号地。典型的RS-232信号在正负电平之间摆动,在发送数据时,发送端驱动器输出正电平在+5~+15V,负电平在-5~-15V电平。当无数据传输时,线上为TTL,从开始传送数据到结束,线上电平从TTL电平到RS-232电平再返回TTL电平。接收器典型的工作电平在+3~+12V与-3~-12V。由于发送电平与接收电平的差仅为2V至3V左右,所以其共模抑制能力差,再加上双绞线上的分布电容,其传送距离最大为约15米,最高速率为20Kbps。RS-232是为点对点(即只用一对收、发设备)通讯而设计的,其驱动器负载为3kΩ~7kΩ。所以RS-232适合本地设备之间的通信。

2 RS-422与RS-485串行接口标准

(1)平衡传输

RS-422、RS-485与RS-232不一样,数据信号采用差分传输方式,也称作平衡传输,它使用一对双绞线,将其中一线定义为A,另一线定义为B。通常情况下,发送驱动器A、B之间的正电平在+2~+6V,是一个逻辑状态,负电平在-2V~6V,是另一个逻辑状态。另有一个信号地C,在RS-485中还有一“使能”端,而在RS-422中这是可用可不用的。“使能”端是用于控制发送驱动器与传输线的切断与连接。当“使能”端起作用时,发送驱动器处于高阻状态,称作“第三态”,即它是有别于逻辑“1”与“0”的第三态。

(2)RS-422电气规定

由于接收器采用高输入阻抗和发送驱动器比RS232更强的驱动能力,故允许在相同传输线上连接多个接收节点,最多可接10个节点。即一个主设备(Master),其余为从设备(Salve),从设备之间不能通信,所以RS-422支持点对多的双向通信。RS-422四线接口由于采用单独的发送和接收通道,因此不必控制数据方向,各装置之间任何必须的信号交换均可以按软件方式(XON/XOFF握手)或硬件方式(一对单独的双绞线)实现。RS-422的最大传输距离为4000英尺(约1219米),最大传输速率为10Mbps。其平衡双绞线的长度与传输速率成反比,在100Kbps速率以下,才可能达到最大传输距离。只有在很短的距离下才能获得最高速率传输。一般100米长的双绞线上所能获得的最大传输速率仅为1Mbps。RS-422需要一终接电阻,要求其阻值约等于传输电缆的特性阻抗。在矩距离传输时可不需终接电阻,即一般在300米以下不需终接电阻。终接电阻接在传输电缆的最远端。

(3)RS-485电气规定

由于RS-485是从RS-422基础上发展而来的,所以RS-485许多电气规定与RS-422相仿。如都采用平衡传输方式、都需要在传输线上接终接电阻等。RS-485可以采用二线与四线方式,二线制可实现真正的多点双向通信。RS-485总线,在要求通信距离为几十米到上千米时,广泛采用RS-485 串行总线标准。RS-485采用平衡发送和差分接收,因此具有抑制共模干扰的能力。加上总线收发器具有高灵敏度,能检测低至200mV的电压,故传输信号能在千米以外得到恢复。 RS-485采用半双工工作方式,任何时候只能有一点处于发送状态,因此,发送电路须由使能信号加以控制。RS-485用于多点互连时非常方便,可以省掉许多信号线。应用RS-485 可以联网构成分布式系统,其允许最多并联32台驱动器和32台接收器。 RS-485与RS-422的不同还在于其共模输出电压是不同的,RS-485是-7V至+12V之间,而RS-422在-7V至+7V之间;RS-485满足所有RS-422的规范,所以RS-485的驱动器可以用在RS-422网络中应用。RS-485与RS-422一样,其最大传输距离约为1219米,最大传输速率为10Mbps。平衡双绞线的长度与传输速率成反比,在100Kbps速率以下,才可能使用规定最长的电缆长度。只有在很短的距离下才能获得最高速率传输。一般100米长双绞线最大传输速率仅为1Mbps。

(4)RS-422与RS-485的网络安装注意要点

RS-422可支持10个节点,RS-485支持32个节点,因此多节点构成网络。网络拓扑一般采用终端匹配的总线型结构,不支持环形或星形网络。在构建网络时,应注意如下几点:

采用一条双绞线电缆作总线,将各个节点串接起来,从总线到每个节点的引出线长度应尽量短,以便使引出线中的反射信号对总线信号的影响最低。

应注意总线特性阻抗的连续性,在阻抗不连续点就会发生信号的反射。下列几种情况易产生这种不连续性:总线的不同区段采用了不同电缆,或某一段总线上有过多收发器紧靠在一起安装,再者是过长的分支线引出到总线。

总之,应该提供一条单一、连续的信号通道作为总线。

二 串口插口种类及转换

串口是一种接口标准,它规定了接口的电气标准,简单说只是物理层的一个标准。没有规定接口插件电缆以及使用的协议,所以只要我们使用的接口插件电缆符合串口标准就可以在实际中灵活使用,在串口接口标准上使用各种协议进行通讯及设备控制。

以上我们了解了串口的协议,而我们日常工作中接触最多的是实际的一些设备的外部接口,我们如何从外形上就知道它是那种接口呢?制作线缆各针脚如何定义?上面我们知道了串口RS-232、RS-422与RS-485标准只对接口的电气特性做出规定,而不涉及接插件、电缆或协议,在此基础上用户可以建立自己的高层通信协议。从我们实际工作中碰到的使用最多的插口有三种DB9 DB25 RJ45,上面三种插口插件都可以用作串口插口插件,也可以通过线缆进行插口之间的转换。下面我们就三种插口的针脚定义分别说明,三个插口之间的转换也只要按照插口定义的线缆跳接即可。

DB9(9脚插口插座),如图2。9针串口功能如表1。

DB25(25脚插口插座),如图3。25针串口功能如表2。

还有一种插口是RJ45,比如湖北台使用的品尼高mss1600、mss700视频服务器的编解码板控制口都为串口,插口是RJ45的,而播控机的串口插口是DB9,因此我们就需要使用转换线缆。转换线缆的针脚定义如图4。

RS485 半双工接法为:RX+ 和TX+ 并联为Data+;RX- 和TX- 并联为Data-。RS485 全双工/RS422 接法为:FULL 和GND 短接;信号线为RX+,TX+,RX-,TX-,可根据需要连接GND。

三 串口的扩展

串口的扩展,我们知道一般一台计算机有两个串口,而对于一台播控计算机需要控制的设备远远不止两台设备,我们需要同时控制视频服务器,录像机、切换台、字幕机等各种设备。所以我们就需要对串口进行扩展,我们可以使用串口扩展卡对串口进行扩展,比如我们在播控系统中使用的串口扩展卡MOXA CI-134。

MOXA CI-134是专为工业环境通信应用设计的 RS-422/485 四串口卡。它支持4个独立的RS-422/485串口,在一对多点的通信应用下,最多可控制128 个设备。为使RS-485 2线半双工 *** 作变得更加简单,每片 CI-134 卡都具有数据流向自动控制(ADDC),不需软件 *** 作。因此,在Windows应用下不需额外的编码就能控制RS-485半双工协议。为达到工业环境对高可靠性产品的要求,本系列产品提供可选择的光电隔离(2 KV)和浪涌保护(25 KV ESD)功能。

该产品特点包括:可选择光电隔离(2KV)和浪涌保护(25KV ESD)功能;提供数据流向自动控制ADDC (Automatic Data Direction Control)功能;RS-485 数据控制l: ADDC 或通过 RTS控制;内建终端电阻;采用芯片硬件流量控制,保证数据不流失;采用先进 ASIC 设计,返修率低;支持众多常见的 *** 作系统。

四 串口在播出控制系统中的应用

我们知道串口RS232有效传输距离为15米, RS-422的最大传输距离为4000英尺(约1219米),最大传输速率为10Mbps。我们播控中使用的录像机如DVCPRO、IMX控制接口有RS232、RS422多个接口供选择,如果使用pin9则为RS422接口,视频服务器编解码口控制都是RS422接口,只是插口为RJ45不是DB9的,需要转换线缆进行转换。因此我们在控制中根据以上特性可以灵活使用,我们由于主备控制切换的需要,以及距离的考虑统一选用RS422倒换开关进行倒换,控制RS422倒换开关的为RS232控制接口,这个直接由播控机本身的COM口来控制倒换开关进行倒换,其他控制录像机、切换台、视频服务器编解码卡使用MOXA卡扩展的RS422接口进入RS422倒换开关进行倒换。控制图如图5。

整个系统中只有RS422倒换开口控制是播控机的COM(RS232)口控制,其他都是MOXA卡扩展的RS422接口,由于应急开关需要RS232所以在应急开关前面加了一个RS422转RS232的转换器。通过控制线播控机可以及时发出播控指令,也可以随时读取录像机、切换台、还有视频服务器的状态。以上只是播控机房的系统控制图。上载、总控机房的系统控制大致和这相同。

RS422总线、RS485和RS422电路原理基本相同,都是以差动方式发送和接受,不需要数字地线。差动工作是同速率条件下传输距离远的根本原因,这正是二者与RS232的根本区别,因为RS232是单端输入输出,双工工作时至少需要数字地线、发送线和接受线三条线(异步传输),还可以加其它控制线完成同步等功能。RS422通过两对双绞线可以全双工工作收发互不影响,而RS485只能半双工工作,发收不能同时进行,但它只需要一对双绞线。以上三种接口各有缺点,在实际工作中可以根据需要灵活选用。

计算机控制在广电播控系统中运用会越来越广泛,而且随着计算机技术的不断发展,智能化也会不断提高,系统也会更加庞大,这就要求我们能更深入了解计算机的基础理论,这样才能更深入的了解系统,维护系统,保证系统的安全稳定运行,更好的保障安全播出。

参考资料:

>

您想问的是“zotero连接器无法与桌面应用程序zotero通信该怎么办”吗解决方法如下:

1、打开“控制面板-查看网络状态和任务-更改适配器设置”;

2、打开连接的网络的属性;

3、双击打开“TCP/IPv4”;

4、选择自动获得IP和DNS,点击下方的“高级”按钮;

5、在“DNS”选项卡中,把“DNS服务器地址”里面的项目删除,点击确定。以上是zotero连接器无法与桌面应用程序zotero通信的解决方法。

以上就是关于c语言中define的用法全部的内容,包括:c语言中define的用法、在电脑上的程序,如何连接外部设备、zotero连接器无法与桌面应用程序zotero通信等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9991362.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-04
下一篇 2023-05-04

发表评论

登录后才能评论

评论列表(0条)

保存