Основы c строк, почему не назначены? - PullRequest
2 голосов
/ 27 сентября 2010

Я пытаюсь изучить основы, я думаю, что объявление char [] и присвоение ему строки будет работать.спасибо

int size = 100;
char str[size];

str = "\x80\xbb\x00\xcd";

выдает ошибку "несовместимые типы в присваивании".в чем дело?спасибо

Ответы [ 7 ]

7 голосов
/ 27 сентября 2010

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

char *str;

str = "\x80\xbb\x00\xcd";
4 голосов
/ 27 сентября 2010

На самом деле это одна из самых сложных частей изучения языка программирования .... str - это массив, то есть часть памяти (размер, умноженный на символ, поэтому размер символа), который зарезервирован и помечен как ул. str [0] - первый символ, str [1] - второй ... str [size-1] - последний. Сама строка, без указания какого-либо символа, является указателем на зону памяти, которая была создана, когда вы сделали

char str[size]

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

strncpy(str, "\x80\xbb\x00\xcd", size); /* Copy up to size characters */
str[size-1]='\0'; /* Make sure that the string is null terminated for small values of size */

Подведение итогов: очень важно различать указатели, области памяти и массив.

Удачи - я уверен, что за меньшее время, чем вы думаете, вы овладеете этими понятиями:)

2 голосов
/ 27 сентября 2010

Массив char может быть косвенно приведен к типу char * при использовании в качестве Rvalue, но не в качестве Lvalue - поэтому назначение не будет работать.

1 голос
/ 27 сентября 2010

Массив нельзя присвоить , используя оператор =.Это просто факт дизайна языка Си.Вы можете инициализировать массив в объявлении, например

char str[size] = "\x80\xbb\x00\xcd";

, но это операция, отличная от присваивания. И обратите внимание, что в этом случае дополнительный '\ 0' будет добавлен в конец строки.

Предупреждение "несовместимые типы" исходит из того, как выражения массива обрабатываютсяязык.Прежде всего, строковые литералы хранятся в виде массивов char со статическим экстентом (то есть они существуют на протяжении всей жизни программы).Таким образом, тип строкового литерала "\ x80 \ xbb \ x00 \ xcd" равен " 4 5-элементный массив из char".Однако в большинстве случаев выражение типа массива будет неявно преобразовываться («распадаться») из типа «массив из N элементов из T» в «указатель на T», и значением выражения будет адрес первогоэлемент в массиве.Итак, когда вы написали оператор

str = "\x80\xbb\x00\xcd";

, тип литерала был неявно преобразован из " 4 5-элементного массива char" в "указатель на char", но целью назначения является тип "массив из 100 элементов char", а типы несовместимы (помимо того факта, что выражение массива не может быть целью оператора =).

Чтобы скопировать содержимое одного массива в другой, вам потребуется использовать библиотечную функцию, такую ​​как memcpy, memmove, strcpy и т. Д. Кроме того, для правильной работы strcpy источникСтрока должна быть 0-концевой.

Редактировать за комментарий R ниже, я вычеркнул более тупые разделы моего ответа.

0 голосов
/ 27 сентября 2010

str это имя массива. Имя массива является адресом 0-го элемента. Следовательно, str является константой указателя. Вы не можете изменить значение константы указателя, как вы не можете изменить константу (например, вы не можете сделать 6 = 5).

0 голосов
/ 27 сентября 2010

char a[100] = "\x80\xbb\x00\xcd"; ИЛИ char a[] = "\x80\xbb\x00\xcd";

0 голосов
/ 27 сентября 2010

Чтобы присвоить строковый литерал массиву str, вы можете использовать функцию копирования строк strcpy.

...