我正在查看用c编写的项目的源代码。这里是定义的选项列表(不,这些不是真正的定义…不是很有描述性!)
...
#define OPTION_5 32768
#define OPTION_6 65536
#define OPTION_7 0x20000L
#define OPTION_8 0x40000L
#define OPTION_9 0x80000L
我想添加一个新的选项OPTION_10
,但在我这样做之前,我想了解十六进制数字究竟代表什么?
这些数字转换成预期的十进制值131,072 262,144 524,288吗?如果是这样,为什么不保持与前面选项相同的格式呢?
将这些数字转换为期望的十进制值131,072
是的。您可以使用Google进行转换:搜索"0x20000 in decimal"。
如果是这样,为什么不保持与前面选项相同的格式呢?
我猜只是因为程序员知道2到65536的幂,所以他们更喜欢十六进制,因为十六进制更容易识别。
L
后缀强制字面值常量至少键入long int
, ,但如果需要保存常量,所选择的类型可能仍然更大。它可能在你的程序中是不必要的,程序员使用它是因为他/她不理解强调子句。具体细节见C99标准第56页6.4.4.1。
只是对现有答案的进一步思考,我更喜欢这样定义这些标志:
enum {
OPTION_5_SHIFT = 15,
OPTION_6_SHIFT,
OPTION_7_SHIFT,
OPTION_8_SHIFT,
OPTION_9_SHIFT,
OPTION_10_SHIFT
};
enum {
OPTION_5 = 1L << OPTION_5_SHIFT,
OPTION_6 = 1L << OPTION_6_SHIFT,
OPTION_7 = 1L << OPTION_7_SHIFT,
OPTION_8 = 1L << OPTION_8_SHIFT,
OPTION_9 = 1L << OPTION_9_SHIFT,
OPTION_10 = 1L << OPTION_10_SHIFT
};
这避免了显式计算常量,并使插入/删除值等更容易。
它们表示同一种数,它们都是2的幂。或者,从另一个角度来看,它们都是只有一个1的二进制数(没有关音)。
它们被这样写的一个可能的原因是(即使这个原因不是很好),许多程序员都知道下面的序列:
1
2
4
8
16
32
64
128
256
512
1024
2048
4096
8192
16384
32768
65536
这个序列对应于2的前17次幂。然后事情就不那么容易了,所以他们可能会切换到十六进制(懒得改变所有早期的数字)。
具体值表示位标志选项,可与位或操作符|
:
flags = (OPTION_5|OPTION_6);
您将从这些值的二进制表示中看到,每个值都有一个唯一的位集,允许使用按位或组合它们:
0x8000L = 32768 = 00000000 00000000 10000000 00000000
0x10000L = 65536 = 00000000 00000001 00000000 00000000
0x20000L = 131072 = 00000000 00000010 00000000 00000000
0x40000L = 262144 = 00000000 00000100 00000000 00000000
0x80000L = 524288 = 00000000 00001000 00000000 00000000
0x100000L = 1048576 = 00000000 00010000 00000000 00000000
要查找flags变量中是否设置了标志,可以使用按位与操作符&
:
if(flags & OPTION_6)
{
/* OPTION_6 is active */
}
一个数的每一位代表该数的基数的乘方,从右向左数,从0开始。
所以32768 = 8 * 10^0 + 6 * 10^1 + 7 * 10^2 + 2 * 10^3 + 3 * 10^4。
(提示:x^0 = 1, x^1 = x.)
十六进制数有16位(0 - 9,A (~10) - F(~15)),因此基数为16,因此0x20 = 0 * 16^0 + 2 * 16^1。
二进制数有2位,基数为2,所以100b = 1 * 2^2 + 0 * 2^1 + 0 * 2^0。
知道你应该能够自己计算剩下的数字并处理二进制和十六进制数字,了解你列出的每个数字是它的前一个数字的两倍,十六进制数字有什么十进制值,行中下一个十进制数应该是什么,以及如何在任何数字系统中表达OPTION_10,特别是二进制,十进制和十六进制