I once asked about pointers a long time ago, I figured it out, thanks to all who answered. But now I had to deal with the type of char :

 int *a; char *b; a = new int(10); b = "bla bla bla"; // Странно ведь мы записываем в адрес, а не в разыменованный указатель cout << "a: " << *a << endl; // Выведет значение, а без * адрес (логично и понятно) cout << "b: " << b << endl; // Выведет значение всего того что мы засунули в "адрес" указателя, почему так, если приводить аналогию с int то почему тут не как там? 

I would like to understand how the pointer to the char type works (I would like to see the reasoned answers, why it is so different, and something from myself as recommendations). Wool Internet - found nothing on the topic of pointers in C ++

PS: I apologize if this topic has gotten everyone or my message is a duplicate (there are similar topics, but, like, this is not what I need).

    4 answers 4

    Let's look at the sentences from your example, step by step.

    In this sentence

     int *a; 

    you declared a variable a as a pointer to an object of type int

    In this sentence

     char *b; 

    you declared b as a pointer to an object of type char

    In this sentence

     a = new int(10); 

    An object was created in the dynamic memory of type int , which was initialized to the value 10.

    In this sentence

     b = "bla bla bla"; 

    on the left side of an expression with an assignment operator is variable with type char * . The right side of this expression uses the string literal "bla bla bla" . C ++ string literals have types of constant character arrays.

    (C ++ Standard, 2.14.5 String literals)

    8 Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow string literal has a type “array of const char” , where there is a storage storage duration (3.7).

    The string literal "bla bla bla" has the type const char [12] . In expressions, arrays are implicitly converted to pointers to their first element.

    According to C ++ standard (4.2 Array-to-pointer conversion)

    1 Analogue of the “array of NT” or “the array of unknown bound of T” can be converted. The result is a pointer to the first element of the array .

    Thus, in the above sentence, the right side of an expression with an assignment operator uses a value of the type const char * , which points to the first character of the string literal "bla bla bla" . That is, there is an attempt to assign the value of a pointer of type char * to the value of a pointer of type const char * . Since there is no implicit conversion from a pointer type to a constant object to a pointer type to a non-constant object, the compiler must issue a diagnostic message.

    It would be correct to declare the variable b as follows.

     const char *b; 

    Then the above assignment statement would be correct, and the variable b would be assigned the address of the first character of the string literal standing on the right side of the expression from the assignment sign.

    This offer

     b = "bla bla bla"; 

    in fact, equivalent to the following sentence

     b = &"bla bla bla"[0]; 

    In this sentence

     cout << "a: " << *a << endl; 

    the integer value addressed by the pointer a is output to the console.

    It would be more correct to write

     cout << "*a: " << *a << endl; ^^^ 

    In this sentence

     cout << "b: " << b << endl; 

    provided that the compiler somehow generated the object module, despite the error I mentioned above, will output a string literal to the console, since for char * pointers the operator << overloaded so that instead of the value of the pointer itself, it outputs the contents of the memory addressed by this pointer as a string.

    If you want to display exactly the value of the pointer itself, then you should write either

     cout << "b: " << ( void * )b << endl; 

    or

     cout << "b: " << static_cast<void *>( b ) << endl; 

    And if the variable b was declared with the const qualifier, then

     cout << "b: " << ( const void * )b << endl; 

    or

     cout << "b: " << static_cast<const void *>( b ) << endl; 
    • and what happens if I write like this * b = "bla bla2"; and when writing, I will write * b - MaximPro
    • @MaximPro Sorry. Your variable b is declared as char *. Therefore * b is of type char and assignment of a pointer of type const char * scalar to type char generates a compilation error. - Vlad from Moscow
    • @MaximPro Also, you did not allocate memory where you want to put the value. That is, the pointer b is not initialized. - Vlad from Moscow
    • Well, it is clear that the initialization is necessary as a matter of course, it is not clear why it is impossible - MaximPro
    • @MaximPro Because these are different types and there is no implicit conversion from one type to another. Usually the size of the address is 4 or 8 bytes, whereas the size of an object of type char is only 1 byte. Therefore, it is not clear how to store the address in an object of type char. You can use casting, but still there’s not much point. - Vlad from Moscow

    You are faced with the special behavior of string literals in C and C ++.

    The fact is that the string literal "bla bla bla" is a constant of type const char* const char [12] [thanks @Pavel Mayorov for clarification] (12 is obtained from 11 characters and an additional zero at the end), and in your context is converted to pointer to the first character of the string / array itself, located by the compiler somewhere in the program. That is, the type of the expression "bla bla bla" is const char [12] , and is implicitly converted to const char* .

    Further, cout has a special behavior for pointers to a character: it treats them as strings, rather than as “ordinary” pointers, and displays all the characters for the first one before the final \0 .

    This special behavior in C ++ is introduced for compatibility with the C language, in which there are no “real” strings. In general, char and char* in C ++ largely have special properties that are complementary to pointers to other types.

    By the way, it is strange that your code was compiled without diagnostics: the types const char* and char* should not be so easily assigned to each other.

    • I understand that in const char * it is impossible to change the value? Why when we write a pointer to cout b does it print all the characters? - MaximPro
    • @MaximPro: Added the answer. In fact, in const char* only a pointer to the very first character, but cout release not only the first, but all subsequent ones up to \0 . - VladD
    • @MaximPro: in const char* it is impossible to change the meaning of the characters in the index. The pointer itself can be changed, of course. - VladD
    • VladD, "bla bla bla" is not a pointer literal, but an array literal! And it can be both of char const[12] type and char[12] depending on the compiler. - Pavel Mayorov
    • one
      @Arkady: It is. For example, the compiler has the right to place string constants in a write-protected section of memory. - VladD

    When the C language only appeared, the character pointers were used to work with the so-called null terminal strings - and by tradition they are still used.

    Therefore, in C and C ++, a pointer to a character is usually a string. And library functions that work with char* know that they work with a string.

    Look at the first part of your console output expressions:

     cout << "a: " cout << "b: " 

    "a: " and "b: " here are also pointers to char . But if instead of these lines were their addresses, you would say that this is strange, wouldn’t it? Then why exactly the same thing, but using an intermediate variable, is surprising?

       b = "bla bla bla"; /// Странно ведь мы записываем в адрес, а не в разименованный указатель 

      "bla bla bla" is not recorded, it is a constant, b - it receives only the address of the first character of this array.

       cout << "b: " << b << endl; /// Выведет значение всего того что мы засунули в "адрес" указателя, почему так, если приводить анологию с int то почему тут не как там? 

      This is due not to a pointer to a char, but to a cout object. Since char * often represents strings, this behavior is defined in cout for it.