有趣的程式

2021-06-28 15:26:04 字數 1296 閱讀 6024

#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碼表,輸出就是我們看到的樣子。 

總結: 

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

有趣的小程式

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

有趣的發現 列印自身源程式

最近看 找規律的列印表 問題,就無意間看到了這個 列印自身源程式 問題,不禁感嘆有時候 真的神奇呀,學的越多就覺得自己知道的越少 作為真正的 quine 有一些約定 程式不能接受輸入或者是開啟檔案,因為那樣就可以直接輸入源 或者是把源 檔案直接開啟再重新列印出來,就沒有什麼意思了 同時,乙個完全空白...

比較有趣的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....