请教一些关于整数性质的问题
char a=-128;
char b=-a;
printf("%d",b);
这个的结果是-128,因为char是一个字节-128-127,-128是1000 0000 加法逆元也是1000 0000所以是128,
但是下面的几个我有点不理解了?
char a=-128;
int b=-a; //不是先-a为1000 0000 然后算术扩充成32位1111... 1000 0000吗,为什么答案是128
printf("%d",b);
char a=-128;
printf("%d",-a); 这个打印是-128,也应该是-a先运算的吧,难道是先转换再运算的。
以及下面的;
char a=-128;
char b=-a;
int c=b;
printf("%d",c);
第三个和第一个怎么不一样、、、、
[最优解释]
LZ用的什么编译器?
char a=-128; // char的范围-128~127
char b=-a; // 对于-a,注意它是对a进行-运算,运算前会将a cast成int,所以-a的结果是int 128,然后赋值给char b的时候,上溢出又变回-128
printf("%d",b); // 对于printf,给出%d,它会期待int,所以b也会cast成int,即-128
char a=-128;
int b=-a; // 同上,-a为int 128,这时b是int能够hold住128这个值,不会上溢
printf("%d",b);
char a=-128;
printf("%d",-a); // 这里printf的%d期待int,而-a就是int 128
char a=-128;
char b=-a;
int c=b;
printf("%d",c); // 这里我也打出了128,按理说在int c = b;这里应该是符号扩展的,但结果显示似乎是无符号扩展,即编译器将char当unsigned char处理了,我用的是gcc,故而问问LZ的编译器。
[其他解释]
char类型的128就是-128, 扩展为int类型,会扩展符号位至ffffff80,值仍然是-128;
1:
char a=-128;
int b=-a; //不是先-a为1000 0000 然后算术扩充成32位1111... 1000 0000吗,为什么答案是128
printf("%d",b);
这个应该是先扩展为int型,为-128,然后再加符号位,print出来为128
3:
char a=-128;
char b=-a;
int c=b;
printf("%d",c);
这个char型128和-128在内存中的形式是一样的,扩展为int后会扩展符号位至ffffff80, 就是-128
[其他解释]
128跟-128是同样的二进制码吧
[其他解释]
坐等答案。。
[其他解释]
打印出来的不是-128而是128啊
[其他解释]
我试了貌似
char a=-128;
char b=-1;
fprintf("%d",a*b);//答案也是128,说明真的是先转换而后进行的乘法;但是下面的检验溢出的函数:
#include<stdio.h>
int mul_ok(int a,int b)//不溢出了就返回1.
{_int64 s=(_int64)a*b;//将a换成64位,然后b会自动换成64位,然后乘后保留在s上;
return s==(int)s;//然后检验将s得到64位和s的截断比较看相等不
}
void main()
{int a=1234567;
fprintf(stdout,"%d",mul_ok(a,a));
}
按照先转换的话那么下面这句话(_int64)可以不写了。但是我测试的时候结果不对、将这个去掉打印出来的就是1了,就显示没有溢出了。。。
_int64 s=(_int64)a*b;
[其他解释]
结果是符号扩展,我现在用的是VC++调的,我再去GCC调试下,你看下我另一个回复,就是你说的那个期待我没怎么理解
[其他解释]
所谓期待是指:char,short在压参的时候,统统是cast成int后压的。
[其他解释]
哦。那么int 和_int64是不会“期待的”。我刚刚将他换成检测short*short溢出的函数时10000*10000都没有溢出,发现是对的。。。那是不是short*short也是保持到32位呢。而32位*32位也保持到32位!
[其他解释]
我在gcc下面看了,情况和lz的一样!楼主看看汇编就知道了!基本char类型在运行之前都被扩展成int类型了!我的机器是通过无符号扩展的
[其他解释]
用SYSTEM 函数 调用rasdial命令进行宽带连接 如何在连接过后判断 宽带是否连接上啊 ????????? 急求 急求 麻烦 能不能帮我看看你这个问题撒
[其他解释]
记住这个规则就好了:
赋值(A=B,A是有符号类型)的规则:如果B的值在A的表示范围内,值不变;如果超出范围,A的值不定,取决于编译器。
//int转char,-128在char的表示范围内,所以a=-128.
//128不在char的表示范围,所以取决于编译器。
//VC2008的规则:不改变两进制表示形式而使值落入范围,
//因为10000000可以表示-128,所以b=-128
char a=-128;
char b=-a;
printf("%d",b);
//a同上。128落在int范围内,所以b=128
char a=-128;
int b=-a;
printf("%d",b);
//这里打印128.因为生成了一个int类型的临时变量
char a=-128;
printf("%d",-a);
//a、b同1.VC2008中打印-128
char a=-128;
char b=-a;
int c=b;
printf("%d",c);
[其他解释]
char a=-128;
004113CE mov byte ptr [a],80h
char b=-a;
004113D2 movsx eax,byte ptr [a] ;eax=FFFFFF80
004113D6 neg eax ;eax=00000080
004113D8 mov byte ptr [b],al ;[b]=80
所以这个打印值是-128
char a=-128;
004113F7 mov byte ptr [a],80h
int b=-a; //不是先-a为1000 0000 然后算术扩充成32位1111... 1000 0000吗,为什么答案是128
004113FB movsx eax,byte ptr [a]
004113FF neg eax
00411401 mov dword ptr [b],eax ;[b]=00000080
printf("%d\n",b);
00411404 mov esi,esp
所以这个打印值是128
char a=-128;
0041141F mov byte ptr [a],80h
printf("%d\n",-a);
00411423 movsx eax,byte ptr [a]
00411427 neg eax ;eax=00000080,直接送去打印
00411429 mov esi,esp
0041142B push eax
0041142C push offset string "%d\n" (415744h)
00411431 call dword ptr [__imp__printf (4182BCh)]
这个打印值是128
char a=-128;
00411441 mov byte ptr [a],80h
char b=-a;
00411445 movsx eax,byte ptr [a]
00411449 neg eax ;eax=00000080
0041144B mov byte ptr [b],al ;[b]=80
int c=b;
0041144E movsx eax,byte ptr [b] ;eax=FFFFFF80
00411452 mov dword ptr [c],eax ;[c]=FFFFFF80
这个打印值是-128
都是扩展32bit后取值,计算,再取8bit或直接用32bit的值,不过这个与编译器息息相关
[其他解释]
所以打印值不同的原因是 编译器对“8bit到32bit”和“32bit到8bit”的对齐处理 出现的问题