【C语言】无符号和有符号转换
最近做了个笔试题int main(int argc, char const *argv[])
{
unsigned int a = 6;
int b = -20;
char c;
(a + b > 6 ) ? (c = 1) : (c = 0);
return 0;
}
问:则c等于多少?
c = 1是毋庸置疑的,但我查阅大量资料,包括C99标准文档,都说是无符号整形和有符号整型相加时,有符号转为无符号运算。
这样算下来a+b是4294967282。
但我们老师这样说的无符号+有符号= 有符号,有符号数与无符号数(6)比较时会转成无符号,-14与6比较时会转换成14。
so,我就很迷惑。
请大佬解答 本帖最后由 侃遍天下无二人 于 2023-3-29 19:47 编辑
这种咋实现要是C标准中没规定那就和具体的编译器有关了,你弄成反汇编看看,一会我上传我这边的结果
.text:0000000000401550 ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:0000000000401550 public main
.text:0000000000401550 main proc near ; CODE XREF: __tmainCRTStartup+242↑p
.text:0000000000401550 ; DATA XREF: .pdata:000000000040506C↓o
.text:0000000000401550
.text:0000000000401550 c= byte ptr -9
.text:0000000000401550 b= dword ptr -8
.text:0000000000401550 a= dword ptr -4
.text:0000000000401550 argc= dword ptr10h
.text:0000000000401550 argv= qword ptr18h
.text:0000000000401550
.text:0000000000401550 55 push rbp
.text:0000000000401551 48 89 E5 mov rbp, rsp
.text:0000000000401554 48 83 EC 30 sub rsp, 30h
.text:0000000000401558 89 4D 10 mov , ecx
.text:000000000040155B 48 89 55 18 mov , rdx
.text:000000000040155F E8 EC 00 00 00 call __main
.text:000000000040155F
.text:0000000000401564 C7 45 FC 06 00 00 00 mov , 6
.text:000000000040156B C7 45 F8 EC FF FF FF mov , 0FFFFFFECh
.text:0000000000401572 8B 55 F8 mov edx,
.text:0000000000401575 8B 45 FC mov eax,
.text:0000000000401578 01 D0 add eax, edx
.text:000000000040157A 83 F8 06 cmp eax, 6
.text:000000000040157D 76 06 jbe short loc_401585
.text:000000000040157D
.text:000000000040157F C6 45 F7 01 mov , 1
.text:0000000000401583 EB 04 jmp short loc_401589
.text:0000000000401583
.text:0000000000401585 ; ---------------------------------------------------------------------------
.text:0000000000401585
.text:0000000000401585 loc_401585: ; CODE XREF: main+2D↑j
.text:0000000000401585 C6 45 F7 00 mov , 0
.text:0000000000401585
.text:0000000000401589
.text:0000000000401589 loc_401589: ; CODE XREF: main+33↑j
.text:0000000000401589 B8 00 00 00 00 mov eax, 0
.text:000000000040158E 48 83 C4 30 add rsp, 30h
.text:0000000000401592 5D pop rbp
.text:0000000000401593 C3 retn
.text:0000000000401593
.text:0000000000401593 main endp
重点关注这几行:
.text:0000000000401564 C7 45 FC 06 00 00 00 mov , 6
.text:000000000040156B C7 45 F8 EC FF FF FF mov , 0FFFFFFECh
.text:0000000000401572 8B 55 F8 mov edx,
.text:0000000000401575 8B 45 FC mov eax,
.text:0000000000401578 01 D0 add eax, edx
.text:000000000040157A 83 F8 06 cmp eax, 6
其中在 add eax, edx之前,变量只在不同寄存器之间传递过,没有做任何处理,所以相加的时候也是两个数做补码运算,结果是 6-20=-14 的补码,自然不可能大于6了
另外无符号的意思不是把负号去掉,是把原有的符号位视为数 给个建议,你们老师要是不能从反汇编证明自己的结论你就趁早换班,山寨的名师很多的 char在不同的平台有不同的规定,有些是有符号的,有些是无符号的。 我手头只有CPU12,编译代码如下,证明楼主是对的。
...
ldaa #$ec
ldab #6
psha
pshb
addb 1,sp
cmpb 0,sp
ldab #1
bcc pc+2
ldab #0
... 这是不是垃圾题!? 正在学C,有问题还需要求助于各位大佬:lol 基本的类型转换规则。
1.当类型转换出现在表达式时,无论是unsigned还是signed的char和short都会被自动转换成int,如有必要会被转换成unsigned int(如果short与int的大小相同,unsigned short就比int大。这种情况下,unsigned short会被转换成unsigned int)。在K&R那时的C中,float会被自动转换成double(目前的C不是这样)。由于都是从较小类型转换为较大类型,所以这些转换被称为升级(promotion)。
2.涉及两种类型的运算,两个值会被分别转换成两种类型的更高级别。
3.类型的级别从高至低依次是long double、double、float、unsignedlong long、long long、unsigned long、long、unsigned int、int。
页:
[1]
2