2013-12-03 4 views
9

если я пишу этотсимвол * массив и массив символов []

char *array = "One good thing about music"; 

Я на самом деле создать массив? Я имею в виду, что это одно и то же?

char array[] = {"One", "good", "thing", "about", "music"}; 
+0

Я понимаю, что вы на самом деле имел в виду '{«One», «хорошо», «вещь», «о», «музыка»}; В противном случае вопрос не имеет никакого смысла. – Lundin

+0

да, вы правы, я редактировал. – yaylitzis

+0

http://stackoverflow.com/questions/1704407/what-is-the-difference-between-char-s-and-char-s-in-c –

ответ

26

Декларация и инициализация

char *array = "One good thing about music"; 

объявляет указатель array и чтобы она указывала на постоянной массив из 31 символов.

Объявление и инициализация

char array[] = "One, good, thing, about, music"; 

объявляет массив символов, содержащий 31 символа.

И да, размер массивов равен 31, так как он включает в себя завершающий символ '\0'.


Выложенный в памяти, то это будет что-то подобное для первого:

 
+-------+  +------------------------------+ 
| array | --> | "One good thing about music" | 
+-------+  +------------------------------+ 

И как это для второй:

 
+------------------------------+ 
| "One good thing about music" | 
+------------------------------+ 

Массивы распадается на указатели к первому элементу массива. Если у вас есть массив как

char array[] = "One, good, thing, about, music"; 

затем, используя обычный array, когда указатель, как ожидается, это то же самое, как &array[0].

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

Указатели и массивы почти сменный. Вы не можете, например, использовать sizeof(pointer), потому что это возвращает размер фактического указателя, а не то, на что указывает. Также, когда вы делаете это, например, &pointer вы получаете адрес указателя, но &array возвращает указатель на массив. Следует отметить, что &arrayочень отличается от array (или его эквивалентом &array[0]). Хотя оба &array и &array[0] указывают на одно и то же место, типы разные. Используя вышеприведенный порядок, &array имеет тип char (*)[31], а &array[0] имеет тип char *.


Для большего удовольствия: как известно, при доступе к указателю можно использовать индексирование массива. Но поскольку массивы распадается на указатели, можно использовать некоторую арифметику указателя с массивами.

Например:

char array[] = "Foobar"; /* Declare an array of 7 characters */ 

С выше, вы можете получить доступ к четвертому элементу ('b 'символов), используя либо

array[3] 

или

*(array + 3) 

И потому, что помимо commutative, последний также может быть выражен как

*(3 + array) 

, что приводит к забавному синтаксису

3[array] 
+0

Во второй команде можно использовать 'array' как указатель на этот массив? – yaylitzis

+1

@ Nat95 Обновлен мой ответ другим абзацем. –

+2

'& array' - указатель на массив, а не на первый элемент, который будет' & array [0] '. –

1

Нет. На самом деле это «тот же», как

char array[] = {'O', 'n', 'e', ..... 'i','c','\0'); 

Каждый символ представляет собой отдельный элемент, с дополнительным \0 символ в виде строки терминатор.

Я процитировал «тот же», потому что есть некоторые различия между char * array и char array[]. Если вы хотите узнать больше, посмотрите на C: differences between char pointer and array

+0

OP не имеет массива. У нее есть указатель. –

+1

Это не «незначительные» отличия. И лучше уточнить их, чем оставить ОП и будущих читателей путать. – StoryTeller

+0

Как массив только для чтения a _ "minor" _ разница, и не относится к OP? Если вы скажете что-то подобное, в течение следующих 15 минут обязательно будет следующий вопрос. –

2

Это очень похоже на

char array[] = {'O', 'n', 'e', ' ', /*etc*/ ' ', 'm', 'u', 's', 'i', 'c', '\0'}; 

но дает только для чтения памяти.

Обсудить разницу между char[] и char *, см. comp.lang.c FAQ 1.32.

+0

Что вы подразумеваете под постоянным запоминающим устройством? – yaylitzis

+0

Это означает, что если вы попытаетесь записать на него (например, 'array [0] = 'X''), вы получите неопределенное поведение (обычно это ошибка сегментации). – tom

8

Нет, вы создаете массив, но есть большая разница:

char *string = "Some CONSTANT string"; 
printf("%c\n", string[1]);//prints o 
string[1] = 'v';//INVALID!! 

Массив создается в только для чтения части памяти, так что вы не можете изменить значение через указатель, в то время как:

char string[] = "Some string"; 

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

string[1] = 'v'; 

Действителен в последнем случае.
Если вы пишете:

char string[] = {"some", " string"}; 

компилятор должен жаловаться, потому что вы построив массив символьных массивов (или символьных указателей), и назначение его в массив символов. Эти типы не совпадают. Либо написать:

char string[] = {'s','o','m', 'e', ' ', 's', 't','r','i','n','g', '\o'}; 
//this is a bit silly, because it's the same as char string[] = "some string"; 
//or 
char *string[] = {"some", " string"};//array of pointers to CONSTANT strings 
//or 
char string[][10] = {"some", " string"}; 

Где последняя версия дает вам массив строк (массивы символов), что вы на самом деле может редактировать ...

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