Есть ли исключения для const char *? - PullRequest
0 голосов
/ 27 сентября 2019

Если cstring - указатель, то почему он может получить значение напрямую?Во-вторых, почему результат ‍‍‍ *cstring не равен целой строке?В-третьих, cstring - это непостоянный указатель на постоянный символ, так зачем менять его значение, а не менять его адрес?

#include <cstdio>
#include <conio.h>
#include <iostream>

using namespace std;

int main() 
{
    const char* cstring = "string";
    cout << cstring << endl << *cstring << endl << &cstring << endl;

    cstring = "foo";
    cout << cstring << endl << *cstring << endl << &cstring << endl;

    _getch();
    return 0;
}

Ответы [ 2 ]

2 голосов
/ 27 сентября 2019

Если cstring является указателем, то почему он может получить значение напрямую?

operator << из cout для const char* специализируется на таком поведении.Он будет обрабатывать указатель как завершенную NULL строку и будет печатать ее вместо значения указателя.Для разных типов вы получаете разное поведение.Для char* у вас напечатана вся строка.

Почему результат c * cstring не равен целой строке?

Это потому, что тип * cstring равен char и снова operator << ведет себя правильно, просто печатая один символ.const char* - это, по сути, массив char. Массив, по сути, является указателем на первый элемент массива.Если вы используете оператор * для указателя, вы получаете доступ ко всему, на что указывает указатель.Если он указывает на первый элемент, то вы получите первый элемент.

В-третьих, cstring - это непостоянный указатель на постоянный символ, поэтому зачем менять его значение, а не изменять егоадрес?

Как вы сказали, cstring - это непостоянный указатель на постоянные данные.Вы не можете изменить место, на которое он указывает (это постоянный указатель), но вы можете заменить содержимое указанных данных другим материалом.Вы указываете на то же место, но содержимое этой ячейки изменяется.

1 голос
/ 27 сентября 2019

Если cstring является указателем, то почему он может получить значение напрямую?

Любой может получить значение, на которое указывает указатель, путем разыменования указателя.Вот что происходит, когда вы делаете std::cout << cstring.Выбирается правильная перегрузка, которая печатает строку, представленную cstring, при условии, что это правильно сформированная строка в стиле C.результат, равный целой строке?

cstring равен const char*, поэтому *cstring равен const char.Передайте это std::cout, и это вызовет перегрузку, которая печатает один char.Функция, которая вызывается внутри, даже не знает, что это всего лишь один char в строке.

В-третьих, cstring - это непостоянный указатель на постоянный символ, так почемуизменить его значение и не изменить его адрес?

Вы не можете изменить адрес переменной.cstring находится в фиксированном месте в стеке.Вы изменяете значение cstring, которое является адресом строки, на которую оно указывает (теперь оно указывает на другую строку, имеющую другой адрес, "string", конечно, стиль имеет тот же адрес).

Что вы, вероятно, хотели попробовать, это:

const char* cstring = "string";
std::cout << (void*)cstring << std::endl;
cstring = "foo";
std::cout << (void*)cstring << std::endl;

Теперь вы можете увидеть разные адреса.Один - это адрес "string", а другой - "foo".

...