有趣的小程式

2021-05-04 13:09:27 字數 1297 閱讀 6715

#include

int main()

執行這個程式,螢幕上會出現乙個 :)

很多人不懂其中的道理,在這裡我給大家分析下**。

先看這兩句:

const short int c1 = 49920;

const int c2 = 1073742008;

定義了兩個區域性變數,數值轉換成16進製為:

const short int c1 = 0xc300;

const int c2 = 0x400000b8;

其中變數c1的位址為:0x0012ff7c ,佔兩個位元組,c2的位址為:0x0012ff78,佔四個位元組。這兩個變數佔據了連續的空間。變數賦值後,從0x12ff78開始的記憶體單元儲存的位元組碼為:b8 00 00 40 00 c3 。對應的彙編碼是:

mov        eax,400000h

ret

接下來的這句:

int (*pf)() = (int (*)())&c2;

分析如下:

定義了乙個函式指標,引數為null,返回值為int型別。 這個函式指標,指向上面的彙編碼。這樣,後面執行pf(),就執行了這段彙編碼。

繼續分析下面這句**:

printf("%c%c/n", *(char*)pf()-19, *((char*)pf()+1)-49);

先看*(char*)pf()-19這個表示式, 執行了了pf指向的彙編**,從彙編**看,

這個函式呼叫後的返回值是0x400000,pf()前面的char *是把函式的返回值轉換成乙個

char*型指標,這個指標指向0x400000,前面再加個*號,表示取0x400000位址的內容,

由於是char *型指標,因此從這個位址取乙個位元組。

*(char*)pf()-19 表示的是從0x400000取出的位元組內容再減去19。

接下來:*((char*)pf()+1)-49代表的意思是從0x400000 + 1的位址取出乙個位元組內容在減去49。

熟悉pe檔案結構的朋友一定知道,對於exe檔案0x400000是記憶體載入的基位址。

也就是說,0x400000 位元組的內容對應的是0x4d,0x400001 位元組的內容對應的是0x5a.

這是我們常說的pe檔案起始的兩個位元組,"mz"

這樣,表示式*(char*)pf()-19的結果是0x3a ,表示式*((char*)pf()+1)-49的結果是0x29

察看ascii碼表,輸出就是我們看到的樣子。

總結:

別看乙個這麼小的程式,但是其中涉及的知識面比較廣

比較有趣的C語言小程式

1.判斷是否是閏年 include int main void if a 1 printf d is a leap year n year else printf d not a leap year n year return0 2.判斷乙個日期是週幾,有兩種演算法 1 include stdio....

有趣的程式

include int main 執行這個程式,螢幕上會出現乙個 很多人不懂其中的道理,在這裡我給大家分析下 先看這兩句 const short int c1 49920 const int c2 1073742008 定義了兩個區域性變數,數值轉換成16進製為 const short int c1...

有趣的小演算法 1

乙個100大小的int陣列,要求隨機新增1 100的數到其中,且不能有重複。思考 在for 0 99 迴圈中 肯定要產生隨機數然後與陣列中元素比較,如果產生的隨機數在for 0 i 中有相等,則 跳出迴圈,再產生隨機數 如果不等,繼續在for 0 i 中比較,直到小迴圈中是i值還是不等,說明不存在相...