19

Why do we need the *?

char* test = "testing";

From what I understood, we only apply * onto addresses.

3
  • 2
    This isn't strictly correct, you should say const char * test = "testing";. String literals are pointers to constant chars.
    – Kerrek SB
    Commented Jul 25, 2011 at 22:48
  • 5
    @Kerrek: Actually, string literals are constant char arrays which can decay into pointers to constant chars. Commented Jul 25, 2011 at 23:02
  • @Fred: Yes, even better!
    – Kerrek SB
    Commented Jul 25, 2011 at 23:13

7 Answers 7

43

This is a char:

char c = 't';

It can only hold one character!


This is a C-string:

char s[] = "test";

It can hold multiple characters. Another way to write the above is:

char s[] = {'t', 'e', 's', 't', 0};

The 0 at the end is called the NUL terminator. It denotes the end of a C-string.


A char* stores the starting memory location of a C-string.1 For example, we can use it to refer to the same array s that we defined above. We do this by setting our char* to the memory location of the first element of s:

char* p = &(s[0]);

The & operator gives us the memory location of s[0]. Here is a shorter way to write the above:

char* p = s;

Notice:

*(p + 0) == 't'
*(p + 1) == 'e'
*(p + 2) == 's'
*(p + 3) == 't'
*(p + 4) == 0  // NUL

Or, alternatively:

p[0] == 't'
p[1] == 'e'
p[2] == 's'
p[3] == 't'
p[4] == 0  // NUL

Another common usage of char* is to refer to the memory location of a string literal:

const char* myStringLiteral = "test";

Warning: This string literal should not be changed at runtime. We use const to warn the programmer (and compiler) not to modify myStringLiteral in the following illegal manner:

myStringLiteral[0] = 'b';  // Illegal! Do not do this for const char*!

This is different from the array s above, which we are allowed to modify. This is because the string literal "test" is automatically copied into the array at initialization phase. But with myStringLiteral, no such copying occurs. (Where would we copy to, anyways? There's no array to hold our data... just a lonely char*!)


1 Technical note: char* merely stores a memory location to things of type char. It can certainly refer to just a single char. However, it is much more common to use char* to refer to C-strings, which are NUL-terminated character sequences, as shown above.

6
  • 2
    Maybe use '\0' or 0 to terminate the strings. NULL is the null pointer constant, not the string terminator.
    – Robᵩ
    Commented Jul 25, 2011 at 23:07
  • @Rob I didn't want to bring in backslashes into the picture, so I'll use 0. (Though I think NULL shows the intent more clearly.) Commented Jul 25, 2011 at 23:14
  • 1
    @muntoo: I'd use NUL, which is the ASCII-name for the zero-bits character. Commented Jul 25, 2011 at 23:16
  • @JerryC You mean like this? Isn't NUL just an abbreviation? Commented Jul 25, 2011 at 23:20
  • 1
    @muntoo: Looks better to me, yes. Commented Jul 25, 2011 at 23:21
5

The char type can only represent a single character. When you have a sequence of characters, they are piled next to each other in memory, and the location of the first character in that sequence is returned (assigned to test). Test is nothing more than a pointer to the memory location of the first character in "testing", saying that the type it points to is a char.

4

You can do one of two things:

char *test = "testing";

or:

char test[] = "testing";

Or, a few variations on those themes like:

char const *test = "testing";

I mention this primarily because it's the one you usually really want.

The bottom line, however, is that char x; will only define a single character. If you want a string of characters, you have to define an array of char or a pointer to char (which you'll initialize with a string literal, as above, more often than not).

There are real differences between the first two options though. char *test=... defines a pointer named test, which is initialized to point to a string literal. The string literal itself is allocated statically (typically right along with the code for your program), and you're not supposed to (attempt to) modify it -- thus the preference for char const *.

The char test[] = .. allocates an array. If it's a global, it's pretty similar to the previous except that it does not allocate a separate space for the pointer to the string literal -- rather, test becomes the name attached to the string literal itself.

If you do this as a local variable, test will still refer directly to the string literal - but since it's a local variable, it allocates "auto" storage (typically on the stack), which gets initialized (usually from a normal, statically allocated string literal) on every entry to the block/scope where it's defined.

The latter versions (with an array of char) can act deceptively similar to a pointer, because the name of an array will decay to the address of the beginning of the array anytime you pass it to a function. There are differences though. You can modify the array, but modifying a string literal gives undefined behavior. Conversely, you can change the pointer to point at some other chars, so something like:

char *test = "testing";

if (whatever)
    test = "not testing any more";

...is perfectly fine, but trying to do the same with an array won't work (arrays aren't assignable).

2

The main thing people forgot to mention is that "testing" is an array of chars in memory, there's no such thing as primitive string type in c++. Therefore as with any other array, you can't reference it as if it is an element.

1

char* represents the address of the beginning of the contiguous block of memory of char's. You need it as you are not using a single char variable you are addressing a whole array of char's

When accessing this, functions will take the address of the first char and step through the memory. This is possible as arrays use contiguous memory (i.e. all of the memory is consecutive in memory).

Hope this clears things up! :)

1

Using a * says that this variable points to a location in memory. In this case, it is pointing to the location of the string "testing". With a char pointer, you are not limited to just single characters, because now you have more space available to you.

-2

In C a array is represented by a pointer to the first element in it.

1

Not the answer you're looking for? Browse other questions tagged or ask your own question.