2010年11月23日 星期二

不用使用任何額外的記憶體, 就把字串反轉!!

字串反轉, 這是個老問題, 隨手寫來也是很快

char* t = "123456789\0";

char* l = new char[strlen(t)];

for(size_t i = 0; i < strlen(t); ++i) {

    l[strlen(t)-1-i] = t[i]; // copy t to l

}

 

沒啥大問題, 但..有沒有辦法不使用額外的記憶體就把字串copy完呢?看下面的程式

 

    char str[10] = {'1', '2', '3', '4', '5', '6', '7'};

    char *a, *b, c;

    a = b = str;

    while (*b) 

        b++; 

    --b;

    while (b >a) {

        c = *a;

        *a++ = *b;

        *b-- = c;

    }

這樣不是用了兩個pointer及一個c嗎?其實在打開compiler最佳化後, 來看一下組合語言

int _tmain(int argc, _TCHAR* argv[])

{

00401000  sub         esp,10h 

00401003  mov         eax,dword ptr [___security_cookie (403000h)] 

00401008  xor         eax,esp 

0040100A  mov         dword ptr [esp+0Ch],eax 

    char str[10] = {'1', '2', '3', '4', '5', '6', '7'};

0040100E  xor         eax,eax 

00401010  mov         dl,31h 

    char *f, *t, c;    /// 這裡並沒有allocate任何記憶體

    f = t = str;

    while (*t) 

00401012  test        dl,dl 

00401014  mov         word ptr [esp+7],ax 

00401019  mov         byte ptr [esp+9],al 

0040101D  lea         eax,[esp] 

00401020  mov         byte ptr [esp],dl 

00401023  mov         byte ptr [esp+1],32h 

00401028  mov         byte ptr [esp+2],33h 

0040102D  mov         byte ptr [esp+3],34h 

00401032  mov         byte ptr [esp+4],35h 

00401037  mov         byte ptr [esp+5],36h 

0040103C  mov         byte ptr [esp+6],37h 

00401041  mov         ecx,eax 

00401043  je          wmain+4Dh (40104Dh) 

        t++;              //使用t時是直接使用eax

00401045  add         eax,1 

00401048  cmp         byte ptr [eax],0 

0040104B  jne         wmain+45h (401045h) 

    --t;

0040104D  sub         eax,1 

 

    while (t > f) {

00401050  lea         edx,[esp] 

00401053  cmp         eax,edx 

00401055  jbe         wmain+6Bh (40106Bh) 

00401057  push        ebx  

        c = *f;

        *f++ = *t;       /// 使用f時是使用ebx

00401058  mov         bl,byte ptr [eax] 

0040105A  mov         dl,byte ptr [ecx] 

0040105C  mov         byte ptr [ecx],bl 

        *t-- = c;         /// 使用c時是使用ecx

0040105E  mov         byte ptr [eax],dl 

00401060  add         ecx,1 

00401063  sub         eax,1 

00401066  cmp         eax,ecx 

00401068  ja          wmain+58h (401058h) 

0040106A  pop         ebx  

    }

return 0;

}

 

所以..完全沒用到記憶體耶..XD

沒有留言: