2012-04-10 2 views
17

Я хочу знать, почему первые заявления работ и почему не второй один в C++Присвоение строки символов в массив символов

char a[10]="iqbal"; // it works 

a="iqbal"; // does not work 
+0

Это C или C++? Пожалуйста уточни. –

+2

это получается как прямая оценка через интерфейс SO. Пожалуйста, выполните поиск перед публикацией: возможный дубликат [Назначение строк массивам символов] (http://stackoverflow.com/questions/579734/assigning-strings-to-arrays-of-characters) –

ответ

18

Строго говоря, массив не является указателем! И массив (базовый адрес массива) не может быть измененным значением. т.е. он не может появиться с левой стороны оператора присваивания. При этом разлагаются в указатели только в определенных обстоятельствах. Прочтите это SO post, чтобы узнать, когда массивы распадаются на указатели. Вот еще один nice article, который объясняет различия между массивами и указателями

Также читайте о lvalues ​​и rvalues ​​here, так что вы получите представление о вещах, которые не могут появиться на LHS из =

полукокса A [10 ] = "Iqbal"; // это работает

В этом случае, внутри то, что происходит,

a[0] = 'i'; 
a[1] = 'q'; 
. 
. 
a[5] = '\0'; 

Так что все в порядке, как array[i] является изменяемым именующим.

a = "iqbal"; // не работает

Внутренне, это примерно эквивалентно

0x60000(Address of a, but is a simple number here) = Address of "iqbal" 

Это неправильно, поскольку мы не можем назначить что-то число.

+2

Фактически, 'a' является изменяемым lvalue, но не может появиться в левой части оператора присваивания. Значение l и r в lvalue и rvalue было потеряно давно. – avakar

+0

'a' может быть lvalue, но не _modifiable_ lvalue и _hence_ can not появляются на LHS' = '? Можете ли вы указать мне какую-нибудь документацию, если я ошибаюсь? Я собираюсь [это] (http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/index.jsp?topic=%2Fcom.ibm.vacpp7a.doc%2Flanguage%2Fref%2Fclrc05lvalue.htm) –

+0

@PavanManjunath: Рассмотрите возможность передачи 'a' как фактического аргумента функции со ссылкой на аргумент массива. Очевидно, что 'a' является lvalue в этом случае и модифицируется. И lvalue или rvalue-ness выражения не зависит от контекста, поэтому 'a' является изменяемым значением lvalue. –

3

Первая строка - это не инструкция, а декларация с инициализацией. Вторая строка - оператор выражения с оператором присваивания.

Вы не можете назначить массивы в С.

Но вы можете инициализировать массив с элементами строкового литерала.

4

Массив char a будет статическим и не может быть изменен, если вы его инициализируете так. В любом случае вы никогда не сможете присвоить символьную строку a = "iqbal" в c. Для этого вам нужно использовать strncpy или memcpy. В противном случае вы попытаетесь переписать указатель на строку, и это не то, что вы хотите.

Так что правильный код будет делать что-то вроде:

char a[10]; 
strncpy(a, "iqbal", sizeof(a) - 1); 
a[sizeof(a) - 1] = 0; 

-1 должны зарезервировать байты для завершения ноля. Обратите внимание: вам нужно будет убедиться в том, что строка завершена нулем или нет. Плохое апи. Существует вызов strlcpy(), который делает это для вас, но он не включен в glibc.

0

При написании символа а [10] = «Икбал» Вы инициализация элементов массива символов в с персонажами. Мы можем сделать то же самое с int (обратите внимание, что тип char получает несколько отличную обработку): int a [10] = {1,2, ...};

Но запись следующих частей после объявления будет недействительной, так как a будет обрабатываться точно так же, как указатель. Так пишу что-то вроде a = {1,2, ...}; или a = "iqbal" не имеет никакого смысла!

1

почему первые заявления работает и почему не второй один в C++

Потому что они разные заявления, почти полностью несвязанные. Не путайте с тем, что оба они используют символ =. В одном случае он представляет инициализацию объекта. В другом случае - оператор присваивания.

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

Ваша вторая строка не является законной, поскольку присвоение массиву нецелесообразно.

Поскольку это C++, могу ли я предположить, что вы избегаете голых массивов? Для символьных строк используйте std::string. Для других массивов используйте std::vector. Если вы это сделаете, например, становится:

std::string a = "iqbal"; // it works 
a="iqbal"; // so does this 
0

попробовать:

char a[10]="iqbal"; 
char *my_a = a; 

и работать с my_a.

Смежные вопросы