| Определение
функцииФункция определяется описанием
типа результата, формальных параметров и
составного оператора (блока), описывающего
выполняемые функцией действия.
Пример double тип результата linfunc (х, а, Ь) имя функции список параметров double x; описание параметров double a; double b; { составной оператор return (a*x + b); возвращаемое значение Оператор return может не возвращать никакого значения или возвращает значение выражения, стоящего в этом операторе. Значение выражения при необходимости преобразуется к типу результата функции. Функция, которая не возвращает значения, должна быть описана как имеющая тип void.Пример void ermesg(s)char * s; printf("***%s\n", s); } |
| Существуют
два способа вызова функции: имя_функцш (е1, е2,. .., eN) (указатель _на_функцию) (е1, е2,..., eN) Указатель _на_функцию - это переменная, содержащая адрес функции. Адрес функции может быть присвоен указателю оператором указатель_на_функцию = имя _функции; Аргументы (фактические параметры) передаются по значению, т. е. каждое выражение el, . . . , eN вычисляется и значение передается функции, например, загрузкой в стек. Порядок вычисления выражений и порядок загрузки значений в стек не гарантируются. Во время выполнения не производится проверка числа или типа аргументов, переданных функции. Такую проверку можно произвести с помощью программы lint до компиляции (см. с. 78). Вызов функции - это выражение, значением которого является значение, возвращаемое функцией. Описанный тип функции должен соответствовать типу возвращаемого значения. Например, если функция linfunc возвращает значение типа double, то эта функция должна быть описана до вызова: extern double ' linfunc(); Замечание. Такое описание не определяет функцию, а только описывает тип возвращаемого значения; оно не нужно, если функция определена в том же файле до ее вызова (см. с. 42). Примеры Правильно: extern double linfuncO; float у; у = linfunc (3.05, 4.0, le-3), Значение функции перед присваиванием переменной у преобразуется из типа double в тип float. Неправильно: float х; float у; х=3.05; у = linfunc (х, 4, le-3); Тип аргументов не соответствует типу параметров, описанных в определении функции, а именно: константа 4 имеет тип int, а не double. В результате аргументы, загруженные в стек, имеют неправильные тип и формат, поэтому значения, выбираемые из стека, бессмысленны и значение, возвращаемое функцией, не определено. Кроме того, если тип функции не описан, то считается, что возвращаемое значение имеет тип int. Поэтому, даже если функция linfunc возвращает правильное значение типа double, выражение, представляющее вызов функции, получит бессмысленное значение типа int (например, старшая половина значения double). |
| Каждая
программа начинает работу с функции main(). Во время
выполнения программы можно передавать аргументы
через формальные параметры argc и argv функции main.
Переменные среды языка оболочки shell передаются
программе через параметр env. Пример /* программа печатает значения фактических параметров, * а затем переменных среды */main (argc, aigv, envp) int argc; /* число параметров*/ char **argv, /* вектор параметров-строк */ char *envp; /* вектор переменных среды */{ register int i; register char **p; /* печать значений параметров */ for (i = 0, i < argc, i++) printf("arg %i:%s\n", i, argv [i]); /* печать значений переменных среды */ for (p = envp; *p != (char*)0; p++) printf ("%s\n", *p); Замечание. Параметры argv и envp могут быть описаны также следующим образом:char *argv[]; char *envp[]; |
| Описания используются для определения переменных и для объявления типов переменных и функций, определенных в другом месте. Описания также используются для определения новых типов данных на основе существующих типов. Описание не является оператором. |
| Примеры
char с, int х; Основными типами являются: char - символ (один байт) ; int - целое (обычно одно слово); unsigned - неотрицательное целое (такого же размера, как целое); short - короткое целое (слово или полуслово); long — длинное целое (слово или двойное слово); float - число с плавающей точкой (ординарной точности); double - число с плавающей точкой (двойной точности); void — отсутствие значения (используется для нейтрализации значения, возвращаемого функцией). Символы (char) в зависимости от компилятора могут быть со знаком или без знака. Рассматриваемые как целые, символы со знаком имеют значения от -127 до 128, а символы без знака - от 0 до 256. Некоторые реализации допускают явный тип unsigned char. Данные целого типа int могут иметь такой же диапазон, как данные типа long иди short. Описание типа unsigned эквивалентно описанию типа unsigned int. Описание unsigned может сочетаться с описанием типа char, short или long, формируя описания типов unsigned char, unsigned short, unsigned long. Описания типов short и long эквивалентны описаниям типов short int и long mt. Диапазон данных типа long обычно в два раза больше диапазона данных типа short. |