首页 > 代码库 > 几道有意思的C++题目

几道有意思的C++题目


例1:已知某计算机机器字长16位,试指出下述C语句的执行结果。

int i=40000;
printf("%d",i);

分析:首先我们复习一下C++里面的数据类型:

数据类型符号所对应的机器字长
int、unsigned int整数字(有、无符号)
short、unsigned short整数半字(有、无符号)
long、unsigned long整数双字(有、无符号)
long long整数四字
char、unsigned char整数字节(有、无符号)
Float浮点数字
Double浮点数双字
long double浮点数四字(倍双字)

数据类型和机器字长密切相关,题目中定义的int类型,因此存储长度为一个字长,也就是16位,我们先将i变换为十六进数得:40000=0X9c40,为有符号整数(即将占用一位数的符号位)且符号位为1(即为负数)

所以编译系统将计算其视为补码(即求反加1,得-0X63c0),因此执行后的输出结果为-25536

例2:已知某程序内的初始数据声明为:char* p=”acd”;当该程序运行到某时刻时,使指针指向字符串内字符‘c’的位置,试判断下述四条C语句中哪一条能够正确取得该字符串内的字符‘a’?

(A)     *p–;         (B) *–p;         (C) *p-1;         (D) *(p–)

分析:地址数值为同长、同类型数据,故该计算将涉及到多重转换的优先策略(即地址变更与对地址的一次间址访问的优先策略)。当复合发生地址变换与访内操作时则要是各自运算符号的相对位置而定。因此可很容易的判断出(B)是正确的语句。辨别该问题正确解答的关键是正确理解间接寻址和多元访问的顺序规则。

例3:试说明C语句“i+++j;”的计算策略。

分析:编译扫描自左向右,故判断操作对象与运算的关系应形成”i++”和’j’两个部分,又”i++”为一元运算,故先予计算。若编译器的扫描方向逆转,则先计算++j也是正确的。所以针对不同的编译器有不同的结果。

使用不同的数据类型与数据长度时应考虑其相互间的(编译)变换规则;

例4:试判断出下述C程序的执行结果(16位字长机器):

long s,l=5;                            
unsigned int u=4;                      
char c=-3;/*0Xfd*/                 
s=l+u*c;/*预期值为-7*/ 
printf(“%ld”, s);  

首先计算u*c,在这之中的c先转换成无符号整数(即0Xfffd),然后完成u*c计算(乘4即左移两位)并获得中间结果0Xfff4。然后为计算l与该中间结果的和,则先让无符号整数的中间结果转换为与l相同的有符号双字(即0X0000fff4),则s=65529(即0X0000fff9。

与预期值不一致的根本原因在于c经历了两次符号间的转换。如果在开始计算之前便使所有计算量值都一致,则此问题就可以避免了。

既将“s=l+u*c;”语句改为“s=l+(long)u*c;” 在近年来的编译器中可以省略强制。


首发于本人博客www.xgezhang.com

几道有意思的C++题目