Наш провайдер rinet
UnixFAQ.ru
   :: Поиск  
   :: Самые новые ::

   :: Самые читаемые ::
   :: Реклама ::
Заказ услуг частного охранного предприятия - лучший выбор фирмы.
шкатулки для часов

Начало
Программирование под UNIX
Язык Си

Чем отличаются простая переменная и массив из одного элемента?

 

Рассмотрим такие объявления:

int i;
int a[1];

Хотя, на первый взгляд, объекты a и i отличаются, почти все их аспекты в языке Си эквивалентны. Так, у них один и тот же размер (sizeof); i и a[0] -- это значения типа int, причем lvalue (то есть, они могут встречаться в левой части оператора присваивания); наконец, &i и a -- это константные указатели на объект int.

Тем не менее, в ANSI Си между свойствами этих объектов есть важное отличие в области арифметики указателей. Как мы знаем, индексация массива в Си сводится к суммированию базового указателя массива и индекса с последующей разадресацией: a[j] -- то же, что и *(a+j). Также все мы знаем, что обращение за границы массива -- это серьезная ошибка. Однако в языке Си ошибкой является не только операция *(a+j), но и a+j, если ее результат выходит за границы массива. Точнее, результат этой операции неопределен, что может означать любые неприятости, вплоть до упразднения языка Си и принудительного перехода на язык Паскаль. На практике эту ситуацию можно представить так: если массив находится близко к концу адресного пространства, вычисление указателя a+j при достаточно большом j может вызвать переполнение соответствующего аппаратного регистра и сбой программы.

Тем не менее, программисты на Си давно используют такую идиоматическую конструкцию:

int tab[100], *p;

for (p = tab; p < tab + sizeof(tab); p++) {
    ...
}

На выходе из такого цикла p примет значение tab+sizeof(tab) и укажет за последний элемент массива! Чтобы не ломать сложившуюся практику, авторы ANSI Си внесли поправку: указатель в пределах массива a[N] может принимать значения от a до a+N. Конечно, разадресовать значение указателя a+N при этом нельзя. Если мы снова представим себе платформу, где переполнение указателя приводит к сбою, то в ней последний элемент массива, a[N-1], не может занимать последнюю ячейку памяти в адресном пространстве.

Вернемся к нашему основному вопросу про i и a[0]. Выходит, что, согласно ANSI Си, указатель a+1 -- действительный, хотя и не отвечает доступной ячейке памяти. В то же время, указатель &i+1 будет недействительным и, возможно, приведет к сбою программы, например, если переменная i займет последнюю ячейку адресного пространства в нашей платформе.

Чтобы ликвидировать это расхождение, стандарт Си-99 явно говорит, что по своим арифметическим свойствам указатель на простую переменную эквивалентен указателю на первый элемент массива из одного элемента того же типа. В нашей платформе теперь и простая переменная не может занимать последнюю ячейку адресного пространства.

Как мы видим, в Си-99 простая переменная и массив из одного элемента стали полностью эквиваленты, но только благодаря дополнительным утверждениям стандарта. Не перемудрили ли его авторы? На самом деле, нет, потому что им приходится учитывать большое разнообразие платформ, на которых язык Си должен работать предсказуемо и в соответствии со стандартом.


Создано: Yar Tikhiy

Последнее обновление: Yar Tikhiy

   :: Новости ::

Сайт снова оживлен на новой площадке.

sem, 22.11.2008

Новый участник проекта - Сергей Матвейчук

glebius, 30.01.2005

Новый участник проекта - Владимир Савкин

glebius, 24.01.2004

Сайт переехал на новую площадку. Теперь услуги co-location предоставляются компанией Best Telecommunications, за что им огромное спасибо.

glebius, 05.09.2003

Новый участник проекта - Андрей Павлов

glebius, 29.07.2002

Сайт вернулся к жизни. Два месяца назад отказал жесткий диск, до этого работавший безотказно и не подавая никаких признаков скорой смерти. Тк я по жизни разгильдяй, то бэкапа не было. Однако нашлись добрые люди, которые подкинули свои мирроры и кэши, и как видите, мы снова живем. Огромное человеческое спасибо Константину Елапину, Дмитрию Тейблюму и Александру Дилевскому из Яндекса, а также vasilich@softhome.net и kx@usp.ru.
Новый дизайн сайта сделал Андрей Селиванов.

glebius, 20.07.2002

   :: Реклама ::
Дом, где используется напольная плитка, показан на рисунке.