最近,我在看以前同事写的代码,发现了一个在常数后面加小写字母'u'的情况,如下所示:
cpp
void Write8209Reg(uint16_t reg_addr, uint32_t data)
{
//enable SPI
SPI_CS_SET();
SPI_CS_RESET();
SPIDelay();
//send Write cmd
reg_addr |= 0x800u; /**bit11最高位写1,表示写命令,其他位数据 */
SPITXBytes8209(reg_addr >> 4, 1); /**一次 */
SPITXBytes8209(data, (reg_addr & 0x0Fu)); /** 多次 */
SPI_CS_SET();
SPIDelay();
}
常数0x800u、0x0Fu,当我读到这里的时候,我就想知道前同事为什么要这样写,在常数后面加这个后缀有什么含义?
其实,我大致知道前同事的意图,u代表的应该是"unsigned"或者"unsigned int"无符号整数,也就是显示之处常数0x800以及0x0F是无符号常数。
那么现在就有一个问题了,我们写代码可能不太正规,例如:unsigned int i = 10;赋值运算符左边的为一个无符号整形变量,赋值运算符右面的为默认insigned有符号的常量,编译器为什么没报错了?
答案:赋值时编译器隐式的进行了类型转换,也就是编译器隐式将10从有符号类型自动转换成无符号类型,所以编译器也不报错。这种类型转换是默认隐藏式执行的,我们自己编程的时候甚至都没有察觉的,所以编译器在背后给我们做了很多事情,我们自己没察觉到,编译器也有一定智能性。
再回到现在的问题:
常数后缀问题,其实常数后面可以跟U(u)、L(l)、F(f):
U(u):表示unsigned
L(l):表示long,长整形,因为一个整数默认是int类型,所以long就是强制转换成长整形。
F(f):表示float浮点类型,主要是给小数显式表示。
补充:不同进制所涉及到的前缀。
常数默认是10进制,这个是自然的,因为要考虑人的习惯。c语言环境下,如果想表示十六进制,就需要在常数前面加0x或者0X而禁止使用后缀"H/h";在c语言环境如果想表示二级制,使用的是前缀0b而禁止使用后缀B/b,例如unsigned int i = 0b1111;在c语言环境中如果想表示八进制,使用的时候需要在前面使用前缀0,例如unsigned int j = 01234;
可能有人会问了,上述"不同进制设计到的前缀"是c语言环境,那么汇编环境呢?
我的说法是:不同汇编环境中八进制或者十六进制的表示方法不同,有些与c语言表示方法一致,有些就使用后缀,例如十六进制使用H/h表示,二进制使用后缀B/b表示。要做到具体环境具体分析。
小结:c语言环境表示不同进制需要添加前缀,汇编环境如果表示进制需要根据具体编译器具体分析。(有些进制汇编环境支持与c语言环境保持一直,有些就不支持,需要添加不同后缀)。