我的大学建议我从本文档中学习C
作为Java
- 程序员:“C for Java Programmers”来自J. Maassen。
在第46页(PDF-第47页),Maassen尝试实施他自己的C
strcpy
函数版本,名为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推出了他的第一个strcpy
方法版本。他包含stdio.h
并将strA
复制到strB
。
所以,以下程序应该有效,不应该吗?
#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
函数here的类似实现。那个实现也不起作用!我得到了同样的错误!
怎么了?
答案 0 :(得分:3)
当编译器看到程序的第8行时,它不知道my_strcpy
采用或返回的类型。可以在源文件中切换main
和my_strcpy
的顺序,也可以在my_strcpy
之前添加main
的原型。
答案 1 :(得分: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;
}
答案 2 :(得分: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"
BTW,main
通常是从命令行传递的参数,因此您可以将其定义为
int main(int argc, char **argv) {
return 0;
}
返回有效的返回码(如果一切顺利,则为0)。您可以使用* pragma * s告诉编译器在被调用代码中不需要某些参数。