In answer to your question about whether the function passed is an array or a pointer, the relevant part of the C99 standard (6.3.2.1/3) states:
Unless it is an operand of a sizeof operator or a unary operator, or is a string literal used to initialize an array, an expression that is of type type '' type is converted to an expression with a type pointer '' to indicate what points to the initial element of an array object and is not an lvalue.
So yes, besides introducing another explicit variable, the following two lines are equivalent:
char x[] = "abc"; fn (x); char x[] = "abc"; char *px = &(x[0]); fn (px);
As for criticism, I would like to raise the following.
While legal, I find it inappropriate to have function prototypes (e.g. stringreverse ) anywhere except at the file level. In fact, I prefer to order my functions so that they are usually not needed, making less space where you have to change it if you need to change the arguments or the type of the return value. This entails in this case placing stringreverse to main .
Never use gets in a real program. It is not protected against buffer overflows. At a minimum, use fgets , which can be protected, or use a decent input function, such as found here .
You cannot create a local variable in stringreverse and pass its address. This behavior is undefined. As soon as this function returns, this variable will disappear, and you will most likely point to everything that happens to replace it on the stack the next time the function is called.
There is no need to pass in the revstr variable. If it were a pointer with backup memory (i.e., space was allocated for it), that would be nice, but then there would be no need to return it. In this case, you would single out both subscribers:
char tempstr[1024]; char revstr[1024]; stringreverse (tempstr, revstr);
You should also avoid magic numbers such as 1024 . It is better to have lines like:
#define BUFFSZ 1024 char tempstr[BUFFSZ];
so you only need to change it in one place if you ever need a new value (which becomes especially important if you have many 1024 numbers with different values - global search and replacement will be your enemy in this case and not your friend) .
To make your function more adaptable, you might want to allow it to handle any length. You can do this by passing both buffers, or using malloc to dynamically allocate buffers for you, for example:
char *reversestring (char *src) { char *dst = malloc (strlen (src) + 1); if (dst != NULL) {
It is the responsibility to free this memory from the caller, but it is a debilitating way to do something.
You should probably use one of the two canonical forms for main :
int main (int argc, char *argv[]); int main (void);
It is also a particularly bad idea to call main from anywhere. Although this might seem like a great way to get an infinite loop, it will almost certainly end up chewing on your stack space :-)
All in all, this is probably the function I originally wrote. This allows the user to fill in their own buffer if they want, or to indicate that they do not have them, in which case the following will be created for them:
char *revstr (char *src, char *dst) { // Cache size in case compiler not smart enough to do so. // Then create destination buffer if none provided. size_t sz = strlen (src); if (dst == NULL) dst = malloc (sz + 1); // Assuming buffer available, copy string. if (dst != NULL) { // Run dst end to start, null terminator first. dst += sz; *dst = '\0'; // Copy character by character until null terminator in src. // We end up with dst set to original correct value. while (*src != '\0') *--dst = *src++; } // Return reversed string (possibly NULL if malloc failed). return dst; }