2011-05-08 78 views
14

這應該是非常微不足道的。我是通過一個非常基本的C程序比較字符串運行:沒有頭文件的C函數

#include <stdio.h> 
int strcmp(char *s, char *t); 
int main() 
{ 
    printf("Returned: %d\n", strcmp("abc", "adf")); 
    return 0; 
} 

int strcmp(char *s, char *t) 
{ 
    printf("Blah\n"); 
    while (*s++ == *t++) 
    { 
     if (*s == '\0') 
      return 0; 
    } 
    return *s - *t; 
} 

所以,我已經基本上實現我自己的strcmp函數的版本已經存在string.h中。當我運行上面的代碼時,我只看到0,1或-1的返回值(至少對於我的一小組測試用例)而不是實際的預期結果。現在我意識到這是因爲代碼沒有轉到我實現的strcmp版本上,而是使用了函數的string.h版本,但我很困惑,爲什麼這種情況即使在我沒有'包括適當的頭文件。

另外,看看它如何使用頭文件版本,編譯代碼時不應該得到'多個實現'錯誤(或沿着這些行的東西)?

+0

你最後一次測試'* s ++ == * t ++'可能會失敗,仍然會增加你的指針......是你想要的嗎? – Benoit 2011-05-08 08:03:47

+0

是的,你說得對。最後一行應該是返回 *( - s) - *( - t) – 2011-05-08 18:22:20

回答

14

您使用的是gcc,對不對? gcc在編譯器中實現了一些內置函數,看起來好像是strcmp is one of those。嘗試使用​​開關編譯您的文件。

頭文件只是告訴編譯器某些符號,宏和類型存在。包含或不包含頭文件不會影響函數的來源,這是鏈接器的工作。如果gcc將strcmp拉出libc,那麼您可能會看到警告。

+0

+1這是我不知道的答案的部分:) – MByD 2011-05-08 06:52:08

+1

我的答案似乎是一個大錯誤.. 。刪除... – MByD 2011-05-08 06:59:49

+0

我確定它沒有發佈,這是一個恥辱...... – MByD 2011-05-08 07:03:19

1

不知道什麼編譯器和lib。所有的結論都只是'可能性'。所以最合理的事情,stdio.h已經包括stdlib.hstring.h

6

不一樣優雅作爲較早的答案,來完成這件事的另一種方式

#include <stdio.h> 
static int strcmp(char *s, char *t); /* static makes it bind to file local sym */ 
int main() 
{ 
    printf("Returned: %d\n", strcmp("abc", "adf")); 
    return 0; 
} 

int strcmp(char *s, char *t) 
{ 
    printf("Blah\n"); 
    while (*s++ == *t++) 
    { 
     if (*s == '\0') 
      return 0; 
    } 
    return *s - *t; 
} 
0

strcmp是一個標準庫函數的名稱。因此,您只能聲明該功能(儘管您必須使用正確的聲明);你不能爲它提供另一個定義。實現可以假定,無論何時使用strcmp,即使您沒有使用正確的#include,也是指標準庫函數。

如果你想提供替代strcmp那麼你應該給它一個替代名稱。

+0

我可以提供大多數庫函數的重新定義。他們中的大多數在glibc中被宣佈爲弱項;此外,標準僅在標題中說明了定義。如果沒有頭文件,就沒有任何「庫函數」,我可以聲明任何東西,甚至是'y0()'或者以非標準的方式定義東西,例如'雙strcmp(int,float *)'。許多實現允許用戶關閉關於標準庫的假設('-fno-builtin'或''-freestanding')。標準在「託管環境」(「託管實施」)中提到了庫,但有一個「符合獨立實現」的標準。 – osgx 2011-07-21 08:55:36