Язык программирования C

       

Указатели - не целые


Вы, возможно, обратили внимание в предыдущих "с"-программах на довольно непринужденное отношение к копированию указателей. В общем это верно, что на большинстве машин указатель можно присвоить целому и передать его обратно, не изменив его; при этом не происходит никакого масштабирования или преобразования и ни один бит не теряется. к сожалению, это ведет к вольному обращению с функциями, возвращающими указатели, которые затем просто передаются другим функциям, - необходимые описания указателей часто опускаются. Рассмотрим, например, функцию strsave(s), которая копирует строку s в некоторое место для хранения, выделяемое посредством обращения к функции alloc, и возвращает указатель на это место. Правильно она должна быть записана так:

char *strsave(s) /* save string s somewhere */ char *s; { char *p, *alloc(); if ((p = alloc(strlen(s)+1)) != null) strcpy(p, s); return(p); }

на практике существует сильное стремление опускать описания:

*strsave(s) /* save string s somewhere */ { char *p;

if ((p = alloc(strlen(s)+1)) != null) strcpy(p, s); return(p); }

Эта программа будет правильно работать на многих машинах, потому что по умолчанию функции и аргументы имеют тип int, а указатель и целое обычно можно безопасно пересылать туда и обратно. Однако такой стиль программирования в своем существе является рискованным, поскольку зависит от деталей реализации и архитектуры машины и может привести к неправильным результатам на конкретном используемом вами компиляторе. Разумнее всюду использовать полные описания. (Отладочная программа lint предупредит о таких конструкциях, если они по неосторожности все же появятся).



Содержание раздела