Literal string initializer for a character array

2019-01-07 05:51发布

问题:

In the following rules for the case when array decays to pointer:

An lvalue [see question 2.5] of type array-of-T which appears in an expression decays (with three exceptions) into a pointer to its first element; the type of the resultant pointer is pointer-to-T.

(The exceptions are when the array is the operand of a sizeof or & operator, or is a literal string initializer for a character array.)

How to understand the case when the array is "literal string initializer for a character array"? Some example please.

Thanks!

回答1:

The three exceptions where an array does not decay into a pointer are the following:

Exception 1. — When the array is the operand of sizeof.

int main()
{
   int a[10];
   printf("%zu", sizeof(a)); /* prints 10 * sizeof(int) */

   int* p = a;
   printf("%zu", sizeof(p)); /* prints sizeof(int*) */
}

Exception 2. — When the array is the operand of the & operator.

int main()
{
    int a[10];
    printf("%p", (void*)(&a)); /* prints the array's address */

    int* p = a;
    printf("%p", (void*)(&p)); /*prints the pointer's address */
}

Exception 3. — When the array is initialized with a literal string.

int main()
{
    char a[] = "Hello world"; /* the literal string is copied into a local array which is destroyed after that array goes out of scope */

    char* p = "Hello world"; /* the literal string is copied in the read-only section of memory (any attempt to modify it is an undefined behavior) */
}


回答2:

Assume the declarations

char foo[] = "This is a test";
char *bar  = "This is a test";

In both cases, the type of the string literal "This is a test" is "15-element array of char". Under most circumstances, array expressions are implicitly converted from type "N-element array of T" to "pointer to T", and the expression evaluates to the address of the first element of the array. In the declaration for bar, that's exactly what happens.

In the declaration for foo, however, the expression is being used to initialize the contents another array, and is therefore not converted to a pointer type; instead, the contents of the string literal are copied to foo.



回答3:

This is a literal string initializer for a character array:

char arr[] = "literal string initializer";

Could also be:

char* str = "literal string initializer";

Definition from K&R2:

A string literal, also called a string constant, is a sequence of characters surrounded by double quotes as in "...". A string has type ``array of characters'' and storage class static (see Par.A.3 below) and is initialized with the given characters. Whether identical string literals are distinct is implementation-defined, and the behavior of a program that attempts to alter a string literal is undefined.



回答4:

It seems like you pulled that quote from the comp.lang.c FAQ (maybe an old version or maybe the printed version; it doesn't quite match with the current state of the online one):

http://c-faq.com/aryptr/aryptrequiv.html

The corresponding section links to other sections of the FAQ to elaborate on those exceptions. In your case, you should look at:

http://c-faq.com/decl/strlitinit.html