2015-08-11 4 views
-4
int y = 5; 
int *x = &y; 

Указатель имеет значение адреса как выше ...Почему я могу присвоить значение char * строке?

.

char *y = "Hello World!"; 
char *x = &y; 

Но как же шар не работает таким образом?

char *x = "Hello"; 

Выше кода работает, но как получается, что указатель x может хранить значение строки вместо адреса?

+7

Наблюдение: ваше имя пользователя не один, что делает людей хотят, чтобы помочь вам. –

+1

Ваш исходный пример символов не работает; 'char y =" Hello World! ";' является основным несоответствием типа (указатель, присвоенный 'char'). Если у вас есть 'char y = 'H';', вы можете использовать 'char * x = & y;' - это законно (хотя 'y' не указывает на символьную строку, а указывает только на один символ). Строки - это массивы символов с нулевым терминатором. –

+1

Раньше я думал, что переполнение стека было для людей, поврежденных мозгом. Затем я получил реальную черепно-мозговую травму, и я полностью уверен, что теперь это потрясающе. Правдивая история. : D – PSkocik

ответ

0

Char * - это всего лишь адрес, а не место для хранения данных. Прежде чем вы сможете сохранить строку, вам нужно будет выделить пространство, используя malloc.

0

Литерал "Hello" не будет создан в стеке. Он будет храниться в секции статического чтения только скомпилированного объектного файла или двоичного файла, а char *x будет только указателем на него. Он не сохранит строку. Это назначение возможно только в С, хотя, я считаю, из-за его слабого контроля типа. В C++ вы можете сделать присвоение переменной const char*.

Это:

char x[] = "Hello"; 

будет фактически хранить строку в массив символов в стеке и массив не должен быть const.

strcpy Ввод строкового литерала в malloc Редактирование памяти также будет выполнено, если вы хотите перезаписываемую версию строкового литерала.


Во всяком случае, этот глючный код:

char y = "Hello World!"; 
char *x = &y; 

будет скомпилирован в gcc, но с предупреждением. Строковый литерал будет автоконвертироваться в указатель char *, который автоматически конвертирует в целое число, которое автоматически отменяет char, но это совсем не то, что вы хотите.

+0

Итак, при использовании 'char *' это должно быть 'const', чтобы я не потерял строку' Hello'? –

+1

Это должно быть const, потому что, если это не так, компилятор не будет предупреждать вас о том, чтобы писать в то, на что он указывает. И если вы пишете то, на что указывает, операционная система обычно убьет вас с помощью SEGFAULT, потому что вы будете записывать в память, отмеченную только для чтения. – PSkocik

+1

Обратите внимание, что более старые версии C++ допускают присвоение строкового литерала указателю несимвольный 'char *' для обратной совместимости с C. Это только современные версии C++ (C++ 11 и более поздние версии), которые обесценивают это назначение, заставляя вас использовать вместо указателя 'const char *'. –

1
char *y = "Hello World!"; 
char *x = &y; 

&y является char** (указатель на указатель на char), а не char* (указатель на char). Вы не можете назначить char**char* и наоборот. Они указывают на две разные вещи.

Но как же шар не работает таким образом?

char *x = "Hello"; 

"Hello" является строковый литерал. Он реализован как массив char[] в статической (только для чтения) памяти. Массив может распад в указатель того же базового типа.Однако обратите внимание, что в этом примере назначение строкового литерала в неконстантнымchar* указатель устарел в современных версиях C++. Более старые версии позволяли его для обратной совместимости с С. В современных версиях C++, вам нужно использовать константногоchar* указателя вместо:

const char *y = "Hello World!"; 
const char *x = y; 

В противном случае, вы можете сделать копию буквального в неконстантныхchar[] массив и распада, что в неконстантногоchar* указатель на:

char y[] = "Hello World!"; 
char *x = y; 
Смежные вопросы