Array M. УЭИТ - Язык Си - руководство для начинающих
- Название:Язык Си - руководство для начинающих
- Автор:
- Жанр:
- Издательство:Мир
- Год:1988
- Город:Москва
- ISBN:5-03-001309-1 /русск./
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Array M. УЭИТ - Язык Си - руководство для начинающих краткое содержание
Язык Си — руководство для начинающих
Язык Си - руководство для начинающих - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Существенны ли эти отличия? Чаще всего нет, но все зависит от того, что вы пытаетесь делать. Посмотрите несколько примеров, а мы возвращаемся к вопросу выделения памяти для строк.
Массив и указатель: различия
В нижеследующем тексте мы обсудим различия в использовании описаний этих двух видов:
static char heart[ ] ="Я люблю Тилли !";
char *head ="Я люблю Милли!";
Основное отличие состоит в том, что указатель heartявляется константой, в то время как указатель head- переменной. Посмотрим, что на самом деле даст эта разница.
Вo-пepвых, и в том и в другом случае можно использовать операцию сложения с указателем.
for(i = 0; i < 6; i++ )
putchar(*(heart + i));
putchar('\n');
for(i = 0; i < 6; i++ )
putchar(*(head + i));
putchar('\n');
в результате получаем
Я люблю Я люблю
Но только в случае с указателем можно использовать операцию увеличения:
while( *(head) != '\0') /* останов и конце строки */
putchar(*(head++ )); /* печать символа и перемещение указателя */
дают в результате:
Я люблю МИЛЛИ!
Предположим, мы хотим заменить headна heart. Мы можем cказать
head = heart /* теперь head указывает на массив hеart */
но теперь мы можем сказать
heart = head; /* запрещенная конструкция */
Ситуация аналогична х = 3или 3 = х;левая часть оператора присваивания должна быть именем переменной. В данном случае head = heart;не уничтожит строку Милли, а только изменит адрес, записанный в head. Вот каким путем можно изменить обращение к heartи проникнуть в сам массив:
heart[8] = 'М';
или
*(heart + 8) = 'М';
Элементы массива (но не имя ) являются переменными
Явное задание размера памяти
Иной путь выделения памяти заключается в явном ее задании. Во внешнем описании мы могли бы скачать:
char m1[44] = "Только ограничьтесь одной строкой.";
вместо
char m1[ ] = "Только ограничьтесь одной строкой.";
Можно быть уверенным, что число элементов по крайней мере на один (это снова нуль-символ) больше, чем длина строки. Как и в других статических или внешних массивах, любые неиспользованные элементы автоматически инициализируются нулем (который в символьном виде является нуль-символом, а не символом цифры нуль).
РИС. 13.2. Инициализация массива.
Отметим, что в нашей программе массиву nameзадан размер:
char name [81];
Поскольку массив nameдолжен читаться во время работы программы, у компилятора нет другого способа узнать заранее, сколько памяти нужно выделить для массива. Это нс символьная константа, в которой компилятор может посчитать символы. Поэтому мы предположили, что 80 символов будет достаточно, чтобы поместить в массив фамилию пользователя.
Массивы символьных строк
Обычно бывает удобно иметь массив символьных строк. В этом случае можно использовать индекс для доступа к нескольким разным строкам. Покажем это на примере:
static char *mytal[LIM] = {"Быстро складываю числа",
"Точно умножаю",
"Записываю данные",
"Правильно выполняю команды",
"Понимаю язык Си"};
Разберемся в этом описании. Вспомним, что LIMимеет значение 5, мы можем сказать, что mytalявляется массивом, состоящим из пяти указателей на символьные строки. Каждая строка символов, конечно же, представляет собой символьный массив, поэтому у нас есть пять указателей на массивы. Первым указателем является mytal[0], и он ссылается на первую строку. Второй указатель mytal[1]ссылается на вторую строку. Каждый указатель, в частности, ссылается на первый символ своей строки:
*mytal[0] == 'Б', *mytal[1] == 'Т', mytal[2] == 'З'
и т. д.
Инициализация выполняется по правилам, определенным для массивов. Тексты в кавычках эквивалентны скобочной записи
{{...}, {...}, ..., {...}};
где многоточия подразумевают тексты, которые мы поленились напечатать. В первую очередь мы хотим отметить, что первая последовательность, заключенная в двойные кавычки, соответствует первым парным скобкам и используется для инициализации первого указателя символьной строки. Следующая последовательность в двойных кавычках инициализирует второй указатель и т. д. Запятая разделяет соседние последовательности.
Кроме того, мы могли бы явно задавать размер строк символов, используя описание, подобное такому:
static char mytal[LIM][LINLIM];
Разница заключается в том, что второй индекс задает "прямоугольный" массив, в котором все "ряды" (строки) имеют одинаковую длину. Описание
static char *mytal [LIM]
однако, определяет "рваный" массив, где длина каждого "ряда" определяется той строкой, которая этот "ряд" инициализировала. Рваный массив не тратит память напрасно.
PИС. 13.3. Прямоугольный массив или pваный
Указатели и строки
Возможно, вы заметили периодическое упоминание указателей в нашем рассказе о строках. Большинство операции языка Си, имеющих дело со строками, работает с указателями. Например, рассморим приведенную ниже бесполезную, но поучительную программу
/* указатели и строки */
#define PX(X) printf("X = %s; значение = %u; &X = %u\n", X, X, &X)
main( ) {
static char *mesg = "He делай глупостей!";
static char *copy;
copy = mesg;
printf(" %s \n" , copy);
PX(mesg);
PX(copy);
}
Взглянув на эту программу, вы можете подумать, что она копирует строку "Не делай глупостей!", и при беглом взгляде на вывод вам может показаться правильным это предположение:
He делай глупостей!
mesg = He делай глупостей!; значение = 14; &mesg = 32
copy = He делай глупостей!; значение = 14; &сору = 34
Но изучим вывод РХ(). Сначала X, который последовательно является mesgи сору, печатается как строка ( %s). Здесь нет сюрприза. Все строки содержат "Не делай глупостей!".
Далее ... вернемся к этому несколько позднее.
Третьим элементом в каждой строке является &X, т. е. адрес X. Указатели mesgи copyзаписаны в ячейках 32 и 34 соответственно.
Теперь о втором элементе, который мы называем значением . Это сам X. Значением указателя является адрес, который он содержит. Мы видим, что mesgссылается на ячейку 14, и поэтому выполняется сору.
Смысл заключается в том, что сама строка никогда не копируется. Оператор copy=mesg;создаст второй указатель, ссылающийся на ту же самую строку.
Читать дальшеИнтервал:
Закладка: