Указатель - запрос - PullRequest
       12

Указатель - запрос

1 голос
/ 21 марта 2011
#include <stdio.h>
#include <stdlib.h>

int main( void ) {
   char *ptr1 = "Hello World\n";
   char *ptr2;

   ptr2 = ptr1 + 6;
   ptr2 = "Test!\n";

   printf("%s",ptr2);
   printf("%s",ptr1);

   return EXIT_SUCCESS;   
}

Вывод:

Test!
Hello World

Почему я не получил Hello Test!?Я думал, что id перезапишет World -часть из ptr1.

Ответы [ 7 ]

6 голосов
/ 21 марта 2011

Строка

ptr2 = "Test!\n";

Изменяет ли не содержимое буфера, на которое указывает ptr2.Вместо этого он просто меняет то, на что указывает ptr2.В С присваивание указателя просто говорит: «Я хочу, чтобы этот указатель прекратил ссылаться на то, на что он ссылался, и вместо этого указал на что-то другое».Если вы действительно хотите изменить значение, на которое указывает указатель, вам нужно либо разыменовать указатель, либо вызвать функцию, которая разыменовывает его (например, strcpy, strcat и т. Д.)

Следовательно,вывод - это то, что вы перечислили выше с сохранением «Hello World».

4 голосов
/ 21 марта 2011

Когда вы назначаете что-то указателю, например ptr1 или ptr2. вы не меняете значение того, что там хранится, вы просто меняете то, на что они указывают.

Когда вы говорите:

ptr2 = ptr1 + 6;

Вы указываете ptr2 на 6-й элемент строки ptr1. Тогда вы говорите:

ptr2 = "Test!\n";

Это означает, что ptr2 теперь указывает на новую, другую строку в другом месте памяти, которая содержит "Test!\n". Итак, у вас есть это:

ptr  ------->  "Hello World\n"
ptr2 ------->  "Test\n"

Теперь, когда вы печатаете их, вы получаете:

Test!
Hello World
3 голосов
/ 21 марта 2011
ptr2 = "Test!\n"

Просто устанавливает ptr2, чтобы он указывал на новую строку символов.Логично, что вы хотели написать *ptr2 = ...., Но теперь вы будете изменять строковый литерал в постоянной памяти.Вам необходимо объявить ptr1 как char[], чтобы строковый литерал размещался в памяти стека, если вы хотите его изменить.

2 голосов
/ 21 марта 2011

Потому что:

   char *ptr1 = "Hello World\n";
   char *ptr2;

На данный момент у вас есть два указателя, один из которых указывает на место в памяти, содержащее «Hello World», а другой - неинициализированный,

   ptr2 = ptr1 + 6;

Теперь ptr2 очковв ячейку памяти через 6 байтов после ячейки, на которую указывает ptr1, в другом - буква «W» «Hello World».Если бы вы вывели ptr2 сейчас, вы бы увидели «Мир».

   ptr2 = "Test!\n";

Теперь ptr2 указывает на совершенно другую область памяти, которая содержит «Test!»

Вот почему при выводеуказатели вы видите, что вы делаете.

2 голосов
/ 21 марта 2011

Указатели просто указывают на адреса памяти.

Ваши назначения ничего не пишут, они просто меняют то, куда указывает ptr2.

Также обратите внимание, что вы не можете перезаписыватьконстантные строки в вашем исполняемом файле все равно могут привести к сбою вашей программы.

1 голос
/ 21 марта 2011

Потому что:

   ptr2 = "Test!\n";

Назначает адрес константы литерала "Test!\n" для ptr2, перезаписывая адрес, который вы присвоили в предыдущей строке.

0 голосов
/ 21 марта 2011

ptr2 = "Test!\n"; Теперь ptr2 указывает на строковый литерал "Test!\n". Содержимое строкового литерала нигде не изменяется.

ptr1 по-прежнему указывает на "Hello World\n".

Я думал, что id перезапишет часть Мира из ptr1.

И почему вы когда-нибудь задумывались об этом?Попытка изменить содержимое строкового литерала - неопределенное поведение.

...