Search code examples
cpointerscharacter-arrays

Clarification of char pointers in C


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?


Solution

  • How does one know that pmessage is a pointer to a character array, and not a pointer to a single character?

    You don't. At least, there's no way to tell from the pointer value itself whether it points to a single char or the first element of an array of char. It can be used either way.

    You have to rely on context or specify explicitly how the pointer is to be used. For example, scanf uses different conversion specifiers in order to determine whether a pointer is pointing to a single char:

    char single_char;
    scanf( " %c", &single_char );
    

    or an array of char:

    char array_of_char[N];
    scanf( "%s", &array_of_char[0] );
    

    Remember that when it isn't the operand of the sizeof or unary & operators or a string literal being used to initialize another array in a declaration, an expression of type "N-element array of T" will be converted ("decay") to an expression of "pointer to T", and the value of the expression will be the address of the first element of the array, so that last line could also be written

    scanf( "%s", array_of_char );
    

    Because of that conversion rule, anytime you pass an array expression to a function, what the function actually receives is a pointer value. In fact, the function declarations

    void foo( char str[N] );
    

    and

    void foo( char str[] );
    

    are equivalent to

    void foo( char *str );
    

    All three treat str as a pointer to char.