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

на главную

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

Вы можете попросить включить проверку аргументов функций в языке С. Для этого достаточно объявить функцию с заданными типами аргументов (точно так же, как в языке С++). Такое объявление называется прототипом функции (function prototype). Тем не менее следует избегать объявлений, не задающих аргументы; они не являются прототипами функций и не включают механизм проверки типов.

int g(double); /* прототип — как в языке С ++ */

int h; /* не прототип — типы аргументов не указаны */

void my_fct

{

g; /*
ошибка: пропущен аргумент */

g("asdf"); /* ошибка: неправильный тип аргумента */

g(2); /* OK: 2 преобразуется в 2.0 */

g(2,3); /* ошибка: один аргумент лишний */

h; /* Компилятор допускает! Результат непредсказуем */

h("asdf"); /* Компилятор допускает! Результат непредсказуем */

h(2); /* Компилятор допускает! Результат непредсказуем */

h(2,3); /* Компилятор допускает! Результат непредсказуем */

}

В объявлении функции
h
не указан тип аргумента. Это не означает, что функция
h
не получает ни одного аргумента; это значит: принимает любой набор аргументов и надеется, что это набор при вызове окажется правильным. И снова отметим, что хороший компилятор предупредит об этой проблеме, а программа
lint
перехватит ее.

Существует специальный набор правил, регламентирующих преобразование аргументов, если в области видимости нет прототипа функции. Например, переменные типов

char
и
short
преобразуются в переменные типа
int
, а переменные типа
float
в переменные типа
double
. Если вы хотите знать, скажем, что произойдет с переменной типа
long
, загляните в хороший учебник по языку С. Наша рекомендация проста: не вызывайте функций, не имеющих прототипов.

Обратите внимание на то, что, хотя компилятор допускает передачу аргументов неправильного типа, например параметр типа

char*
вместо параметра типа int, использование таких аргументов приводит к ошибкам. Как сказал Деннис Ритчи: “С — это язык программирования со строгим контролем типов и слабой проверкой”.

27.2.3. Определения функций

Можете определять функции точно так же, как в языке С++. Эти определения являются прототипами функций.

double square(double d)

{

return d*d;

}

void ff

{

double x = square(2); /* OK: переводим 2 в 2.0 и вызываем */

double y = square; /* пропущен аргумент */

double y = square("Hello"); /* ошибка: неправильный тип

аргументов */

double y = square(2,3); /*
ошибка: слишком много аргументов */

}

Определение функции без аргументов не является прототипом функции.

void f { /* что-то делает */ }

void g

{

f(2); /* OK в языке C; ошибка в языке C++ */

}

Код

void f; /* не указан тип аргумента */

означающий, что функция

f
может принять любое количество аргументов любого типа, выглядит действительно странно. В ответ на это я изобрел новое обозначение, в котором понятие “ничего” указывалось явным образом с помощью ключевого слова
void
(void — слово из четырех букв, означающее “ничего”).

void f(void); /* не принимает никаких аргументов */

Впрочем, вскоре я об этом пожалел, потому что эта конструкция выглядит странно и при последовательной проверке типов аргументов является излишней. Что еще хуже, Деннис Ритчи (автор языка C) и Дуг Мак-Илрой (Doug McIlroy) (законодатель мод в Исследовательском центре компьютерных наук в компании Bell Labs (Bell Labs Computer Science Research Center; см. раздел 22.2.5) назвали это решение “отвратительным”. К сожалению, оно стало очень популярным среди программистов, работающих на языке С. Тем не менее не используйте его в программах на языке С++, в которых оно выглядит не только уродливо, но и является совершенно излишним.

В языке C есть альтернативное определение функции в стиле языка Algol-60, в котором типы параметров (не обязательно) указываются отдельно от их имен.

int old_style(p,b,x) char* p; char b;

{

/* ... */

}

Это определение “в старом стиле” предвосхищает конструкции языка С++ и не является прототипом. По умолчанию аргумент без объявленного типа считается аргументов типа
int
. Итак, параметр
x
является аргументом функции
old_style
, имеющим тип
int
. Мы можем вызвать функцию
old_style
следующим образом:

old_style; /* OK: пропущены все аргументы */

old_style("hello",'a',17); /* OK: все аргументы имеют правильный тип */

old_style(12,13,14); /* OK: 12 — неправильный тип */

/* но old_style может не использовать p */

Компилятор должен пропустить эти вызовы (но мы надеемся, что он предупредит о первом и третьем аргументах).

Мы рекомендуем придерживаться следующих правил проверки типов аргументов функций.

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

Неудержимый. Книга XVII

Боярский Андрей
17. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XVII

Энфис 3

Кронос Александр
3. Эрра
Фантастика:
героическая фантастика
рпг
аниме
5.00
рейтинг книги
Энфис 3

Кодекс Охотника. Книга X

Винокуров Юрий
10. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
6.25
рейтинг книги
Кодекс Охотника. Книга X

Генерал Империи

Ланцов Михаил Алексеевич
4. Безумный Макс
Фантастика:
альтернативная история
5.62
рейтинг книги
Генерал Империи

Жена по ошибке

Ардова Алиса
Любовные романы:
любовно-фантастические романы
7.71
рейтинг книги
Жена по ошибке

Брак по-драконьи

Ардова Алиса
Фантастика:
фэнтези
8.60
рейтинг книги
Брак по-драконьи

Авиатор: назад в СССР

Дорин Михаил
1. Авиатор
Фантастика:
попаданцы
альтернативная история
5.25
рейтинг книги
Авиатор: назад в СССР

Кодекс Охотника. Книга XXI

Винокуров Юрий
21. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XXI

Камень. Книга шестая

Минин Станислав
6. Камень
Фантастика:
боевая фантастика
7.64
рейтинг книги
Камень. Книга шестая

Неудержимый. Книга X

Боярский Андрей
10. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга X

Воин

Бубела Олег Николаевич
2. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.25
рейтинг книги
Воин

Менталист. Эмансипация

Еслер Андрей
1. Выиграть у времени
Фантастика:
альтернативная история
7.52
рейтинг книги
Менталист. Эмансипация

Делегат

Астахов Евгений Евгеньевич
6. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Делегат

Кодекс Охотника. Книга XXVI

Винокуров Юрий
26. Кодекс Охотника
Фантастика:
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXVI