2010-05-30 2 views

ответ

2

Первая декларация объявляет массив, а второй - указатель.

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

9

char a[]="string"; // a представляет собой массив символов.

char *p="string"; // p строковый литерал, имеющий статическое распределение. Любая попытка изменить содержимое p приводит к неопределенному поведению, поскольку строковые литералы хранятся в разделе памяти только для чтения.

2

Без разницы. Если вы не хотите писать в массив, в этом случае весь мир взорвется, если вы попытаетесь использовать вторую форму. См. here.

27

Первый - это массив, другой - указатель.

Объявление массива «char a[6];» прошу пространство для шести символов быть отведено, чтобы быть известным под названием «a.» То есть, есть место под названием «a», в которой шесть символов могут сидеть. Объявление указателя «char *p;», с другой стороны, запрашивает место, которое содержит указатель. Указатель должен быть известен под именем «p,» и может указывать на любой символ (или непрерывный массив символов) в любом месте.

Операторы

char a[] = "hello"; 
char *p = "world"; 

бы привести к структурам данных, которые могут быть представлены следующим образом:

+---+---+---+---+---+---+ 
a: | h | e | l | l | o |\0 | 
    +---+---+---+---+---+---+ 
    +-----+  +---+---+---+---+---+---+ 
p: | *======> | w | o | r | l | d |\0 | 
    +-----+  +---+---+---+---+---+---+ 

Важно понимать, что ссылка, как х [3] порождает разный код в зависимости от является ли x массивом или указателем. Учитывая вышеприведенные объявления, когда компилятор видит выражение a [3], он испускает код, начинающийся с места «a», перемещаясь три мимо него и извлекая там символ. Когда он видит выражение p [3], он испускает код для начала в месте «p», извлекает здесь значение указателя, добавляет три к указателю и, наконец, извлекает символ, на который указывает. В приведенном выше примере оба параметра [3] и p [3] являются символом «l», но компилятор попадает туда по-другому.

Вы можете использовать поиск Есть тонны объяснений по этому вопросу в Интернете й.

+4

где находится память, выделенная в первом случае и где во втором случае? стек? кучи? когда вы решите указать p на что-то еще, это означает, что «wrold» будет освобожден? – Laz

+6

+1 для работ ASCII. –

+3

@Ram Bhat: в первом случае это зависит от того, где это определение помещено; если он находится в функции, вероятно, в стеке, если он находится в структуре, это зависит от того, где выделяется вся структура; если он находится вне любой функции, в сегменте глобальных варов. То же самое верно для указателя p; строка «world», к которой p указывает, вместо этого * обычно * находится в определенном разделе исполняемого файла, который отображается в памяти при загрузке, который используется как таблица строк. –

1

Одно различие состоит в том, что SizeOf (а) -1 будет заменено на длину строки во время компиляции. С помощью p вам нужно использовать strlen (p), чтобы получить длину во время выполнения. Также некоторые компиляторы не любят char * p = "string", они хотят const char * p = "string", и в этом случае память для "string" доступна только для чтения, но память для a не является. Даже если компилятор не требует объявления const, это неверная практика, чтобы изменить строку, на которую указывает p (т.е. * p = 'a'). Указатель p можно изменить, чтобы указать на что-то другое. С массивом a новое значение должно быть скопировано в массив (если он подходит).