幾道有意思的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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章