C 之一些事一些情 變數值的溢位問題

2021-06-19 16:58:10 字數 1451 閱讀 3738

對於千年蟲,學習過計算機基本理論的同學應該都不陌生了,它曾經引起了全世界人民共同關注,並且對當年世界造成了廣而深的影響,是計算機歷史中的乙個大事件。引用互動百科對「千年蟲」的解釋:

所謂千年蟲,泛指由於各種原因,計算機時鐘系統不能在2023年以後正確計時,從而導致軟體或硬體系統不能正常工作甚至發生崩潰。這裡主要是乙個兩位計年(比如:99年)到四位計年(2023年)轉化的問題,由此引發在pc機、收款機、工控機等等計算機控制系統上不可預料的操作故障。

所謂千年蟲,其實說白了就是變數溢位問題,當數值超出了當前變數型別所能表示的範圍就會發生溢位,下面將會舉例說明容易發生變數溢位的一些場合和原因,以及在選擇變數型別時需要注意的地方。

在《c陷阱和缺陷》中介紹了c函式庫中的fgetc、getc、getchar幾個函式的乙個缺陷,很多初學者在使用前面提到的幾個函式時,都可能會寫出下面的**:

char ch;

while ((ch = fgetc(fp)) != eof)

fgetc等函式返回指是int型別,上面的**使用char型別儲存fgetc的返回值就有可能產生問題了。這裡有兩點需要注意的:

1) 在32位系統下,int占用4個位元組,char占用1個位元組

若將乙個int變數賦值給乙個char變數,將會導致int變數的前三個位元組被截斷,因此,ch中儲存的資料可能就是錯的了;

2) char型別與eof比較的時候會自動提公升為int型別

當ch與eof比較的時候會自動提公升為int型別,而根據char是unsigned還是signed,當ch被轉為int的時候的值不一定相同:

對於上面的例子,若fgetc返回值是0x 00 00 00 ff,而ch的型別為signed char,那麼ch就會截斷前三個位元組,實際儲存的值為0x ff,當將ch與eof比較時,ch會強制轉為int型別,其值轉為0x ff ff ff ff(即十進位制數-1),而系統定義的eof的值一般都為-1,則此時ch的值就等於eof的值,迴圈結束。

(ch = fgetc(fp)) != eof  //讀到值為ff的字元,誤認為eof
這是乙個好的資料,並不是檔案結尾,卻因為溢位而退出了迴圈。因此,為了得到正確的結果,上面的程式片段中的變數ch應該定義為int型別。

當無符號數賦值給有符號數時,也會發生資料溢位:

unsigned int uvalue = 0xffffffff;

int ivalue = uvalue;

cout有人可能會說,哪有這麼笨,有點常識都不會寫出以上的**了,但是要注意的是,當程式的邏輯越來越大以及維護**的人越來越多的時候,這種情況就有可能出現了,不要小看問題的嚴重性,往往浪費你幾個通宵的debug時間,最後找到的就是你這不以為然的小問題了。

C 之一些事一些情 虛析構函式

虛析構函式是為了解決這樣的乙個問題 基類的指標指向派生類物件,並用基類的指標刪除派生類物件 以下是兩個類的宣告,其中base類為基類,而derived類繼承自base類 class base public base cout base constructor 下面為相應的測試 base ptr ne...

最近的一些事

前段時間,工作不是很忙,閒暇的時候,做了很多自己喜歡做的事情。組內乙個技術很厲害的員工,要離職了,給我們分享了他的很多東西,我們收穫很大。有的同學已經開始自己創業了,想邀請我加入,但是我現在確實還沒有那個信心。自己買了很多書,再一次把自己定位為乙個技術人員,開始堅持不懈的專研技術。身體素質大不如以前...

NOIP 的一些事

noip考完了,忍不住的有些話想說。想要狠狠地吐槽一句 今年你tm的考的都是些什麼題啊?完全沒有意義的好不好?記得考試前一天,早早的22 00就睡了,第二天早上頂著小雨到電子科大報到,一路上怒求rp 看到南實的坐車一直坐到基實樓下,還調侃了幾句。8 30到了,題發下來,一看,整個人都傻了。題怎麼這麼...