简体   繁体   中英

Why can't we initialize a 2D integer array as a pointer?

Why can a 2D character array be initialized as a pointer but not as a 2D integer array? Why does it give an error when I try to do so? Also, what does initializing an array as a pointer mean?

#include<stdio.h>
int main()
{
    char* m[] = { "Excellent","Good", "bad" };
    int* x[] = { {1,2,3},{4,5,6} }; 
    return 0;                      
}

In the context of a declaration, { and } just mean “here is a group of things.” They do not represent an object or an address or an array. (Note: Within initializations, there are expressions, and those expressions can contain braces in certain contexts that do represent objects. But, in the code shown in the question, the braces just group things.)

In char* m[] = { "Excellent","Good", "bad" }; , three items are listed to initialize m : "Excellent" , "Good" , and "bad" . So each item initializes one element of m .

"Excellent" is a string literal. During compilation, it becomes an array of characters, terminated by a null character. In some situations, an array is kept as an array:

  • When it is used as the operand of sizeof .
  • When it is used as the operand of unary & (for taking an address).
  • When it is a string literal used to initialize an array.

None of these apply in this situation. "Excellent" is not the operand of sizeof , it is not the operand of & , and it is initializing just one element of m , not the entire array. So, the array is not kept as an array: By a rule in C, it is automatically converted to a pointer to its first element. Then this pointer initializes m[0] : m[0] is a pointer to the first element of "Excellent" .

Similarly, m[1] is initialized to a pointer to the first element of "Good" , and m[2] is initialized to a pointer to the first element of "bad" .

In int* x[] = { {1,2,3},{4,5,6} }; , two things are listed to initialize x . Each of these things is itself a group (of three things). However, x is an array of int * . Each member of x should be initialized with a pointer. But a group of three things, {1,2,3} , is not a pointer.

The C rules on interpreting groups of things when initializing arrays and structures are a bit complicated, because they are designed to provide some flexibility for omitting braces, so I have to study the standard a bit more to explain how they apply here. Suffice it to say that the compiler interprets the declaration as using 1 to initialize x[0] . Since 1 is an int and x[0] is an int * , the compiler complains that the types do not match.

Supplementary Notes

char *m[] does not declare a two-dimensional array. It is an array of pointers to char . Because of C's rules, it can generally be used syntactically the same way as a two-dimensional array, so that m[i][j] picks out character j of string i . However, there is a difference between char *m[] and char a[3][4] , for example:

  • In m[i][j] , m[i] is a pointer. That pointer is loaded from memory and use as the base address for [j] . Then j is added to that address, and the character there is loaded from memory. There are two memory loads in this evaluation.
  • In a[i][j] , a[i] is an array. The location of this array is calculated by arithmetic from the start of a . Then a[i][j] is a char , and its address is calculated by adding j , and the character there is loaded from memory. There is one memory load in this evaluation.

There is a syntax for initialization an array of int pointers to point to an array of int . It is called a compound literal . This is infrequently used:

int *x[] = { (int []) {1, 2, 3}, (int []) {4, 5, 6} };

A crucial difference between these string literals and compound literals is that string literals define objects which exist for the lifetime of program execution, but compound literals used inside functions have an automatic storage duration—it will vanish when your function returns, and possibly earlier, depending on where it is used. Novice C programmers should avoid using compound literals until they understand the storage duration rules.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM