這次實(shí)驗(yàn)是寫(xiě)個(gè)自己寫(xiě)代碼的程序,而第一步就是這個(gè)程序先能打印出自己的代碼。
打印自身代碼的程序如下:
#include <stdio.h>
int main()
{
char *str = "#include <stdio.h>%cint main() %c{ %c char *str = %c%s%c; %c printf( str, 10, 10, 10, 34, str, 34, 10, 10, 10 ); %c return 0; %c}";
printf( str, 10, 10, 10, 34, str, 34, 10, 10, 10 ); // ASCII中,10為換行鍵,34為引號(hào)
return 0;
}
?
gcc 編譯后,執(zhí)行顯示如下:

看的很亂,不過(guò)不要緊,慢慢分析:主要是第4行和第5行。
首先看第4行,就是一個(gè)字符串 (*str) ,這段字符串是程序整個(gè)代碼的框架。
再看第5行,在ASCII中,10為換行鍵,34為引號(hào),整個(gè)代碼有7行,6個(gè)換行鍵,故第5句 printf 中,有6個(gè)10;至于兩個(gè)34所代表的引號(hào),則是第4句代表字符串的引號(hào)。
那么,剩下的兩個(gè)字符串指針str代表的是什么呢?我們來(lái)改一下之前的代碼,把第二個(gè)str刪掉。
#include <stdio.h>
int main()
{
char *str = "#include <stdio.h>%cint main() %c{ %c char *str = %c%c; %c printf( str, 10, 10, 10, 34, str, 34, 10, 10, 10 ); %c return 0; %c}";
printf( str, 10, 10, 10, 34, 34, 10, 10, 10 ); // ASCII中,10為換行鍵,34為引號(hào)
return 0;
}
這段代碼較之前面的代碼,做出了如下更改,第4句刪掉了%s ,第5句刪掉了第二個(gè)str,也就是說(shuō),這次顯示的是第一個(gè)str的輸出,gcc編譯后執(zhí)行結(jié)果如下:

我們與第一次執(zhí)行后的結(jié)果進(jìn)行對(duì)比,會(huì)發(fā)現(xiàn),只有第四句發(fā)生了改變,所以可以證明,程序的第五句中,printf的第2個(gè)字符串指針str,是 *str 自身的內(nèi)容,在第二個(gè)str中,%c,%s 只是相當(dāng)于字符串輸出,沒(méi)有任何特殊意義;而第一個(gè)str中,%c對(duì)應(yīng)著10,%s對(duì)應(yīng)著第二個(gè)str,輸出的是整個(gè)程序的代碼框架。
我的疑問(wèn):為什么第一個(gè)str輸出的是代碼框架,第二個(gè)才是str自身呢?*
希望得到指點(diǎn),謝謝!