What sorcery is this?

May anyone please explain this line to me?

 
char* P_SampleCharacter = "Hello";

I am greatly surprised with that line of code.
This is how I interpret it "Pointer of char 'SampleCharacters' points to address of "Hello"".
How does 'SampleCharacters' accepts the address of "Hello" even though it is a literal string?

If I do this I receive a syntax error
 
int* P_SampleInteger = 13; 

or
 
char* P_AnotherSampleCharacter = 'a';


English isn't my native language sorry.
Thanks in advance.!
A string literal gives you an array of chars. "Hello" has type char[6] (array of 6 chars).

Arrays automatically decay to a pointer to the first element in the array in many situations.
1
2
int a[2] = { 1, 2 }; 
int* p = a; // OK, p will point to 1 in the a array. 


String literals are actually const (meaning you are not allowed the change the elements in the array) so you should have used a const pointer.

const char* P_SampleCharacter = "Hello";
It is more correct to write this as a pointer to const char:

const char* P_SampleCharacter = "Hello";

How does 'SampleCharacters' accepts the address of "Hello" even though it is a literal string?

It's a feature. The "Hello" string literal will be stored (probably) in a read-only segment of the program's memory. And because it's basically an array of char, you can take its memory address.

This doesn't work with non-arrays literals because the optimizer can possibly remove them from the program completely.

Here's a C program (C99 standard) to show how you can do something similar for non-char arrays.

Unfortunately this relies on a feature of the C language that C++ doesn't have yet, named compound literals.

1
2
3
4
5
6
7
8
#include <stdio.h>

int main(void)
{
    const int *p = (const int[]){10, 11, 12, 13};

    printf("%d\n", p[2]);
}
12

P_Anything
Address of 'P_Anything': 004FFB78
Value its holding: a╠╠╠╠╠╠╠╠o√O
Value(*): a

Character
Address of 'Character': a╠╠╠╠╠╠╠╠o√O
Value its holding: a

        Try 'P_Anything' to hold the address of 'AnotherCharacter'

P_Anything
Address of 'P_Anything': 004FFB78
Value its holding: b╠╠╠╠╠╠╠╠╠╠╠a╠╠╠╠╠╠╠╠c√O
Value(*): b

AnotherCharacter
Address of 'AnotherCharacter': b╠╠╠╠╠╠╠╠╠╠╠a╠╠╠╠╠╠╠╠c√O
Value: b
        Try 'P_Anything' to hold again the previous address

P_Anything
Address of 'P_Anything': 004FFB78
Value its holding: a╠╠╠╠╠╠╠╠o√O
Value(*): a

Character
Address of 'Character': a╠╠╠╠╠╠╠╠o√O
Value its holding: a


I tried to create a simple program to understand more about this.

Whereas,
1
2
3
4
	char* P_Anything = "Hello";
	char Character = 'a';
	char AnotherCharacter = 'b';
	P_Anything = &Character;


It seems that if I let the pointer to hold another address,it is just appending the address of the assigned address to the address that the pointer currently pointing.

There is another question raised on my mind. May you please guys give a real world usage of
char* foo = "boo";

I will research more about this topic. Thanks peter and cat. :D
It seems that if I let the pointer to hold another address,it is just appending the address of the assigned address to the address that the pointer currently pointing.

No. Also pay attention, we told you twice to use a const pointer and you are ignoring that.

C style strings (char arrays) are NUL-terminated. This means that a string like "dog" contains four characters: 'd', 'o', 'g' and 0 (which is called NUL).

So when you print the contents of a pointer to char, the contents are printed until a value of 0 is found. In your case, you see how 'a' and 'b' are situated in memory and you also see what's in between them.

1
2
3
4
5
6
7
8
9
10
#include <iostream>

int main()
{
    //            012345
    char arr[] = "Hello, World!";

    arr[5] = '\0';
    std::cout << arr << std::endl;
}
Hello


There is another question raised on my mind. May you please guys give a real world usage of
char* foo = "boo";


An array of error messages, for example:

1
2
3
4
5
6
const char *errors[] = {
    "Not enough ink.",
    "Not enough paper.",
    "Invalid password.",
    "Invalid pizza."
};


Edit: typos.
Last edited on
The type of a string literal is 'array of const char'

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>

template < std::size_t N >
void foo( char (&) [N] ) { std::cout << "array of char\n" ; }

template < std::size_t N >
void bar( char (&) [N] ) { std::cout << "overload for 'array of char'\n" ; }

template < std::size_t N >
void bar( const char (&) [N] ) { std::cout << "overload for 'array of const char'\n" ; }

int main ()
{
    // foo( "hello" ) ; // *** error: no matching function foo

    bar( "hello" ) ; // overload for 'array of const char'
}

http://coliru.stacked-crooked.com/a/713cf4b70ba03163


> Unfortunately this relies on a feature of the C language that C++ doesn't have yet, named compound literals.

In C++, the deduced type of {10, 11, 12, 13} is std::initializer_list<int>

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>

int main ()
{
    auto lst = { 10, 11, 12, 13 } ;

    for( int v : lst ) std::cout << v << ' ' ; // 10 11 12 13 
    
    std::cout << "(size " << lst.size() << ")\n" ; // (size 4)
    
    std::cout << lst.begin()[2] << '\n' ; // 12
}

http://coliru.stacked-crooked.com/a/175a9245edc65b91
Topic archived. No new replies allowed.