2011-05-08 47 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