Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Initializing an array of strings (char **s vs. char *s[])
Index -> Programming, C -> C Help
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
stkmtd




PostPosted: Thu Nov 18, 2010 11:26 am   Post subject: Initializing an array of strings (char **s vs. char *s[])

When we initialize a single string, it's perfectly valid to say

code:
char *s = "This is a string";


However, when we initialize an array of strings, it seems the following doesn't work:

code:
char **s = {"These", "are", "some", "strings"};


we get the following error:

code:
stringarr.c:5: warning: initialization from incompatible pointer type
stringarr.c:5: warning: excess elements in scalar initializer
stringarr.c:5: warning: (near initialization for ?s?)


Strangely, if we go:

code:
char *s[] = {"These", "are", "some", "strings"};


the code works. I'm wondering what the difference is. In my mind:

char **s -> array of array of char
char *s[] -> array of array of char

Simply put, why can we initialize "char *s[]", and not "char **s"?
Sponsor
Sponsor
Sponsor
sponsor
OneOffDriveByPoster




PostPosted: Fri Nov 19, 2010 12:55 am   Post subject: Re: Initializing an array of strings (char **s vs. char *s[])

stkmtd @ Thu Nov 18, 2010 11:26 am wrote:
Simply put, why can we initialize "char *s[]", and not "char **s"?
char ** is a scalar type. An initializer list should be used with aggregate types. An array of char is a special case in that you can initialize it with a string literal. The reason char * works with a string is because a string literal is an array lvalue (surprise) which will implicitly convert to a char *. The equivalent for your char ** case would be something like:
c:
char **x = (char *[]){"hello", "world"};
stkmtd




PostPosted: Fri Nov 19, 2010 12:24 pm   Post subject: Re: Initializing an array of strings (char **s vs. char *s[])

OneOffDriveByPoster @ Fri Nov 19, 2010 12:55 am wrote:
stkmtd @ Thu Nov 18, 2010 11:26 am wrote:
Simply put, why can we initialize "char *s[]", and not "char **s"?
char ** is a scalar type. An initializer list should be used with aggregate types. An array of char is a special case in that you can initialize it with a string literal. The reason char * works with a string is because a string literal is an array lvalue (surprise) which will implicitly convert to a char *. The equivalent for your char ** case would be something like:
c:
char **x = (char *[]){"hello", "world"};


So, in essence, when I say "char **s", all C knows is that I have a pointer to a pointer (which is scalar, one value). Initializing with a list of values only works for aggregate types (which I gather are definitions like arrays that allow for multiple values).

So in C's mind:

char **s -> single value
char *s[] -> because we have the sq. brackets, C is smart enough to see that we're using an array.

in the case of char **s, the meaning is ambiguous (could be a list of char pointers, or a list of strings, so it avoids doing anything "fancy" (e.g. accepting a list as initialization))

I hope I'm understanding this right.
OneOffDriveByPoster




PostPosted: Fri Nov 19, 2010 5:32 pm   Post subject: Re: Initializing an array of strings (char **s vs. char *s[])

stkmtd @ Fri Nov 19, 2010 12:24 pm wrote:
So, in essence, when I say "char **s", all C knows is that I have a pointer to a pointer (which is scalar, one value). Initializing with a list of values only works for aggregate types (which I gather are definitions like arrays that allow for multiple values).

So in C's mind:

char **s -> single value
char *s[] -> because we have the sq. brackets, C is smart enough to see that we're using an array.
Quite accurate.

stkmtd @ Fri Nov 19, 2010 12:24 pm wrote:
in the case of char **s, the meaning is ambiguous (could be a list of char pointers, or a list of strings, so it avoids doing anything "fancy" (e.g. accepting a list as initialization))

I hope I'm understanding this right.
It is more a lack of motivation to have the initializer list implicitly act as a literal in the example case you had. It may be helpful to revisit the difference between char * and char [].

c:
char *s = "hi"; // s is pointer to char; points to memory owned by string literal

c:
char s[] = "hi"; // s is array of 3 char; s actually holds the characters of the null-terminated string
Xupicor




PostPosted: Tue Feb 22, 2011 8:31 pm   Post subject: RE:Initializing an array of strings (char **s vs. char *s[])

So, in other words:
char** s; - pointer to pointer to char
char* s[N]; an array of pointers to char

You can use the "[]" syntactic sugar to ease yourself, think: the compiler will fill it in on its own at compile time, since I provided it with sufficient information already (the string literal, compound literal, initializer list).
Display posts from previous:   
   Index -> Programming, C -> C Help
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 5 Posts ]
Jump to:   


Style:  
Search: