Мне трудно понять, что содержит pointer2
. Второй printf
печатает llo World
, а третий печатает Hey you guys!
. Почему так, если strcpy
копирует y you guys!\n
в llo World
. Насколько я понимаю приведенную ниже программу, последним выводом должен быть llo Worldy you guys!\n
, не так ли?
int main()
{
char str_a[20]; // a 20 element character array
char *pointer; // a pointer, meant for a character array
char *pointer2; // and yet another one
strcpy(str_a, "Hello World\n");
pointer = str_a; // set the first pointer to the start of the array
printf("%p\n", pointer);
pointer2 = pointer + 2; // set the second one 2 bytes further in
printf("%s", pointer2); // print it
strcpy(pointer2, "y you guys!\n"); // copy into that spot
printf("%s", pointer); // print again
}
Почему вы ожидаете, что strcpy
добавит строку в конец? Кроме того, ваш массив может содержать только 20 символов. Вы ожидаете, что он будет держать больше, чем это.
@CaglayanDOKME Как изменяется pointer
? strcpy
не заморачивайтесь.
pointer
не изменяется. Он указывает на str_a
так же, как pointer2
указывает на массив. Этот массив изменен.
@Gerhardh Я думаю, у меня неправильное представление о том, что на самом деле делает pointer + 2
.. Какую часть строки он занимает, He
или остальное?
нвм мальчики. спасибо тебе
Указатель pointer
указывает на первый символ массива str_a
.
pointer = str_a;
Массив содержит строку "Hello World\n"
.
Указатель pointer2
указывает на третий элемент строки
pointer2 = pointer + 2;
то есть он указывает на "llo World\n"
.
Затем эта подстрока перезаписывается, сохраняя неизменными str_a[0]
и str_a[1]
.
strcpy(pointer2, "y you guys!\n");
Итак, массив str_a
содержит строку "Hey you guys!\n"
На самом деле приведенный выше вызов strcpy эквивалентен
strcpy( &str_a[2], "y you guys!\n");
потому что, в свою очередь, это утверждение
pointer2 = pointer + 2;
эквивалентно
pointer2 = &str_a[2];
или
pointer2 = &pointer[2];
И этот звонок
printf("%s", pointer);
выводит строку.
То есть "He"
(начиная с str_a[0]) плюс "y you guys!\n"
(начиная с str_a[2]
) дает результирующую строку.
Где ждет He
? Почему добавляется He
, а не остальная часть строки, которая была сокращена pointer2
?
@userfaultfd Элементы массива str_a[0] и str_a[1] не были перезаписаны. Новая строка была записана, начиная с str_a[2]. И указатель-указатель выводит массив результатов, начиная с str_a[0].
Ага, теперь я понимаю. Моя проблема заключалась в том, что я думал, что указатель сам по себе является объектом. Я не знал, что при strcpy
наведении указателя место, на которое он указывает, также изменяется. Нужно вернуться к указателям ig.
@userfaultfd: указатель — это объект сам по себе, тот, который указывает на другой объект, strcpy
изменяет объект, на который указывает указатель, а не указатель (он остается неизменным)
char str_a[20]; // a 20 element character array
char *pointer; // a pointer, meant for a character array
char *pointer2; // and yet another one
Первая строка создает и выделяет память на 20 символов. Два других только создают указатели ни на что. Эти указатели можно использовать для указания на область памяти, что означает, что вы можете хранить в них адрес (число).
strcpy(str_a, "Hello World\n");
Эту строку скопируйте "Hello World\n" в str_a (выделенная память - ОК).
pointer = str_a; // set the first pointer to the start of the array
printf("%p\n", pointer);
Теперь мы копируем адрес str_a в переменную указатель. Эти две переменные можно использовать одинаково. Они указывают на одно и то же воспоминание. Указанный адрес памяти печатается.
pointer2 = pointer + 2; // set the second one 2 bytes further in
printf("%s", pointer2); // print it
Здесь мы тоже копируем адрес (число), как это делалось раньше, но добавляем 2 к адресу de. Итак, если str_a и указатель указывают на позицию X, то теперь указатель2 будет указывать на X+2 (X — число, адрес блока памяти). Мы знаем, что этот блок (str_a) имеет содержимое "Hello World\n", а затем указатель2 указывает на позицию на 2 символа вправо: "llo World\n". Это означает, что номер адреса, хранящийся в указатель2, указывает на эту позицию, но выделенный блок еще содержит все предложение.
strcpy(pointer2, "y you guys!\n"); // copy into that spot
printf("%s", pointer); // print again
Теперь мы можем видеть копию символов по адресу, указанному указатель2. Таким образом, первые два символа находятся за пределами места копирования, а «y you, ребята!\n» будет скопировано в позицию 2 str_a, то есть в позицию 0 указатель2.
Результат: "He" (два первых символа str_a не тронуты) + "y, ребята!\n" (символы скопированы в указатель2) = "Эй, ребята!\n"
Если вы напечатаете указатель2, вы увидите "у вас, ребята!\n".
Спасибо, Алекс. Теперь я понимаю гораздо больше.
Во-первых, добро пожаловать в StackOverflow.
pointer2
содержит адрес первогоl
вHello World
строке. После его однократной печати данные, на которые он указывает, перезаписываются строкойy you guys
! Строка записывается в память, начиная сpointer2