Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to understand char * ch="123"?

Tags:

c++

char

How should I understand char * ch="123"?

'1' is a char, so I can use:

char x = '1';
char *pt = &x;

But how do I understand char *pt="123"? Why can the char *pt point to string?

Is pt's value the first address value for "123"? If so, how do I get the length for the string pointed to by pt?

like image 844
jiafu Avatar asked Nov 27 '13 09:11

jiafu


People also ask

How does a char * work?

char * a, is just a pointer that can store address, which might be of a single variable or might be the first element of an array. Be ware, we have to assign to this pointer before actually using it. Contrary to that char arr[SIZE] creates an array on the stack i.e. it also allocates SIZE bytes.

What is the meaning of char * ch?

char toLowerCase(char ch) Returns the uppercase or lowercase form of the specified char value. toString(char ch) Returns a String object representing the specified character value — that is, a one-character string.

What does char * a means?

char* means a pointer to a character.

What is the meaning of char * p?

char **p; declares a pointer to a pointer to char . It reserves space for the pointer. It does not reserve any space for the pointed-to pointers or any char . char *p[N]; declares an array of N pointers to char .


3 Answers

That is actually a really good question, and it is the consequence of several oddities in the C language:

1: A pointer to a char (char*) can of course also point to a specific char in an array of chars. That is what pointer arithmetic relies on:

// create an array of three chars
char arr[3] = { 'a', 'b', 'c'};
// point to the first char in the array
char* ptr = &arr[0]
// point to the third char in the array
char* ptr = &arr[2]

2: A string literal ("foo") is actually not a string as such, but simply an array of chars, followed by a null byte. (So "foo" is actually equivalent to the array {'f', 'o', 'o', '\0'})

3: In C, arrays "decay" into pointers to the first element. (This is why many people incorrectly says that "there is no difference between arrays and pointers in C"). That is, when you try to assign an array to a pointer object, it sets the pointer to point to the first element of the array. So given the array arr declared above, you can do char* ptr = arr, and it means the same as char* ptr = &arr[0].

4: In every other case, syntax like this would make the pointer point to an rvalue (loosely speaking, a temporary object, which you can't take the address of), which is generally illegal. (You can't do int* ptr = &42). But when you define a string literal (such as "foo"), it does not create an rvalue. Instead, it creates the char array with static storage. You're creating a static object, which is created when the program is loaded, and of course a pointer can safely point to that.

5: String literals are actually required to be marked as const (because they are static and read-only), but because early versions of C did not have the const keyword, you are allowed to omit the const specifier (at least prior to C++11), to avoid breaking old code (but you still have to treat the variable as read-only).

So char* ch = "123" really means:

  1. write the char array {'1', '2', '3', '\0'} into the static section of the executable (so that when the program is loaded into memory, this variable is created in a read-only section of memory)
  2. when this line of code is executed, create a pointer which points to the first element of this array

As a bonus fun fact, this differs from char ch[] = "123";, which instead means

  1. write the char array {'1', '2', '3', '\0'} into the static section of the executable (so that when the program is loaded into memory, this variable is created in a read-only section of memory)
  2. when this line of code is executed, create an array on the stack which contains a copy of this statically allocated array.
like image 164
jalf Avatar answered Sep 20 '22 18:09

jalf


char* ptr = "123"; is compatible and almost equivalent to char ptr[] = { '1', '2', '3', '\0' }; (see http://ideone.com/rFOk3R).

In C a pointer can point to one value or an array of contiguous values. C++ inherited this. So a string is just an array of character (char) ended by a '\0'. And a pointer to char can point to an array of char.

The length is given by the number of character between the begining and the terminal '\0'. Exemple of C strlen giving you the length of the string:

size_t strlen(const char * str)
{
    const char *s;
    for (s = str; *s; ++s) {}
    return(s - str);
}

An yes it fails horribly if there is no '\0' at the end.

like image 21
Johan Avatar answered Sep 22 '22 18:09

Johan


A string literal is an array of N const char where N is the length of the literal including the implicit NUL terminator. It has static storage duration and it's implementation defined where it is stored. From here on, it's the same a with a normal array - it decays to a pointer to its first character - that's a const char*. What you have there is not legal (not anymore since onset of C++11 standard) in C++, it should be const char* ch = "123";.

You can get the length of a literal with sizeof operator. Once it decays to a pointer, though, you need to iterate through it and find the terminator (that's what strlen function does).

So, with a const char* ch; you get a pointer to a constant character type that can point to a single character, or to the start of an array of characters (or anywhere between the start and the end). The array can be dynamically, autimatically or statically allocated and can be mutable or not.

In something like char ch[] = "text"; you have an array of characters. This is syntatic sugar for a normal array initializer (as in char ch[] = {'t','e','x','t','\0'}; but note that the literal will still be loaded at the start of the program). What hapens here is:

  • an array with automatic storage duration is allocated
  • its size is deduced from the size of the literal by the compiler
  • the contents of the literal are copied to the array

As a result, you have a region of storage that you can use at will (unlike literals, which must not be written into).

like image 24
jrok Avatar answered Sep 21 '22 18:09

jrok