Как этот массив символов может хранить четыре отдельные строки?

Меня смущает этот фрагмент из книги, которую я читаю. Текстовые строки помещаются в массив char. Есть четыре слова с четырьмя элементами в массиве. Подождите, но это означает, что один элемент char содержит целую текстовую строку. Я уверен, что chars может обрабатывать только один символ. Вот код.

const char *words[4] = { "aardvark", "abacus", 
    "allude", "zygote" };

Так что дает? Как автор может использовать chars для хранения целых строк? Я знаю, что решение должно быть ослепительно очевидным, но я просто не вижу его. Кроме того, что с ключевым словом const? Почему его нужно только читать, если все, что мы планируем делать с этим массивом, — это подсчитывать длину каждого слова, используя strlen()?


person Mackey18    schedule 17.09.2012    source источник
comment
Очень похоже (видимо, этот человек читает ту же книгу): stackoverflow.com/questions/9876693/   -  person jscs    schedule 17.09.2012
comment
Ты прав. Возможно, это свидетельствует о том, что эта конкретная книга не полностью объясняет, что она делает. Спасибо за ссылку.   -  person Mackey18    schedule 17.09.2012


Ответы (3)


Код не использует символы для хранения строк, обратите внимание, что объявление представляет собой массив char *.

char может содержать один символ, а char * может использоваться для указания на первый элемент массива символов, который может содержать стандартную строку C. Это важная основа C: посмотрите на char *, и вы сразу же должны подумать о строках C, оканчивающихся нулем.

Точно так же int * можно использовать для ссылки на весь массив int, сохраняя адрес первого int в массиве. int* можно индексировать так же, как массив, объявленный с помощью [].

char * также можно использовать для простого хранения адреса одного символа, т. е. не первого символа в строке с завершающим нулем.

person pb2q    schedule 17.09.2012
comment
Я думаю, что спрашивающий знает это - он упустил то, что синтаксис const char* words[] разрешается в const char** words - person JRaymond; 17.09.2012
comment
Верно, это многое объясняет. char *, должно быть, намекнул на меня. Мне нужно изучить это сейчас, но, конечно, использование char * сильно ограничивает вас в отношении просмотра каждого символа в этой строке. Обычно вы бы использовали word [5], чтобы получить 5-ю букву в слове, но это невозможно, используя char *, не так ли? Еще раз спасибо за полезный ответ, я отметил вас и сделаю этот ответ принятым, когда это будет возможно. - person Mackey18; 17.09.2012
comment
@ Mackey18 то же самое возможно: вы можете индексировать, например. char * то же, что и char[], и, конечно же, то же самое для других типов - person pb2q; 17.09.2012
comment
@Mackey18 Mackey18, упомянутый вами синтаксис массива на самом деле является сокращением для арифметики указателей - он фактически разрешается в (word + 5) - и разрешается одинаково, используете ли вы char* или char word[] - вот почему строки в c заканчиваются нулем - иначе вы бы не знали где конец - person JRaymond; 17.09.2012
comment
Да, words[1][3] должен оцениваться как 'c' в "abacus". - person Analog File; 17.09.2012
comment
Итак, в этом примере я мог бы использовать (word [2] + 5) для получения 5-го символа второго массива символов, т.е. U? Это правильно. РЕДАКТИРОВАТЬ: Только что увидел ваш комментарий Аналоговый, это кажется гораздо более приятным способом ведения дел. Спасибо. - person Mackey18; 17.09.2012
comment
@Mackey18 прочитал это - это хороший материал cs.umd .edu/class/sum2003/cmsc311/Notes/BitOp/pointer.html - person JRaymond; 17.09.2012
comment
Это хорошее чтение, очень подробное и охватывает многое. Мне все еще кажется странным, что, прочитав целую книгу по C, в которой подробно рассматриваются строки и массивы, ни разу не упоминалось, что char* создаст массив символов. Единственные строки, которые он охватывал, были исключительно в форме char word [i], где i — отдельные символы. - person Mackey18; 17.09.2012
comment
Извините, я знаю, что не должен задавать дополнительные вопросы, но вот. Большая часть моего изучения C была связана с тем фактом, что определенные массивы тратят память впустую, если она не используется, то есть массив comment [250] (дающий вам 250 символов для написания комментария) был бы расточительным, если бы ввод использовал только 100 символов. Полностью ли char * решает эту проблему, делая его очень эффективным с точки зрения использования памяти? Кроме того, прав ли я, говоря, что он автоматически добавляет Null в конец, поэтому я знаю, что больше не нужно вручную добавлять null в строку из входного буфера? - person Mackey18; 17.09.2012
comment
использование char * на самом деле не меняет количество неиспользуемых элементов, которые могут оказаться в массиве. вам, как правило, все еще нужно выбрать верхнюю границу для вашего буфера, и, как правило, он не заполнит все. Это действительно не проблема. И обычно вы не получаете автоматическое завершение нуля, но некоторые методы библиотеки строк добавят для вас нулевое значение. Вы должны быть всегда осторожны с этим моментом. - person pb2q; 17.09.2012
comment
@JRaymond, по поводу первого комментария, массив не является указателем. Если бы это было так, этот пример печатал бы одинаковый размер для обоих. - person chris; 17.09.2012
comment
@Mackey18 также обратите внимание, что с помощью realloc вы можете увеличить размер буфера, выделенного с помощью malloc, поэтому, когда вы выбираете размеры буфера, они не должны быть разовыми. например если вы читаете файл или сетевой поток, вы можете выбрать верхнюю границу и увеличить ее позже по мере необходимости. - person pb2q; 18.09.2012
comment
Да, я уже сталкивался с malloc, но не с realloc. Используется ли malloc в Objective-C вообще? - person Mackey18; 18.09.2012


Точка, которую вам не хватает, это *.

char letter = 'a';  //stores a single character
char *word = "bigger"; //stores a string literal

это означает, что слово действительно:

word ---> [b][i][g][g][e][r][\0]

указывая на группу символов (или "строку" символов). В вашем примере автор определил:

const char *words[4] = { "aardvark", "abacus",      "allude", "zygote" }; 

Итак, у вас есть 4 строки символов, которые являются постоянными. Константа была выбрана автором, чтобы добавить это туда... ее можно было бы не использовать. Это просто гарантия, примечание для компилятора (и автора), что эти значения не должны были быть изменены.

person Mike    schedule 17.09.2012
comment
Спасибо, Майк, за действительно ясный ответ, это мне очень помогло. Пометил тебя. - person Mackey18; 17.09.2012
comment
@ Mackey18 - Рад помочь, нам всем нужно с чего-то начинать :) - person Mike; 17.09.2012