I'm working through K&R second edition, chapter 5.
On page 87, pointers to character arrays are introduced as:
char *pmessage;
pmessage = "Now is the time";
How does one know that pmessage
is a pointer to a character array, and not a pointer to a single character?
To expand, on page 94, the following function is defined:
/* month_name: return the name of the n-th month */
char *month_name(int n)
{
static char *name[] = {
"Illegal month",
"January", "February", "March",
...
};
return (n < 1 || n > 12) ? name[0] : name[n];
}
If one were simply provided with the function declaration for the above, how could one know whether a single character or a character array is returned?
If one were to assume the return from month_name()
is a character array and iterate over it until a NULL
is encountered, but the return was in fact a single character then is there not the potential for a segmentation fault?
Could somebody please demonstrate the declaration and assignment of a pointer to a single character vs a character array, their usage with functions and identification of which has been returned?
So what you have is a string literal which is an array of char with static storage duration:
"Now is the time"
in most contexts an array will decay into a pointer to the first element which is what happens here:
pmessage = "Now is the time";
You need to design and document your interface in such a way that you know what to expect for the input and output. There is no run-time information to tell the nature of what is being pointed to.
For example if we look at the man page of strtok it tells us:
Each call to strtok() returns a pointer to a null-terminated string containing the next token.
and so the programmer knows exactly what to expect and deals with the result accordingly.
In the case where you have a pointer to a single char and instead it like a C style string then you will have undefined behavior because you will be accessing memory out of bounds. A segmentation fault is one possibility but being undefined just means the result is unpredictable.
What does
char *pmessage;
pmessage = "Now is the time";
mean?char *pmessage;
means that you declared pmessage
as a pointer to char
pmessage = "Now is the time";
means that pmessage
now points to the first character of the string literal Now is the time
.
When you return pmessage
from a function then a pointer to string literal is returned.
If you will print pmessage
with %c
specifier then it will print N
and if you will print it with %s
then it will print the entire string literal.
printf("%c\n", *N); // 'N' will be printed
printf("%s\n", N); // "Now is the time" will be printed
Strange as it seems, C trusts the intelligence of the programmer. If I see a function such as:
/* month_name: return the name of the n-th month */
char *month_name(int n)
{
static char *name[] = {
"Illegal month",
"January", "February", "March",
...
};
return (n < 1 || n > 12) ? name[0] : name[n];
}
I look at the documentation and read that it returns a NUL-terminated string that is a pointer to statically allocated memory. That is enough for me to treat the return value as I should.
If the creator of the function changes the return value in a future release to a different kind of string, they better shout it out loud, change the function name, or make it very clear otherwise it's very bad behavior from their side.
If I on the other hand fail to treat the return value correctly even though it's documented properly, well I wouldn't be so intelligent then and perhaps cut out to be a Java developer.
Lastly, if the function is not documented, find its owner and burn his house.1
1if it's in a library this is released! Don't burn people's house as soon as they start coding a library! ^_^
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With