c语言常数后缀所牵扯出的一些新认识

最近,我在看以前同事写的代码,发现了一个在常数后面加小写字母'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语言环境保持一直,有些就不支持,需要添加不同后缀)。

相关推荐
冉佳驹7 个月前
C语言 ——— 操作符
c语言·操作符·隐式类型转换·原、反、补码·左移右移操作符·结构成员访问操作符·按位操作符
YuanlongWang2 年前
.net 隐式自定义类型转换运算符 static implicit operator
c#·operator·implicit·隐式类型转换