我想知道什么时候应该投出更好.在添加,乘法等时,C++中的隐式类型转换规则是什么.例如,
int + float = ?
int * float = ?
float * int = ?
int / float = ?
float / int = ?
int / int = ?
int ^ float = ?
Run Code Online (Sandbox Code Playgroud)
等等...
表达式是否总是被评估为更精确的类型?Java的规则有所不同吗?如果我不准确地说出这个问题,请纠正我.
我试过执行以下程序:
#include <stdio.h>
int main() {
signed char a = -5;
unsigned char b = -5;
int c = -5;
unsigned int d = -5;
if (a == b)
printf("\r\n char is SAME!!!");
else
printf("\r\n char is DIFF!!!");
if (c == d)
printf("\r\n int is SAME!!!");
else
printf("\r\n int is DIFF!!!");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
对于这个程序,我得到输出:
char是DIFF !!! int是相同的!
为什么我们两者都有不同的输出?
输出应该如下?
char是相同的!int是相同的!
一个键盘连接.
假设我有2个变量:
uint64_t a = ...
uint32_t b = ...
Run Code Online (Sandbox Code Playgroud)
比较整数会产生预期的结果,即(a != b),或(b > a)?
可能重复:
当二元运算符两边的签名不同时,促销规则如何工作?
我试图围绕整数提升和C++溢出.我对以下几点感到困惑:
a)如果我有以下代码段:
int i = -15;
unsigned j = 10;
std::cout << i + j;
Run Code Online (Sandbox Code Playgroud)
我出去-5 % UINT_MAX.这是因为表达式i + j会自动提升为unsigned吗?我试图阅读标准(4.13):
— The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type.
我不确定我是否读错了,但如果这是真的,为什么i + j最终会成为无符号?
b)添加到上一部分,我现在有:
int k = j + i;
Run Code Online (Sandbox Code Playgroud)
正在接受评估-5.不应该j + i首先评估表达式,4294967291在我的系统上给出,并将其设置为等于j?那应该是超出范围的,所以这种行为是不确定的?我不知道为什么会这样-5.
c)如果我稍微改变a)的段short,我有:
short i = -15;
unsigned …Run Code Online (Sandbox Code Playgroud) unsigned int value = 1860;
int data = 1300;
if( (data - value) > 0)
{
printf("Why it is printing this");
}
Run Code Online (Sandbox Code Playgroud)
输出:为什么打印这个
我不明白为什么减去有符号形式的无符号传递"if",即使变量"data"的值小于变量"value".我真的很好奇签名和无符号减法'一个小错误',但导致一个大错误,因为我使用"延迟"功能而不是"printf",我的任务被推迟,这造成了混乱.
unsigned int value = 1860;
int data = 1300;
if( (data - value) > 0)
{
Delay(data - value);
}
Run Code Online (Sandbox Code Playgroud)
这部分继续延迟,我的任务永远不会结束.这意味着"数据 - 价值"的价值是负的,这就是为什么它继续无限等待.同时它通过"if",其中条件是"data-value"> 0.我怀疑如果签名转换为无符号并通过"if",那么为什么它给"延迟"函数赋予负值.
今天我看到了一个非常奇怪的类型推导。这是代码:
unsigned int y = 15;
int k = 5;
auto t = k - y / 2;
Run Code Online (Sandbox Code Playgroud)
由于kis int,我认为该类型也t应该是int。但令我惊讶的是,它的类型是unsigned int. 我找不到为什么类型被推断为unsigned int. 知道为什么吗?
我运行这个简单的程序:
#include <stdint.h>
#include <iostream>
int main() {
uint8_t x = 100;
int8_t y = -128;
if (x < y) {
std::cout << (int) x << " is less than " << (int) y << std::endl;
} else {
std::cout << (int) y << " is less than " << (int) x << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
有输出,正确:
-128 is less than 100
Run Code Online (Sandbox Code Playgroud)
起初我很惊讶地看到没有生成签名警告。
然后我很惊讶没有进行错误的转换(-128 -> 255),因此没有得到错误的结果。
然后我读了这个:
1除 bool、char16_t、char32_t 或 wchar_t 之外的整数类型的纯右值,其整数转换等级 (4.13) 小于 int …
一段时间以来,我一直在努力处理一些低级别的消息,结果证明校验和计算存在问题.我认为按位XOR运算符不关心符号,所以我使用a QByteArray来存储字节,并使用at返回a 的方法char来计算校验和.这些消息有时被正确承认,但并非总是如此.
看起来另一端的人uint8_t用来存储字节,并且校验和在某些情况下失败了.我通过铸造char来解决它uint8_t,但我对此感到困惑.
为什么按位XOR运算符关心符号?不管他们代表什么,我认为它在某种程度上有效.这是我用来试图理解它的一段代码.
#include <stdio.h>
#include <stdint.h>
#include <iostream>
#include <bitset>
int main ()
{
uint8_t a = 0b10010101;
char b = 0b10010101;
uint32_t checksum;
checksum = 55;
checksum ^= a;
std::cout << std::bitset<32>(checksum) << std::endl;
checksum = 55;
checksum ^= b;
std::cout << std::bitset<32>(checksum) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
即使两个整数都保持相同的位,操作在每种情况下产生不同的结果.
我不确定何时使用无符号字符时我不得不担心溢出.这个案子很清楚:
uint8_t a = 3;
uint8_t b = 6;
uint8_t c = a - b; // c is 253
Run Code Online (Sandbox Code Playgroud)
但是,这里发生了什么:
float d = a - b; // d is -3
Run Code Online (Sandbox Code Playgroud)
在进行减法之前是a还是被转换为float?
或者在这种情况下:
float e = (a - b) + (a - c);
Run Code Online (Sandbox Code Playgroud)
是否所有三个变量都转换为浮点数?
是否有可能发生溢出的情况,即使分配给的变量是浮点数?如果e是float,int或其他什么,规则是否相同?
此外,在这种情况下会发生什么:
int a = std::abs(a - b);
Run Code Online (Sandbox Code Playgroud) 可能重复:
当二元运算符两边的签名不同时,促销规则如何工作?
当从unsigned整数转换为signed整数时,我知道变量位的表示会发生变化.例如,255可以从转换时成为-1,uint8到int8.但是,我从来不确定底层位本身的"强制转换"或"转换"是什么.
我的问题是,整数变量的原始位模式是否保证在有static_cast符号和无符号类型之间保持不变,或者它是否可能以某种方式由强制转换?
出于好奇,static_cast整数标牌类型之间是否生成汇编,或者仅用于编译器知道生成的asm指令是什么?
编辑:
以下是我想要了解的场景示例:
unsigned int uintvar = random();
unsigned int control = uintvar;
assert(control == static_cast<unsigned int>(static_cast<signed int>(uintvar)));
Run Code Online (Sandbox Code Playgroud)
忽略双重演员将被优化掉的事实,这个例子是否会被保证永远保持真实?
c++ ×9
c ×3
integer ×2
bitwise-or ×1
casting ×1
char ×1
expression ×1
gcc4.9 ×1
implicit ×1
overflow ×1
signedness ×1
types ×1