-3

我的大学建议我从这份文档中学习C成为一名Java程序员:“<a href="http://faculty.ksu.edu.sa/jebari_chaker/papers/C_for_Java_Programmers.pdf" rel="nofollow noreferrer">C for Java程序员”,J. Maassen 着。

在第 46 页(PDF-page 47),Maassen 尝试实现他自己版本的C'sstrcpy函数,称为my_strcpy

char *my_strcpy(char *destination, char *source)
{
    char*p = destination;
    while (*source != '\0')
    {
        *p++ = *source++;
    }
    *p = '\0';
    return destination;
}

我试图用这个函数编写一个程序。
查看第 45 页(PDF-第 46 页)。在这里,Maassen 介绍了他的第一个版本的 astrcpy方法。他包括stdio.h并复制strAstrB.

那么,下面的程序应该可以工作,不是吗?

#include <stdio.h>

char strA[80] = "A string to be used for demonstration purposes";
char strB[80];

int main(void)
{
    my_strcpy(strB, strA);
    puts(strB);
}

char *my_strcpy(char *destination, char *source)
{
    char*p = destination;
    while (*source != '\0')
    {
        *p++ = *source++;
    }
    *p = '\0';
    return destination;
}

嗯,实际上并没有。
因为每次我编译这个程序时,我都会收到以下错误:

PROGRAM.c:12:7: error: conflicting types for ‘my_strcpy’
 char *my_strcpy(char *destination, char *source)
       ^
PROGRAM.c:8:5: note: previous implicit declaration of ‘my_strcpy’ was here
 mystrcpy(strB, strA);
 ^

为什么这个程序不起作用?我的意思是,它应该工作,不是吗?
我在这里strcpy看到了一个类似的函数实现。而且该实施也不起作用!我遇到了同样的错误!

怎么了?

4

3 回答 3

3

当编译器看到程序的第 8 行时,它不知道my_strcpy接受或返回什么类型。要么在源文件中切换mainand的顺序,要么添加beforemy_strcpy的原型。my_strcpymain

于 2013-12-07T17:20:48.577 回答
2

与 Java 中方法可以在以文本形式声明之前使用不同,C 需要您调用的每个函数的原型。如果您不提供原型,C 将使用默认规则,要求无原型函数采用与您第一次传递的任何类型匹配的参数,并返回一个int.

要解决此问题,请在前面添加此行main

char *my_strcpy(char *, char *);

注意:实数strcpy允许指向常量的指针作为第二个参数传递。这使您可以像这样进行调用:

my_strcpy(dest, "quick brown fox");

我建议您将声明和定义更改如下:

char *my_strcpy(char *, const char *);

char *my_strcpy(char *destination, const char *source)
{
      char* p = destination;
      while (*source != '\0')
      {
          *p++ = *source++;
      }
      *p = '\0';
     return destination;
}

另一件需要注意的事情是,您可以使用与destination. 相同的方法source,避免p. 您还可以使用与零的隐含比较 - Java 中不可用的另一件事:

char *my_strcpy(char *destination, const char *source)
{
      while (*source) // Removed comparison to zero
      {
          *destination++ = *source++;
      }
      *destination = '\0';
     return destination;
}

最后,为了避免在循环结束时分配零,您可以使用无主体的单行实现:

char *my_strcpy(char *destination, const char *source)
{
      while (*destination++ = *source++)
          ;
     return destination;
}
于 2013-12-07T17:22:33.913 回答
1

当你第一次使用my_strcpy时,编译器还没有看到它,也没有它的原型。因此它(可能)自动将其定义为返回的函数int

您需要在调用之前提供原型:

char *my_strcpy(char *destination, char *source);

int main(void)
{
    my_strcpy(strB, strA);
    puts(strB);
}

char *my_strcpy(char *destination, char *source)
{
    ...

或在实际调用之前定义调用(即,将 main() 放在底部)。

对于大型项目,您可以将所有原型放在一个外部文件中,然后将其包括在内:

#include "my_functions.h"

顺便说一句,main通常从命令行传递参数,因此您可以将其定义为

int main(int argc, char **argv) {


    return 0;
}

返回有效的返回码(例如,如果一切顺利,则返回 0)。您可以使用 *pragma*s 告诉编译器某些参数在被调用的代码中并不真正需要。

于 2013-12-07T17:21:15.293 回答