Вопрос: Как "получить" нулевой указатель в программе? Ответ: В языке С константа 0, когда она распознается как указатель, преобразуется компилятором в нулевой указатель. То есть, если во время инициализации, присваивания или сравнения с одной стороны стоит переменная или выражение, имеющее тип указателя, компилятор решает, что константа 0 с другой стороны должна превратиться в нулевой указатель и генерирует нулевой указатель нужного типа. Следовательно, следующий фрагмент абсолютно корректен:
Однако, аргумент, передаваемый функции, не обязательно будет распознан как значение указателя, и компилятор может оказаться не способным распознать голый 0 как нулевой указатель. Например, системный вызов UNIX "execl" использует в качестве параметров переменное количество указателей на аргументы, завершаемое нулевым указателем. Чтобы получить нулевой указатель при вызове функции, обычно необходимо явное приведение типов, чтобы 0 воспринимался как нулевой указатель.
Если не делать преобразования (char *), компилятор не поймет, что необходимо передать нулевой указатель и вместо этого передаст число 0. (Заметьте, что многие руководства по UNIX неправильно объясняют этот пример.) Когда прототипы функций находятся в области видимости, передача аргументов идет в соответствии с прототипом и большинство приведений типов может быть опущено, так как прототип указывает компилятору, что необходим указатель определенного типа, давая возможность правильно преобразовать нули в указатели. Прототипы функций не могут, однако, обеспечить правильное преобразование типов в случае, когда функция имеет список аргументов переменной длины, так что для таких аргументов необходимы явные преобразования типов. Всегда безопаснее явные преобразования в нулевой указатель, — чтобы не наткнуться на функцию с переменным числом аргументов или на функцию без прототипа, — чтобы временно использовать не-ANSI компиляторы, — чтобы продемонстрировать, что Вы знаете, что делаете. (Кстати, самое простое правило для запоминания.) Итог:
Смотри: K&R I Разд. A7.7 c. 190, Разд. A7.14 c. 192; K&R II Разд. A7.10 c. 207, Разд. A7.17 c. 209; H&S Разд. 4.6.3 c. 72; ANSI Разд. 3.2.2.3 . |