Чтение онлайн

на главную

Жанры

Язык программирования Си для персонального компьютера

Субботин Д. М.

Шрифт:

Идентификаторы формальных параметров не могут совпадать с идентификаторами переменных, объявляемых внутри тела функции, но возможно локальное переобъявление формальных параметров внутри вложенных блоков функции.

В объявлениях формальных параметров не может быть объявлен никакой другой идентификатор, кроме перечисленных в списке параметров. Если функция имеет переменное число параметров, то программист отвечает и за определение их числа при вызове, и за получение их из стека внутри тела функции.

Тип каждого формального параметра должен соответствовать типу фактического аргумента и типу соответствующего аргумента

в списке типов аргументов функции, если имеется предварительное объявление функции со списком типов аргументов. Компилятор выполняет преобразования по умолчанию отдельно над типом каждого формального параметра и над типом каждого фактического аргумента.

После преобразования все формальные параметры имеют тип размером не меньше, чем int, и ни один из формальных параметров не имеет тип float. Это означает, например, что объявление формального параметра с типом char эквивалентно его объявлению с типом int, а объявление с типом float эквивалентно объявлению с типом double.

Если используются модификаторы near, far, huge, то компилятор также может неявно провести преобразование аргументов-указателей. Метод преобразования в этом случае зависит от размера указателей в выбранной модели памяти и от наличия или отсутствия списка типов аргументов функции.

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

Пример:

struct student {

char name [20];

int id;

long class;

struct student *nextstu;

} student;

main(void)

{

int match(struct student *, char *);

.

.

.

if(match (student.nextstu, student.name) > 0) {

.

.

.

}

}

match (struct student *r, char *n)

{

int i = 0;

while(r->name[i] == n[i])

if(r->name[i++] == '\0')

return(r->id);

return (0);

}

В примере содержатся: объявление структурного типа student, определение главной функции, содержащей предварительное объявление функции match и ее вызов, и определение функции match. Обратите внимание на то, что одно и то же имя student используется без противоречия для тега структуры и имени структурной переменной.

Функция match объявлена с двумя аргументами. Первый аргумент — указатель на структуру типа student, второй — указатель на значение типа char.

В определении функции match заданы два формальных параметра, r и n. Параметр r объявлен

как указатель на структуру типа student. Параметр n объявлен как указатель на значение типа char. По умолчанию, для функции match подразумевается тип возвращаемого значения int.

Функция match вызывается с двумя аргументами. Оба аргумента являются элементами переменной структурного типа student с именем student.

Поскольку имеется предварительное объявление функции match, компилятор проверит соответствие типов фактических аргументов в операторе ее вызова списку типов аргументов, а затем соответствие типов фактических аргументов типам формальных параметров. В данном случае несоответствия типов нет и в преобразованиях нет необходимости.

Обратите внимание на то, что имя массива, заданное в качестве второго аргумента в вызове функции, преобразуется по умолчанию к указателю на char. В функцию передается не сам массив, а адрес начала массива. Соответствующий формальный параметр также объявлен как указатель на char, а мог бы быть объявлен и как char n[], поскольку в выражении используется как идентификатор массива. Идентификатор массива рассматривается в выражении как адресное выражение, поэтому объявление формального параметра char *n; эквивалентно объявлению char n[];.

Внутри функции объявляется локальная переменная i, используемая в качестве индекса массива. Функция возвращает структурный элемент id, если структурный элемент name совпал с содержимым массива n; в противном случае функция возвращает нулевое значение.

Тело функции

Тело функции представляет собой составной оператор, или блок. Он содержит операторы, которые определяют действие функции, и объявления переменных, используемых в этих операторах. Составной оператор описан в разделе 5.3.

Все переменные, объявленные в теле функции, имеют по умолчанию класс памяти auto, но можно явно присвоить им другой класс памяти. При вызове функции выделяется память для ее локальных переменных и, если указано, производится их инициализация. Управление передается первому оператору составного оператора. Выполнение продолжается до тех пор, пока не встретится оператор return или конец тела функции (составного оператора). Управление возвращается в точку вызова функции.

Если функция возвращает значение, то должен быть выполнен оператор return, содержащий выражение. Если оператор return не выполнен, или если в операторе return отсутствует выражение, то возвращаемое значение не определено.

Объявление функции

Объявление функции определяет ее имя, тип возвращаемого значения, класс памяти и может также задавать тип некоторых или всех аргументов функции. Детальное описание синтаксиса объявлений функции дано в разделе 3.5. В разделе 3.6 рассмотрена зависимость области действия функции от ее класса памяти.

Поделиться:
Популярные книги

Мир-о-творец

Ланцов Михаил Алексеевич
8. Помещик
Фантастика:
альтернативная история
5.00
рейтинг книги
Мир-о-творец

Виконт. Книга 4. Колонист

Юллем Евгений
Псевдоним `Испанец`
Фантастика:
фэнтези
попаданцы
аниме
7.50
рейтинг книги
Виконт. Книга 4. Колонист

Титан империи

Артемов Александр Александрович
1. Титан Империи
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Титан империи

Запретный Мир

Каменистый Артем
1. Запретный Мир
Фантастика:
фэнтези
героическая фантастика
8.94
рейтинг книги
Запретный Мир

Ты предал нашу семью

Рей Полина
2. Предатели
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Ты предал нашу семью

Цеховик. Книга 2. Движение к цели

Ромов Дмитрий
2. Цеховик
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Цеховик. Книга 2. Движение к цели

Сила рода. Том 3

Вяч Павел
2. Претендент
Фантастика:
фэнтези
боевая фантастика
6.17
рейтинг книги
Сила рода. Том 3

Проданная невеста

Wolf Lita
Любовные романы:
любовно-фантастические романы
5.80
рейтинг книги
Проданная невеста

Волк 7: Лихие 90-е

Киров Никита
7. Волков
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Волк 7: Лихие 90-е

Падение Твердыни

Распопов Дмитрий Викторович
6. Венецианский купец
Фантастика:
попаданцы
альтернативная история
5.33
рейтинг книги
Падение Твердыни

Приручитель женщин-монстров. Том 9

Дорничев Дмитрий
9. Покемоны? Какие покемоны?
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Приручитель женщин-монстров. Том 9

Ночь со зверем

Владимирова Анна
3. Оборотни-медведи
Любовные романы:
любовно-фантастические романы
5.25
рейтинг книги
Ночь со зверем

Я – Орк. Том 6

Лисицин Евгений
6. Я — Орк
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я – Орк. Том 6

Совок-8

Агарев Вадим
8. Совок
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Совок-8