純粹打發時間 :-)
#define _ _asm int main ()??< int i; char s[]("*****"); _ mov esi,5 L:_ dec esi _ mov i,esi puts (s+i); _ mov esi,i _ or esi,esi _ jne L??>
*
**
***
****
*****
另一種直觀做法:
int main() { char s[80] = {0}; int i = 0, N = 5; while (i<N? s[i++]='*':0) puts (s); }
*
**
***
****
*****
int main() { #define for puts do; while ( for ("*"+ for ("**"+ for ("***"+ for ("****"+ for ("*****")))))); }
*****
****
***
**
*
#define 回圈 _ void 回圈(int n) { n && (回圈(n-2), 1); puts ("*******"+8-n), printf (" " +n/2); } int main() { 回圈(10); }
* *** ***** *******
//執行需求:32 bits 機器 + cdecl 堆疊慣例 #include <stdio.h> #include <iostream> using namespace std; char s[] = "*************************"; void star (int i) { printf ("%*c%s\n",i+1,' ',s+i); i&&(*((int volatile*)&--i-1)-=5); } int main (/* daviddr 081203 */) { int n; cin>>n; s[n]=0; star(n); }
這是一種綁死在 Calling Convention (extern"C" 或 _cdecl)* ** *** **** *****
與 OS 與 Compiler 與 IA32 上的寫法,純粹 for fun。
這一句的邏輯等同:
void star (int i) { star_: printf ("%*c%s\n",i/2+1,' ',s+i-1); if (i != 0) { i = i - 2; //----i; goto star_; //(*((int volatile*)&i-1)-=5) } }觀察呼叫端的 star(n);
她會生成:
進入一個什麼都不做的 void star (int i) 後,位址 組合語言 ---------------------------------------- 00411603 mov eax,dword ptr [n] 00411606 push eax 00411607 call star (411055h) 0041160C add esp,4
生成如下組語:
此時參數堆疊內容為:void star (int i) { push ebp mov ebp,esp sub esp,0C0h push ebx push esi push edi lea edi,[ebp-0C0h] mov ecx,30h mov eax,0CCCCCCCCh rep stos dword ptr es:[edi] } pop edi pop esi pop ebx mov esp,ebp pop ebp ret
我們在程式尾端使用 (int volatile*)&i位址 內容 | | |----------| &i-4 | 0x41160C | <-- 此為 ret 的返回位址 |----------| &i | n | |----------|
來確實取得 i 在記憶體中的位址,之後「-1」
即是扣掉 sizeof (void*),其值為 0x4
再將其內容,也就是 0x41160C,-5,改成 0x411607
於是 ret 又轉跳至 call star (411055h)
等於將函式呼叫轉成一種「迴圈」~
一直執行到 i==0 時才跳離!
當對底層實作有一定的掌握時,
有時可以無視語言規格限制,另闢蹊徑來達成目的..
只是,這些技巧幾乎都不具普適性,僅可視為一種例外;
他們唯二的好處是:
1. 作為一種 coding 上的娛樂。
2. 激發出一種新的程式編寫方法,
或是為了將別種語言獨有的機制「暫時」引進來「試用」,
作為開發新程式語言 (or 寫作風格) 的靈感或基礎。
#include <stdio.h> char*_= " " " "; #define P(L_,__,o) for(;*_;_++)\ putchar ((*_<3?_++,2:*_&1)[" "#o]);\ puts (#L_" "#__); int main() {P(Merry,Christmas!,\n*);}應景程式,耶誕快樂:
使用格式化字串,再加另一個遞迴就是 BNF 了:* *** ************* ********* ******* *** *** * * Merry Christmas!
void rep (char c, int n) { if (n) rep (putchar(c), n-1); } void put (char* s) { char c = *s++; if (c) { if (isdigit(*s)) rep (c, strtol (s,&s,10)); else rep (c==','?'\n':c, 1); put (s); } } int main() { put ("*5,* 3*,*5\n\n"); put ("*7, 6*, 6*,*7, 6*, 6*,*7"); }
***** * * ***** ******* * * ******* * * *******
變形題,印出如下字母三角,高度為 5~10:
EEEEEEEEE DDDDDDD CCCCC BBB A
#include <stdio.h> #include <time.h> #include <string> #include <iostream> #include <iomanip> using namespace std; //比較快 int f1() { char s[80] = {0}; int i,j, n = rand()%6+5 for (i=0; j=n-i; ++i) printf ("%*s\n", j+n, memset (s+i*2, '@'+j, j*2-1)); } //使用cout: int f2() { int i, n = rand()%6+5; for (i=0; i<n; ++i) cout << setw(i) <<setfill(' ') << "" << setw((n-i)*2) << setfill (char('@'+n-i)) << "\n"; } //也可以寫成: int f3() { int i, n = rand()%6+5; for (i=0; i<n; ++i) cout << string (i, ' ') << string ((n-i)*2, '@'+n-i) << "\n"; } int main () { srand (time(0)); f1(); f2(); f3(); }
以星星印字:
#undef UNICODE #include <windows.h> int main() { HDC hdc = GetDC (GetConsoleWindow()); TextOut (hdc, 0,0 ,"永" ,2); for (int x, y=0; y<15; y++, puts("")) for (x=0; x<15; x++) printf (GetPixel (hdc,x,y)?" ":"**"); SelectObject (hdc, GetStockObject (4)); Rectangle (hdc, 0,0, 16,16); }輸出:
印菱形:****** **** ************ **** **** **** **** ******************** **** ****** **** ****** **** ******** **** **** **** **** **** **** **** **** **** **********
void dia (int n, int i=0, int x=0, int y=2) { if (i++ < n) { COORD c = {(n+x)*2, y}; SetConsoleCursorPosition ( GetStdHandle (STD_OUTPUT_HANDLE), c); cout <<"*"; dia (n, i, x+1, y+1); dia (n, i, x-1, y+1); dia (n, i, x, y+2); if (y == 2*n && x <2*n*(n-1)) dia (n, 0, x+2*n); } } int main() { int n; cout << "輸入一個數字: "; cin >> n; dia (n); }輸出:
* * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * ** * * ** * * * * * * * * * * * * * * * * * * * * * * * * * * *
沒有留言:
張貼留言