-1

Possible Duplicate:
What is the difference between char s[] and char *s in C?

Can the statements

char str[]="abcdef"; 

and

char *str="abcdef"; 

be used to explain the char array and string literal in C? What is relationship between char array and string literal? What is actually usage of char array except storing a string literal?

Community
  • 1
  • 1
Victor S
  • 4,021
  • 15
  • 43
  • 54
  • http://c-faq.com/strangeprob/strlitnomod.html http://c-faq.com/decl/strlitinit.html – cnicutar Jul 31 '12 at 06:23
  • Another question: in statement char str[]="abcdef"; Is the str a char array, is "abcdef" a string literal? – Victor S Jul 31 '12 at 06:42
  • That's correct, `str` is a `char` array, and `"abcdef"` is a string literal - which is a special kind of `char` array. – Daniel Fischer Jul 31 '12 at 06:44
  • @DanielFischer string literal is a special kind of char array, what is its special point? – Victor S Jul 31 '12 at 06:52
  • They're unmodifiable (trying to modify one is UB). The compiler-inserted 0-terminator can also be considered special. But mostly, it's that they're unmodifiable although their type is plan `char[strlen(string) + 1]` – Daniel Fischer Jul 31 '12 at 06:57

2 Answers2

4

A string literal is an array of char that is not modifiable.

C99 6.4.5 p2:

A character string literal is a sequence of zero or more multibyte characters enclosed in double-quotes, as in "xyz".

And then, in C99 6.4.5 p5:

In translation phase 7, a byte or code of value zero is appended to each multibyte character sequence that results from a string literal or literals. The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence. For character string literals, the array elements have type char, and are initialized with the individual bytes of the multibyte character sequence;...

The draft C11 I have has similar wording. I believe it is worded with "have type char" precisely to allow a string literal to be assigned to char *. However, the standard does go on to say in C99 6.4.5 p6:

If the program attempts to modify such an array, the behavior is undefined.

So assignable, but not modifiable.

A string literal can be used as an initializer for an array of char. From C99 6.7.8 p14:

An array of character type may be initialized by a character string literal, optionally enclosed in braces. Successive characters of the character string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.

jxh
  • 69,070
  • 8
  • 110
  • 193
0

Your second assignment is erronous. It should be a const char * - string literals, when assigned to a pointer, are constants, but they become modifiable when they initialize an array. For example, you couldn't use the 2nd version in a call to strtok() (google its man page to see why!)

  • So what if I later want to point `str` at modifiable data ? – cnicutar Jul 31 '12 at 06:24
  • you have to either `strdup()` it OR `strcpy()` to a non-const buffer. –  Jul 31 '12 at 06:25
  • **Or** I could just not make it `const` in the first place and just change the pointer. – cnicutar Jul 31 '12 at 06:26
  • @cnicutar no. The string literal itself is created read-only by the compiler and it'll segfault (so please revoke your downvote). –  Jul 31 '12 at 06:29
  • 1
    H2CO3 I didn't downvote (you can look at my vote count). I think you also misread my comments. I know full well literals are non-modifiable. I was just asking, what if you want to make `str` point to an object that **is modifiable** ? I.e. I was challenging your first statement that the `const` is needed. – cnicutar Jul 31 '12 at 06:30
  • 1
    @Flexo Why won't anyone read carefully :-) You can't point a `const` pointer at non-`const` data. – cnicutar Jul 31 '12 at 06:31
  • 1
    You *can* point a `const` pointer at non-`const` data. And you should prefer that to doing the opposite. If you use the same pointer variable both for pointing at unmodifiable strings and modifiable strings, it should be a pointer-to-const. If you need to actually use that variable to do the modifying of a modifiable string, change your design. – Alan Curry Jul 31 '12 at 06:36
  • @AlanCurry You can point it but it won't do you much good if you need to change the object. That's why one shouldn't throw `const` everywhere "because it's safer". – cnicutar Jul 31 '12 at 06:38
  • 1
    Think of `const char *` as meaning "pointer to char" and `char *` as meaning "pointer to char **and I intend to modify it**" – Alan Curry Jul 31 '12 at 06:40
  • @cnicutar if you're using a `const char *`, you can modify the **pointer** itself, you just can't do like `pointer[1] = 'a';` -- a const char * is **not** a const pointer to a char, but a non-const pointer to a const char. –  Jul 31 '12 at 07:46
  • I said it three times already. Let's say I have a `char modifiable[100]`. And I want to point your `const char *str` at it. I can, of course. **But I can't use it to modify it** - the const stops me from doing so. – cnicutar Jul 31 '12 at 07:48
  • @cnicutar of course it does. But why would you want to reuse a pointer to a string literal to point to a non-literal string? –  Jul 31 '12 at 07:52
  • I don't know. I'm just challenging your first statement that the pointer automatically should be a `const char *`. Maybe it should, maybe it shouldn't. – cnicutar Jul 31 '12 at 07:54
  • @cnicutar it should, because you can assign a const char * to a char *, but not vice versa. –  Jul 31 '12 at 08:12
  • 2
    @H2CO3 “you can assign a const char * to a char *, but not vice versa” Are you saying that one cannot assign a char * expression to a const char * lvalue? Considering that this is exactly what you are suggesting to do —string literals have type char[] in C, no const— I have a hard time understanding what you are getting at. – Pascal Cuoq Jul 31 '12 at 13:32
  • @PascalCuoq sorry, I meant exactly the opposite. I'll add the correct comment. –  Jul 31 '12 at 17:09
  • @cnicutar so it should be a const char, because you can assign a char * to a pointer of type const char *, but you can't assign a const char * value to a char * variable. –  Jul 31 '12 at 17:10