Подтвердить что ты не робот

Почему строка может быть назначена указателю char *, но не массиву char []?

Может кто-нибудь объяснить, почему это работает с указателем:

char * str1;

str1 = "Hello1";

str1 = "new string";

// but not this
char str2 [] = "hello";
str2 = "four";

// or this
char str3 [];
str3 = "hello";
str3 = "hello";
4b9b3361

Ответ 1

Почему это работает с указателями:
Когда вы говорите char * str1 в C, вы выделяете указатель в памяти. Когда вы пишете str1 = "Hello";, вы создаете строковый литерал в памяти и указываете на него указатель. Когда вы создаете другой строковый литерал "new string" и назначаете его str1, все, что вы делаете, меняется там, где указывает указатель.

Почему это не работает с массивами:
Когда вы говорите char str2 [] = "Hello", вы создаете строковый литерал и помещаете его в массив во время его определения. Достаточно не указывать размер, так как массив вычисляет его и добавляет к нему '\0'. Вы не можете переназначить что-либо в этот массив без изменения его размера. Вот почему str2 = "four" не будет работать.

В случае str3 это тот же случай. Вы не определили размер массива в определении, поэтому он рассчитал его размер равным 0. Вы не можете назначить что-либо новое без изменения размера массива.

Ответ 2

Массив и указатель - это разные вещи, поэтому. Вы можете назначить указатель, но вы не можете назначить массив. Особое исключение делается для инициализации массивов char со строковыми литералами.

char a[] = "Hello"; //initialize a char array with string literal. Special case, OK
char* p = "Hello"; //initializa a pointer with an array(which gets converted to pointer)
p = "My";   //assign pointer to point to another value. OK
a = "My";   //error, arrays cannot be assigned to. Use `strcpy`

Строковые литералы (такие как "Привет" ) имеют тип char[N], где N - количество символов (включая завершающий '\0'). Массив может быть преобразован в указатель на его первый элемент, но массивы и указатели - это не одно и то же, что могут сказать некоторые плохие книги или учителя.

Ответ 3

Проще говоря, потому что массив не является первоклассным объектом в C/С++. Единственный способ назначить массиву - использовать str (n) cpy или memcpy.

В то время как массив сбрасывается в указатель при передаче функции, невозможно назначить массив, за исключением момента компиляции в качестве инициализации.

Ответ 4

Это просто потому, что, когда вы пишете этот код:

char str2 [] = "hello";

или даже:

int arr[] = {1,2,4,4,5};

он создает str2 или arr как константный указатель. Поэтому вы не можете переназначить любые другие значения этим указателям, а в более позднем случае вы создаете нормальный указатель, и вы можете назначить ему что-либо.

Ответ 5

Случай с указателями Это работает, потому что, когда вы назначаете как str1="Hello", вы на самом деле создаете строковый литерал с именем hello, выделяя его где-то в памяти и назначая указателю первый символ литерала указателю, а поскольку указатель не является константой, вы может назначить его снова с разными адресами. Еще одним важным моментом является то, что строковый литерал создан в памяти только для чтения.

Случай с символьным массивом Вы можете назначить ему строковый литерал, в то время как инициализация будет поддерживаться языком. И не путайте назначение с инициализацией. В то время как назначение, так как его массив символов вы должны изменить символ значения по символу, вы пытаетесь адресовать первый адрес строкового литерала к первому символу массива (имя массива возвращает адрес первого элемента массив). И это явно неверно, поскольку первый элемент не является указателем, он не может хранить адрес.