Разница между назначением строкового литерала массиву символов при объявлении и указателю на символ?

avatar
Naja
8 августа 2021 в 22:46
157
1
1

Я пытаюсь понять, почему оба :

#include <unistd.h>

int main()
{
    char buffer[8] = "Hello \n";
    write(1, buffer, 7);
    return 0;
}

и

#include <unistd.h> 

int main()
{
   char buffer[8];
   char *ptr = buffer;
   ptr = "Hello \n";
   write(1, ptr, 7);
   return 0;
}

успешно выводит "Hello " на консоль, но

#include <unistd.h> 

int main()
{
   char buffer[8];
   char *ptr = buffer;
   ptr = "Hello \n";
   write(1, buffer, 7);
   retrun 0;
}

нет (вместо этого выводит тарабарщину), когда я ожидаю, что все три будут по существу одинаковыми.

Я предполагаю, что в моем понимании отношений между указателями и массивами в c ...

есть что-то принципиально неверное.
Источник
kaylum
8 августа 2021 в 22:49
2

Указатель хранит адрес некоторой памяти. Изменение указателя не меняет содержимого того, на что он указывал. Просто указывает куда-то еще. Таким образом, в последних двух примерах указатель изменяется с указателя на память buffer на строковый литерал. Исходное содержимое buffer не изменилось.

jxh
8 августа 2021 в 22:54
2

buffer и ptr — это две разные переменные (с разными типами для загрузки). Если у вас есть две переменные int, присвоение значения одной из них не повлияет на другую.

jxh
8 августа 2021 в 22:57
0

Переменная-указатель может использоваться для воздействия на значение объекта, на который указывает указатель, но вы должны разыменовать указатель для обращения к объекту, на который указывает ссылка.

Ответы (1)

avatar
paulsm4
8 августа 2021 в 22:51
3

Здесь вы смешиваете несколько разных, не связанных между собой проблем:

 char buffer[8];      // You're allocating 8 bytes: OK
 char *ptr = buffer;  // You're aliasing "ptr" to "&buffer[0]": OK
 ptr = "Hello \n";    // Now you're ASSIGNING ptr to a completely DIFFERENT address
 write(1, buffer, 7); // You never actually assigned any data to buffer

Предположим, вместо этого вы сделали следующее:

 char buffer[8];      // Allocate 8 bytes
 char *ptr = buffer;  // Aliasing "ptr" to "&buffer[0]"
 strcpy(ptr, "Hello \n"); // Now you've actually assigned data
 write(1, buffer, 7); /. You should no longer see "garbage" ;)

Другими словами, это не столько "указатели против массивов"; на самом деле это "правильная инициализация того, на что вы указываете".

'Надеюсь, это поможет...

Naja
8 августа 2021 в 22:54
0

Ах, это имеет смысл, большое спасибо. Думаю, я не понимал, как строковые литералы работают больше, чем указатели...