本节内容紧接上节,解决红色字体遗留问题。本节所有例子运行环境: win10 + VS2015 + X64 + debug
在上节例子中,查看变量 c 、d 、d+1 的类型。
//// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。 #include "stdafx.h" #include <iostream> #include <iostream> #include <cstddef> #include <typeinfo> int main() { system("color 3f"); short int a = 32766; short b = 2; int c = a + b; short d = a + b; printf("c: %d: Dec: %d; Hex: %x; size: %d; ",c, c, c, sizeof(c)); printf("d: %d: Dec: %d; Hex: %x; size: %d ",d, d, d, sizeof(d)); printf("d+1: %d: Dec: %d; Hex: %x; size: %d ", d+1, d + 1, d + 1, sizeof(d + 1)); std::cout << "type c: " << typeid(c).name() << " " << "type a+b: " << typeid(a+b).name() << " " << "type d: " << typeid(d).name() << " " << "type d+1: " << typeid(d+1).name() << " " << std::endl;
system("pause"); return 0; }
运行结果:
"a + b" 在运算时,由于a和b是short int 型,先转换为int(注意这是无条件转换,因为short、char等运算时,都先转换成int,即使是两个同类型的char/short运算,也要转换成 int 型),具体为什么可点击这里或者参考[2] P31,故 a+b 运算结束后为 int 型。同理,“d + 1”运算的结果也是 int 型。 “c = a + b” 则是由于int型的“a + b”赋值给 int 型的c,所以 c为 int 型。由于“a + b”是 int 型,但是需要赋值给取值范围更小的 short 型的 d,有可能发生截断,最后 d 的数据类型依然是 short 型,所占字节数为 2,但是在内存中依然使用32位来表示 d 。进一步做以下实验来说明这种情况:
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> #include <iostream> #include <cstddef> #include <typeinfo> int main() { system("color 3f"); short m = 32767; printf("m: %d: Dec: %d; Hex: %x; size: %d; ", m, m, m, sizeof(m)); short n = 32768; printf("n: %d: Dec: %d; Hex: %x; size: %d; ", n, n, n, sizeof(n)); std::cout << " "; system("pause"); return 0; }
实验结果:
当发生溢出时,依然用32位来表示两个字节的short。
参考文献
[1]C++数据溢出(上溢和下溢). http://c.biancheng.net/view/1332.html
[2] 谭浩强.C++程序设计[M].北京:清华大学出版社.