|
|||
Department of Engineering | |
University of Cambridge > Engineering Department > computing help |
#include <stdio.h> #include <stdlib.h> void print_reverse(char *str) { int i; unsigned int len; len = strlen(str) - 1; /* Why the -1? Because arrays start at 0, so if a string has n chars, the last char will be at position n-1 */ for (i=len; i>=0; i--) putchar(str[i]); } void main() { char input_str[100] /* why 100? */ printf("Input a string\n"); gets(input_str); /* should check return value */ printf("String was %s\n", input_str); print_reverse(input_str); }
This works, but is a bit `loose' (suppose the user types more than 100 characters?) and doesn't keep a copy of the reversed string should it be needed later. The next example shows a wrong (but not uncommon) attempt to solve the latter limitation.
#include <stdio.h> /* WRONG! */ char* make_reverse(char *str) { int i, j; unsigned int len; char newstr[100]; len = strlen(str) - 1; j=0; for (i=len; i>=0; i--;) newstr[j] = str[i]; j++; /* now return a pointer to this new string */ return newstr; } void main() { char input_str[100]; /* why 100? */ char *c_ptr; printf("Input a string\n"); gets(input_str); /* should check return value */ c_ptr = make_reverse(input_str); printf("String was %s\n", input_str); printf("Reversed string is %s\n", c_ptr); }
Like many flawed C programs this will work much of the time, especially if it's not part of a bigger program. The problems are that :-
`\0'
, so trying to print the characters out
as a string may be disastrous. `Luckily' the memory location that should
have been set to zero is likely to be zero anyway.
/* mallocing.c */ #include <stdio.h> #include <stdlib.h> char* make_reverse(char *str) { int i; unsigned int len; char *ret_str, *c_ptr; len = strlen(str); /* Create enough space for the string AND the final \0. */ ret_str = (char*) malloc(len +1); /* Now ret_str points to a `permanent' area of memory. */ /* Point c_ptr to where the final '\0' goes and put it in */ c_ptr = ret_str + len; *c_ptr = '\0'; /* now copy characters from str into the newly created space. The str pointer will be advanced a char at a time, the cptr pointer will be decremented a char at a time. */ while(*str !=0){ /* while str isn't pointing to the last '\0' */ c_ptr--; *c_ptr = *str; str++; /* increment the pointer so that it points to each character in turn. */ } return ret_str; } void main() { char input_str[100]; /* why 100? */ char *c_ptr; printf("Input a string\n"); gets(input_str); /* Should check return value */ c_ptr = make_reverse(input_str); printf("String was %s\n", input_str); printf("Reversed string is %s\n", c_ptr); }
The malloc'ed space will be preserved until it is explicitly freed (in this case by doing `free(c_ptr)'). Note that the pointer to the malloc'ed space is the only way you have to access that memory: lose it and the memory will be inaccessible. It will only be freed when the program finishes.
malloc is often used to create tree and list structures, since one often doesn't know beforehand how many items will be needed. See section A.4 for an example.