Синтаксис функції C, типи параметрів, оголошені після списку параметрів


79

Я відносно новачок у C. Я натрапив на синтаксис функції, якого я ніколи раніше не бачив, де типи параметрів визначаються після цього списку параметрів. Хтось може пояснити мені, чим він відрізняється від типового синтаксису функції C?

Приклад:

Відповіді:


65

Це синтаксис старого стилю для списків параметрів, який досі підтримується. У K&R C ви також можете залишити оголошення про типи, і вони за замовчуванням будуть int. тобто

буде такою ж функцією.


17
І C89 / 90, і C99 все ще офіційно підтримують декларації стилю K&R. Однак у C99 усі параметри повинні бути явно оголошені (більше не існує правила "неявного int").
AnT

1
Я ненавиджу запізнюватися на вечірку (як через 4 роки?), Але ви хочете сказати, що в C99 їх потрібно чітко оголосити у списку параметрів або у функції ? Наприклад, правило int за замовчуванням - оскільки вони більше не мають значення int, то їх типи потрібно оголосити у функції перед використанням, якщо типи не були вказані у списку параметрів?
Chris Cirefice

1
@ChrisCirefice Щоб відповісти вам через 4 роки: у C99 усі параметри повинні бути оголошені у списку параметрів. Змінні, які оголошені у функції, ніколи не мали за замовчуванням int, і тому повинні бути оголошені явно.
Френк Кастерс

28

Що цікаво, так це різниця між умовами викликів функцій з та без прототипу. Розглянемо старе визначення стилю:

У цьому випадку умова виклику полягає в тому, що всі аргументи просуваються перед передачею функції (наприклад, floatаргумент спочатку підвищується до double, перед передачею). Отже, якщо fотримує а, doubleале параметр має тип float(що цілком дійсний), компілятор повинен видавати код, який перетворює подвійний у плаваючий перед виконанням тіла функції.

Якщо ви включите прототип, компілятор більше не робить таких автоматичних рекламних акцій, і будь-які передані дані перетворюються у типи параметрів прототипу, як за призначенням. Отже, наступне не є законним і спричиняє невизначену поведінку:

У цьому випадку визначення функції перетворить надісланий параметр із double(рекламованої форми) у, floatоскільки визначення є старим стилем. Але параметр подано як плаваючий, оскільки функція має прототип. Наприклад, дзвін дає

main.c: 3: 9: попередження: підвищений тип "подвійний" параметра функції K&R не сумісний з типом параметра "float", оголошеним у попередньому прототипі [-Wknr-promoted-parameter]

Варіанти вирішення суперечностей:

Варіант 2 слід віддавати перевагу, якщо у вас є вибір, оскільки він позбавляється від попереднього визначення старого стилю. Якщо такі суперечливі типи функцій для функції з'являються в одній і тій же одиниці перекладу, компілятор зазвичай повідомляє про це (але це не потрібно). Якщо подібні суперечності виникають у кількох одиницях перекладу, помилка, можливо, залишиться непоміченою і може призвести до важко передбачуваних помилок. Краще уникати цих визначень старого стилю.


10

Це той, хто телефонує декларація стилю K&R або старого стилю .

Зауважте, що ця декларація суттєво відрізняється від сучасної декларації. Декларація K&R не вводить прототип для функції, це означає, що вона не виставляє типи параметрів зовнішньому коду.


4

Ніякої різниці немає, це просто те, що це старий синтаксис для оголошень функцій в C - він використовувався до ANSI. Ніколи не пишіть такий код, якщо не плануєте передати його своїм друзям із 80-х . Крім того, ніколи не залежать від неявних припущень типу (як, схоже, пропонує інша відповідь)


Ну до C99; він використовувався до ANSI, який був стандартизований в 1989 році, але процес розпочався в 1983 році.
Брайан Кемпбелл,

2
Гм ... Декларації стилю K&R все ще офіційно підтримуються C99, лише з однією незначною зміною - більше немає "неявного int", всі параметри повинні бути явно оголошені.
AnT

Серед критики я повинен сказати, що я з вами згоден: не робіть цього.
BobbyShaftoe

4

Хоча старий синтаксис для визначення функції все ще працює (із попередженнями, якщо ви запитаєте свого компілятора), їх використання не надає прототипів функцій.
Без прототипів функцій компілятор не перевірить, чи правильно викликані функції.

Коли програма запущена, результат на моїй машині є


1

Це така ж, але стара мода. Ви, мабуть, виявили, що це якийсь старий, застарілий код.


0

Старий чи ні, я б сперечався, що є старим, а що нат .. як піраміди давні, але жоден із сучасних так званих вчених не здогадується, як вони там робили. Озираючись назад, старі програми все ще працюють і сьогодні без витоків пам'яті, але ці "нові" програми, як правило, виходять з ладу частіше. Тут я бачу тенденцію.

Можливо, вони розглядали функції як структури, що мають виконуваний корпус. Для розгадки таємниці тут потрібні знання АСМ.

Редагувати, знайшов макрос, який вказує, що вам зовсім не потрібно вводити імена аргументів.

Ось приклад використання, бібліотека - zlib-1.2.11 .

Отже, моє друге припущення стосується перевантаження функції, інакше ці аргументи не мали б ніякої користі. Одна конкретна функція, і тепер нескінченна кількість функцій з однойменною назвою.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.