Wan*_*ool 11 c++ bitwise-operators integer-promotion unsigned-integer signed-integer
我有一个简单的程序.请注意,我使用的是无符号的固定宽度整数1字节.
#include <cstdint>
#include <iostream>
#include <limits>
int main()
{
uint8_t x = 12;
std::cout << (x << 1) << '\n';
std::cout << ~x;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin.get();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我的输出如下.
24
-13
Run Code Online (Sandbox Code Playgroud)
我测试了更大的数字,操作员<<总是给我正数,而操作员~总是给我负数.我然后使用sizeof()并发现......
当我使用左移位运算符(
<<)时,我收到一个无符号的4字节整数.当我使用bitwise not运算符(
~)时,我收到一个带符号的4字节整数.
似乎bitwise not运算符(~)像算术运算符一样执行有符号整数提升.但是,左移运算符(<<)似乎提升为无符号整数.
我觉得有必要知道编译器什么时候改变我背后的东西.如果我在分析中是正确的,那么所有按位运算符都会提升为4字节整数吗?为什么一些签名和一些未签名?我很困惑!
编辑:我总是得到肯定或总是得到负值的假设是错误的.但是由于错误,我理解真正发生的事情,这要归功于下面的重要答案.
[expr.unary.op]
操作数
~应具有整数或无范围的枚举类型; 结果是其操作数的一个补码.执行整体促销.
[expr.shift]
转移运营商
<<和>>组从左到右.[...]操作数应为整数或无范围的枚举类型,并执行整体促销.
什么是整体推广uint8_t(通常会unsigned_char在幕后)?
[conv.prom]
以外的整数类型的prvalue
bool,char16_t,char32_t,或wchar_t,其整数转换秩(4.13)小于的秩int可以被转换成类型的prvalueint如果int可以表示源类型的所有值; 否则,源prvalue可以转换为类型的prvalueunsigned int.
所以int,因为a的所有值uint8_t都可以表示int.
什么是int(12) << 1?int(24).
什么是~int(12)?int(-13).
出于性能原因,C和C++语言被认为int是"最自然的"整数类型,而"类型"的类型比int被认为是"存储"类型的类型更小.
在表达式中使用存储类型时,它会自动转换为a int或unsigned int隐式.例如:
// Assume a char is 8 bit
unsigned char x = 255;
unsigned char one = 1;
int y = x + one; // result will be 256 (too large for a byte!)
++x; // x is now 0
Run Code Online (Sandbox Code Playgroud)
发生了什么,x并且one在第一个表达式中已经隐式转换为整数,已经计算了加法并且结果已经存储回整数.换句话说,未使用两个无符号字符执行计算.
同样,如果float表达式中有值,编译器将要做的第一件事就是将其提升为a double(换句话说,它float是一种存储类型,double而不是浮点数的自然大小).这是其中的原因,如果你使用printf打印彩车你不需要说%lf的int格式字符串和%f足够的(%lf是需要scanf但因为该函数存储结果和float可能比一个更小double).
C++使问题变得复杂很多,因为在将参数传递给函数时,您可以区分ints和较小的类型.因此,在每个表达式中执行转换并不总是如此...例如,您可以:
void foo(unsigned char x);
void foo(int x);
Run Code Online (Sandbox Code Playgroud)
哪里
unsigned char x = 255, one = 1;
foo(x); // Calls foo(unsigned char), no promotion
foo(x + one); // Calls foo(int), promotion of both x and one to int
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4729 次 |
| 最近记录: |