tags:

views:

104

answers:

5

Hi there,

Just trying to really get my head round Arrays and Pointers in C and the differences between them and am having some trouble with 2d arrays.

For the normal 1D array this is what I have learned:

char arr[] = "String constant";

creates an array of chars and the variable arr will always represent the memory created when it was initialized.

char *arr = "String constant";

creates a pointer to char which is currently pointing at the first index of the char array "String constant". The pointer could point somewhere else later.

char *point_arr[] = {
    "one", "two","three", "four"
};

creates an array of pointers which then point to the char arrays "one, "two" etc.

My Question

If we can use both:

char *arr = "constant";

and

char arr[] = "constant";

then why can't I use:

char **pointer_arr = {
    "one", "two", "three", "four"
};

instead of

char *pointer_arr[] = {
    "one", "two", "three", "four"
};

If I try the char ** thing then I get an error like "excess elements in scalar initializer". I can make the char** example work by specifically allocating memory using calloc, but as I didn't have to do this with char *arr = "blah";. I don't see why it is necessary and so I don't really understand the difference between:

char **arr_pointer;

and

char *arr_pointer[];

Many thanks in advance for your advice.

+3  A: 

In short, you cannot use { ... } as an initialiser for a scalar.

char **arr_pointer declares a scalar, not an array. In contrast, the reason you can do char *arr = "constant"; is because you're still declaring a scalar, it just happens to point at a string literal.

Oli Charlesworth
Strictly speaking, you *can* use `{...}` as an initializer for a scalar. In C `int x = { 5 }` is perfectly legal. The compiler is complaining about *excessive* initializers. Although the OP's question is not about that...
AndreyT
+4  A: 

See this answer in the C FAQ:

There it is explained for char [] vs char *. The same thing can be extended to char *[] vs char **.

George B.
A: 

Pointers (char *pointer;) have values; arrays (char array[];) have elements.

The declaration char **ptr2 declares an object that can take a single value, not an object that can take several elements.

pmg
A: 

Quote from Wikipedia:

In computing, a scalar variable or field is one that can hold only one value at a time... ...For example, char, int, float, and double are the most common scalar data types in the C programming language.

So as Oli Charlesworth pointed out in his reply using {.....} initializes multiple items but as char **arr_pointer is a 'scalar' and so can only point at 1 thing at a time (an address) then the {...} notation cannot work here.

Joe
+1  A: 

If you really want to get through the bottom of it then try to understand arrays and pointers through ints rather than chars. According to my experience I had trouble understanding pointers and arrays when chars were involved. Once you understand ints properly you will realize that it's not diff at all.

int *ptr[] is an array of pointers to integers where as int **ptr is a pointer to a pointer that references an integer.

int *arrptrs[2];
arrptrs[0]=(int *)malloc(sizeof(int)*5);
arrptrs[1]=(int *)malloc(sizeof(int)5);
This initializes two arrays referenced by the elements of the array arrptrs. The name of an array refers to the memory location of the first element of an array so arrptrs is of type (int *
) as the first element of this array is of type (int *)

Suppose we do int **ptr=arrptrs Then, *ptr is the first element of arrptrs which is arrptrs[0]and *(ptr+1) is arrptrs[1] and doing a *arrptrs[0] is the first element in the array referenced by arrptrs[0].

I hope this helps although I am not sure if you needed this.

Meeir Aalie