2

why does

char *names [] = {"hello", "Jordan"};

work fine

but this does not

char names [] = {"hello", "Jordan"};

would appreciate if someone could explain this to me, thank you :).

3
  • 3
    First one is an array of pointers to strings. The second one is an array of chars. I guess this should be enough to explain why the first one is OK and the second one is not... Commented Sep 17, 2018 at 15:12
  • Because char[] is an array of characters, not an array of strings. It's the same reason char *foo = "Hi"; works, but char foo = "Hi"; does not (though the first one really should be const char *). Commented Sep 17, 2018 at 15:12
  • 1
    Why do you expect the * does not make a difference? What is unclear about the * in a declaration, what does your textbook omit? Commented Sep 17, 2018 at 18:47

4 Answers 4

3

Here

char *names [] = {"hello", "Jordan"};

names is array of char pointers i.e it can holds pointers i.e names each elements itself is one char array. But here

char names [] = {"hello", "Jordan"};

names is just a char array i.e it can hold only single char array like "hello" not multiple.

In second case like

int main(void) {
        char names[] = {"hello", "Jordan"};
        return 0;
}

when you compile(Suggest you to compile with -Wall -pedantic -Wstrict-prototypes -Werror flags), compiler clearly says

error: excess elements in char array initializer

which means you can't have more than one char array in this case. Correct one is

char names[] = {'h','e','l','l','o','\0'}; /* here names is array of characters */

Edit :- Also there is more possibility if syntax of names looks like below

char names[] = { "hello" "Jordan" }; /* its a valid one */

then here both hello and Jordan gets joined & it becomes single char array helloJordan.

char names[] = { "helloJordan" }; 
Sign up to request clarification or add additional context in comments.

Comments

2

The first is an array of pointers to char. The second is an array of char and would have to look like char names[] = {'a', 'b', 'c'}

1 Comment

...or char names[] = "abc" - with an implicit \0 as fourth element.
0

A string literal, such as "hello", is stored in static memory as an array of chars. In fact, a string literal has type char [N], where N is the number of characters in the array (including the \0 terminator). In most cases, an array identifier decays to a pointer to the first element of the array, so in most expressions a string literal such as "hello" will decay to a pointer to the char element 'h'.

char *names[] = { "hello", "Jordan" };

Here the two string literals decay to pointers to char which point to 'h' and 'J', respectively. That is, here the string literals have type char * after the conversion. These types agree with the declaration on the left, and the array names[] (which is not an array of character type, but an array of char *) is initialized using these two pointer values.

char names[] = "hello";

or similarly:

char names[] = { "hello" };

Here we encounter a special case. Array identifiers are not converted to pointers to their first elements when they are operands of the sizeof operator or the unary & operator, or when they are string literals used to initialize an array of character type. So in this case, the string literal "hello" does not decay to a pointer; instead the characters contained in the string literal are used to initialize the array names[].

char names[] = {"hello", "Jordan"};

Again, the string literals would be used to initialize the array names[], but there are excess initializers in the initializer list. This is a constraint violation according to the Standard. From §6.7.9 ¶2 of the C11 Draft Standard:

No initializer shall attempt to provide a value for an object not contained within the entity being initialized.

A conforming implementation must issue a diagnostic in the event of a constraint violation, which may take the form of a warning or an error. On the version of gcc that I am using at the moment (gcc 6.3.0) this diagnostic is an error:

error: excess elements in char array initializer

Yet, for arrays of char that are initialized by an initializer list of char values rather than by string literals, the same diagnostic is a warning instead of an error.

In order to initialize an array of char that is not an array of pointers, you would need a 2d array of chars here. Note that the second dimension is required, and must be large enough to contain the largest string in the initializer list:

char names[][100] = { "hello", "Jordan" };

Here, each string literal is used to initialize an array of 100 chars contained within the larger 2d array of chars. Or, put another way, names[][] is an array of arrays of 100 chars, each of which is initialized by a string literal from the initializer list.

Comments

0

char name[] is an array of characters so you can store a word in it:

char name[] = "Muzol";

This is the same of:

char name[] = {'M', 'u', 'z', 'o', 'l', '\0'}; /* '\0' is NULL, it means end of the array */

And char* names[] is an array of arrays where each element of the first array points to the start of the elements of the second array.

char* name[] = {"name1", "name2"};

It's the same of:

char name1[] = {'n', 'a', 'm', 'e', '1', '\0'}; /* or char name1[] = "name1"; */
char name2[] = {'n', 'a', 'm', 'e', '2', '\0'}; /* or char name2[] = "name2"; */
char* names[] = { name1, name2 };

So basically names[0] points to &name1[0], where it can read the memory until name1[5], this is where it finds the '\0' (NULL) character and stops. The same happens for name2[];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.