Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C Strings: Simple Question

Tags:

c++

c

string

I have three variables initialised below :

char c1[] = "Hello";
char c2[] = { 'H', 'e', 'l', 'l', 'o', '\0'};
char* c3 = "Hello";

I am aware that c1 and c2 are the same, and that they are both strings because they are terminated by \0. However, c3 is different from c1 and c2. Is this because c3 does not terminate with a \0? Does that mean that c3 is not a string? If c3 is not a string, then why does printf("%s", c3); not give an error? Thanks!

EDIT:

Is there a reason why c1 and c2 can be modified but c3 can't?

like image 562
OckhamsRazor Avatar asked Jun 27 '11 04:06

OckhamsRazor


People also ask

What is string in C with example?

In C programming, a string is a sequence of characters terminated with a null character \0 . For example: char c[] = "c string"; When the compiler encounters a sequence of characters enclosed in the double quotation marks, it appends a null character \0 at the end by default.

What is C-string used for?

The C-string is basically a thin piece of wire with fabric around it that can be moulded to fit the shape of your crotch. It's a sanitary towel/thong hybrid. C-strings are sold online at cstringdirect.com and they now come in a variety of colours and materials, including lace and polkadots.

What is string give example?

A string is any series of characters that are interpreted literally by a script. For example, "hello world" and "LKJH019283" are both examples of strings. In computer programming, a string is attached to a variable as shown in the example below.

What is the problem with C-string?

Disadvantages of C-stringsWorking with C-strings is not intuitive. Functions are required to compare strings, and the output of the strcmp functions is not intuitive either. For functions like strcpy and strcat , the programmer is required to remember the correct argument order for each call.


2 Answers

In terms of C, the most pertinent difference between c3 and the others is that you are not allowed to attempt to modify the underlying characters with c3. I often find it helpful to think of it like this:

char *xyz = "xyz";

will create a modifiable pointer on the stack and make it point at the non-modifiable character sequence {'x','y','z','\0'}. On the other hand,

char xyz[] = "xyz";

will create a modifiable array on the stack big enough to hold the character sequence {'x','y','z','\0'} and then copy that character sequence into it. The array contents will then be modifiable. Keep in mind the standard says nothing about stacks but this is commonly how it's done. It is just a memory aid, after all.

Formally, c3 is a pointer to a string literal while c1 and c2 are both arrays of characters which both happen to end with a null character. When they're passed to functions like printf, they decay to a pointer to the first element of the array which means they'll be treated identically to c3 within that function (actually they decay under quite a few circumstances, see third quote from c99 below for exceptions).

The relevant sections of C99 are 6.4.5 String literals which explains why you're not allowed to modify what c3 points to:

It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.

and why it does have a null terminator:

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.

And 6.3.2.1 Lvalues, arrays, and function designators under 6.3 Conversions states:

Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

like image 174
paxdiablo Avatar answered Sep 21 '22 21:09

paxdiablo


First point,

char* c3 = "Hello"; // may be valid C, but bad C++!

is an error prone style, so don't use it. Instead use,

const char* c3 = "Hello";

It's a valid code. Pointer c3 points to the address of the location where "Hello" string is stored. But you cannot modify *c3 (i.e. content of c3) as earlier cases (if you do so, it's an undefined behavior).

like image 38
iammilind Avatar answered Sep 19 '22 21:09

iammilind