简体   繁体   English

C和C ++中的宏定义

[英]Macro definition in C and C++

I am a new programmer in C/C++ having programmed in Java for quite a while. 我是C / C ++的新程序员,已经用Java编程了一段时间。 I am currently understanding some C code. 我目前正在理解一些C代码。 Here I am seeing some macro definitions like: 在这里,我看到一些宏定义,例如:

/* Flags for ds_flags */ 
#define DSF_OVER        (1<<0)  
#define DSF_DISPLAY     (1<<1)    
#define DSF_CALLFLOW    (1<<2) 

I am not able to understand why do we have to define these macros in such a manner. 我不明白为什么我们必须以这种方式定义这些宏。 What is the advantage gained in these rather than in defining like: 在这些而不是像这样定义中获得了什么好处?

#define DSF_OVER        0
#define DSF_DISPLAY     1    
#define DSF_CALLFLOW    2

When seeing something like 当看到类似的东西

#define DSF_FOO 0x800
#define DSF_BAR 2048

not many people are able to quickly see that only one bit is set, and which it is. 没有多少人能够快速看到仅设置了一位。

#define DSF_FOO (1<<11)

however makes this very clear. 但是,这很清楚。

The only potential advantage is that it's easier to see that the code correctly defines each constant with one distinct bit set. 唯一的潜在优势是,可以更容易地看到代码正确地定义了带有一个不同位集的每个常量。

Most people will see that at a glance anyway if you just write 1, 2, 4 instead of 1<<0 , 1<<1 , 1<<2 , so perhaps it's difficult to see that advantage in this example. 无论如何,只要写1,2,4而不是1<<0 1<<1 1<<2 ,大多数人都会一眼看出来,因此在这个示例中可能很难看到这种优势。 Once you get to 1<<15 , some people would miss a typo like 32748. 一旦您达到1<<15 ,有些人就会错过像32748这样的错字。

These are bit values, eg 1, 2, 4. 8. 这些是位值,例如1、2、4、8。

Bit 0 = (1 << 0) = 1
Bit 1 = (1 << 1) = 2
Bit 2 = (1 << 2) = 4
Bit 3 = (1 << 3) = 8
...etc...

It's a more convenient and robust way of defining them than using explicit values, especially as the bit indices get larger (eg (1<<15) is much easier to understand and more intuitive than 32768 or 0x8000 , in that it obviously means "bit 15" rather than some possibly arbitrary number). 与使用显式值相比,这是一种更方便,更可靠的定义方式,尤其是当位索引变大时(例如(1<<15)327680x8000更容易理解和直观),因为它显然意味着“位” 15英寸,而不是一些任意数字)。

Using (1<<x) in a define makes it clear that the value is a single bit and not a number. 在定义中使用(1<<x)可以清楚地表明该值是一个位而不是一个数字。

For the compiler it makes no difference because (1<<2) is computed at compile time and not at runtime. 对于编译器而言,这没有什么区别,因为(1<<2)是在编译时而不是在运行时计算的。 Showing clearly that they are single-bit values is instead useful for whoever reads the code because for example they could be multiple values that can be combined or that a single variable can be used to store multiple flags: 清楚地表明它们是单个位的值对读取代码的人很有用,因为例如,它们可以是可以组合的多个值,或者可以使用单个变量来存储多个标志:

// Multiple options are combined with bitwise-or
show_message(DSF_CAPTION|DSF_ALERT, "Hey...");
...

// Checking is made using bitwise-and, not equality
if (status & DSF_RUNNING)
  ...

Also requiring specific bits is sometimes needed when dealing with hardware (eg on a certain I/O port may be you need to specify the fifth bit because that's how the hardware is wired, and (1<<4) is more readable than 16 for that). 在处理硬件时,有时还需要特定的位(例如,在某个I / O端口上,您可能需要指定第五位,因为这是硬件的连接方式,并且(1<<4)16更易读那)。

It's for clarity really - it shows that the different definitions are bit masks that will typically be used together to filter values from an input. 确实是为了清楚起见-它表明不同的定义是位掩码,通常将它们一起用于过滤来自输入的值。 I don't know if you already know what a bit mask is - here's a link: http://www.vipan.com/htdocs/bitwisehelp.html 我不知道您是否已经知道位掩码是什么-这是一个链接: http : //www.vipan.com/htdocs/bitwisehelp.html

Regardless of whether you prefer (1 << n) or not, everyone should be aware of what hexadecimal numbers signify. 无论您是否喜欢(1 << n) ,每个人都应该知道十六进制数字表示什么。 Whenever you encounter hex in source code it always means that som bit- or byte manipulations are taking place. 每当您在源代码中遇到十六进制时,就始终意味着对som的位或字节进行了操作。 You don't use hex notation for any other purpose. 请勿将十六进制表示法用于任何其他目的。 Therefore it is wise to write masks, numeric bit manipulation literals etc as hex. 因此,将掩码,数字位操作文字等写为十六进制是明智的。

Some times the position of the bits represent some bit operations like in your case: 有时,位的位置表示某些位操作,例如您的情况:

#define DSF_OVER        (1<<0)  is 1
#define DSF_DISPLAY     (1<<1)  is 2  
#define DSF_CALLFLOW    (1<<2)  is 4 (This is not 3)

If you were to add a new item later, you will do it as 如果您以后要添加新项目,将按照

#define DSF_OVER       1
#define DSF_DISPLAY    2  
#define DSF_CALLFLOW   4
#define DSF_CALLNEW    5.

You cant have a value 5 here since it is two bits enabled (101 in binary). 您不能在此处使用值5,因为它启用了两位(二进制为101)。 To avoid such potential errors it is always safe to use macros using >> . 为避免此类潜在错误,使用>>宏始终是安全的。 It can't produce a value of 5 (101) by error in when the next bit should be 1000 in binary. 当下一位应为二进制二进制数1000时,它无法产生错误的5(101)值。

It is all about programming convenience to produce error free code. 产生无错误代码的全部目的在于编程便利。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM