Reputation: 41
My university advised me to learn C
as a Java
-programmer from this document: “C for Java Programmers” by J. Maassen.
On page 46 (PDF-page 47), Maassen tries to implement his own version of C
’s strcpy
function, called my_strcpy
char *my_strcpy(char *destination, char *source)
{
char*p = destination;
while (*source != '\0')
{
*p++ = *source++;
}
*p = '\0';
return destination;
}
I’ve tried to write a program with this function.
Take a look at page 45 (PDF-page 46). Here, Maassen has introduced his first version of a strcpy
-method. He included stdio.h
and copied strA
to strB
.
So, the following program should work, shouldn’t it?
#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;
}
Well, actually it doesn’t.
Because every time I’m compiling this program, I get the following errors:
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);
^
Why isn’t this program working? I mean, it should work, shouldn’t it?
I’ve seen a similar implementation of a strcpy
function here. And that implementation isn’t working either! I’m getting the same errors!
What’s wrong?
Upvotes: -3
Views: 1689
Reputation: 726539
Unlike Java where methods can be used before they are declared textually, C requires a prototype for each function that you call. In case you do not provide a prototype, C uses default rules, requiring prototype-less functions to take parameters matching the type of whatever you pass for the first time, and return an int
.
To fix this, add this line ahead of main
:
char *my_strcpy(char *, char *);
Note: the real strcpy
allows pointers to constants to be passed as the second parameter. This lets you make calls like this:
my_strcpy(dest, "quick brown fox");
I suggest that you change the declaration and the definition as follows:
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;
}
Another thing to note is that you could do with destination
the same thing that you did with the source
, avoiding p
. You can also use the implied comparison to zero - another thing not available in Java:
char *my_strcpy(char *destination, const char *source)
{
while (*source) // Removed comparison to zero
{
*destination++ = *source++;
}
*destination = '\0';
return destination;
}
Finally, to avoid the assignment of zero at the end of your loop, you could go for a body-less one-liner implementation:
char *my_strcpy(char *destination, const char *source)
{
while (*destination++ = *source++)
;
return destination;
}
Upvotes: 2
Reputation: 57388
When you use my_strcpy
the first time, the compiler hasn't seen it yet and has no prototype for it. So it (possibly) defines it automatically as a function returning int
.
You need to either supply a prototype before the call:
char *my_strcpy(char *destination, char *source);
int main(void)
{
my_strcpy(strB, strA);
puts(strB);
}
char *my_strcpy(char *destination, char *source)
{
...
or define the call before actually calling it (i.e. placing main() at bottom).
For large projects you would place all of your prototypes in an external file that you would then include:
#include "my_functions.h"
BTW, main
usually is passed arguments from the command line, so you would define it as
int main(int argc, char **argv) {
return 0;
}
returning a valid return code (e.g. 0 if all went well). You may use *pragma*s to tell the compiler that some arguments aren't really needed in the called code.
Upvotes: 1
Reputation: 182763
When the compiler sees line 8 of your program, it has no idea what types my_strcpy
takes or returns. Either switch the order of main
and my_strcpy
in the source file or add a prototype of my_strcpy
before main
.
Upvotes: 3