Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Нужны ли прототипы функций 
:(
    Опции темы
Чупакабро
Дата 1.10.2012, 14:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 220
Регистрация: 27.2.2007

Репутация: нет
Всего: 4



В книге Г. Шилдта по С++ прочитал, что одним из отличий С++ от С является необходимость обязательного написания прототипов функций.
Однако MSVS 2010 хавает функцию без прототипа и даже не давится.
Кто здесь неправ?
--------------------
Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 00459B8B in module 'Project1.exe'. Read of address 0000019C'. Process stopped. Use Step or Run to continue.
PM MAIL   Вверх
baldina
Дата 1.10.2012, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



ты.
либо прототип есть (напрмер, в файле, который включается в stdafx.h)
либо компиляция происходит в режиме С

PM MAIL   Вверх
Чупакабро
Дата 1.10.2012, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 220
Регистрация: 27.2.2007

Репутация: нет
Всего: 4



Цитата(baldina @  1.10.2012,  14:24 Найти цитируемый пост)
либо прототип есть 

Нет. Функция моя.
Цитата(baldina @  1.10.2012,  14:24 Найти цитируемый пост)
либо компиляция происходит в режиме С

где это можно посмотреть?
--------------------
Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 00459B8B in module 'Project1.exe'. Read of address 0000019C'. Process stopped. Use Step or Run to continue.
PM MAIL   Вверх
baldina
Дата 1.10.2012, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



в настройках проекта

Добавлено через 29 секунд
покажи код, где нет прототипа
PM MAIL   Вверх
volatile
Дата 1.10.2012, 19:33 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 16
Всего: 85



Если тело функции находится выше по коду (включаяя инклуды), прототип не нужен.

Шилдт имелл ввиду прототипы функций-членов (методов класса).
Прототипы классов (и естественно прототипы функций входящих в нево) является обязательной необходимостью.

PM MAIL   Вверх
Чупакабро
Дата 1.10.2012, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 220
Регистрация: 27.2.2007

Репутация: нет
Всего: 4



Цитата(baldina @  1.10.2012,  18:05 Найти цитируемый пост)
покажи код, где нет прототипа 

Код

int kdfjgnj()
{
        return 0;
}

void sdvsddvsd()
{
    kdfjgnj();
}
Вот на это не ругается.


Цитата(volatile @  1.10.2012,  19:33 Найти цитируемый пост)
Шилдт имелл ввиду прототипы функций-членов (методов класса).Прототипы классов (и естественно прототипы функций входящих в нево) является обязательной необходимостью. 

Я тоже так думал, но этот товарисч написал, что это отличие С++ от С, а так как в С нет классов, то я и подумал, что речь идет про обычные функции.
--------------------
Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 00459B8B in module 'Project1.exe'. Read of address 0000019C'. Process stopped. Use Step or Run to continue.
PM MAIL   Вверх
NoviceF
Дата 2.10.2012, 00:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 13.3.2012
Где: Ростов-на-Дону

Репутация: 2
Всего: 2



Цитата(Чупакабро @  1.10.2012,  14:19 Найти цитируемый пост)
В книге Г. Шилдта по С++ прочитал, что одним из отличий С++ от С является необходимость обязательного написания прототипов функций.


У Шилдта "Прототип позволяет компилятору узнать тип значения, возвращаемого функцией, также количество и тип параметров, которые она может иметь. Компилятору нужно знать эту информацию до первого вызова функции".

Там ещё нужно смотреть примеры из книги, где у него определение функции написано после main(). В таком случае естественно, что сначала нужно объявление. А ситуация, когда вместе с объявлением(прототипом) сразу идёт определение, свойственна для inline функций.
PM MAIL   Вверх
Dem_max
Дата 2.10.2012, 04:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 4
Всего: 39



Цитата

Я тоже так думал, но этот товарисч написал, что это отличие С++ от С, а так как в С нет классов, то я и подумал, что речь идет про обычные функции.

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


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
baldina
Дата 2.10.2012, 10:08 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(Чупакабро @  1.10.2012,  20:22 Найти цитируемый пост)
int kdfjgnj()
{
        return 0;
}
void sdvsddvsd()
{
    kdfjgnj();
}

все идентификаторы C++ должны быть предварительно объявлены. прототипы функций нужны для их объявления, если сами они (их определение) находится в другой единице компиляции или ниже по тексту.
в данном случае функция kdfjgnj() определена и объявлена выше использования, она сама себе прототип.

PM MAIL   Вверх
xvr
Дата 2.10.2012, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(baldina @  2.10.2012,  10:08 Найти цитируемый пост)
в данном случае функция kdfjgnj() определена и объявлена выше использования, она сама себе прототип.

+1

Кстати, в С точно так же - объявление функции уже является ее прототипом (хотя и не всегда):
Код

int kdfjgnj(void)
{
        return 0;
}
 - является прототипом
Код

int kdfjgnj()
{
        return 0;
}
 - не является

PM MAIL   Вверх
wowka19
Дата 2.10.2012, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 30.11.2011

Репутация: нет
Всего: нет



Цитата(xvr @  2.10.2012,  12:42 Найти цитируемый пост)
Кстати, в С точно так же - объявление функции уже является ее прототипом (хотя и не всегда):

Код

int kdfjgnj(void)
{
        return 0;
}

 - является прототипом


Код

int kdfjgnj()
{
        return 0;
}

 - не является


можно вот это пояснить? не пойму чем отличаются эти две записи, разве void не подразумевается и не является чисто формальностю?

Это сообщение отредактировал(а) wowka19 - 2.10.2012, 15:16
PM MAIL   Вверх
xvr
Дата 2.10.2012, 15:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(wowka19 @  2.10.2012,  15:11 Найти цитируемый пост)
разве void не подразумевается и не является чисто формальностю?

В С++ да, в С - нет. Что бы описание функции (равно как и предварительное описание) было прототипом, в нем необходимо указать типы параметров, даже если их вообще нет. Вот тут void и пишут.

PM MAIL   Вверх
wowka19
Дата 2.10.2012, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 30.11.2011

Репутация: нет
Всего: нет



значит выше приведенное сравнение относится только к plain C?
Блин, нада почитать книжку Денниса Ритчи.
Вообще странный ход разработчиков языка C не последовать примеру C++. Все-таки по дефолту подразумевать void логично и удобно. Может это пережиток ANSI C и в C99 это работает?
PM MAIL   Вверх
xvr
Дата 2.10.2012, 21:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(wowka19 @  2.10.2012,  16:27 Найти цитируемый пост)
значит выше приведенное сравнение относится только к plain C?

Да

Цитата(wowka19 @  2.10.2012,  16:27 Найти цитируемый пост)
Вообще странный ход разработчиков языка C не последовать примеру C++.

С вроде как бы раньше появился smile

Цитата(wowka19 @  2.10.2012,  16:27 Найти цитируемый пост)
Может это пережиток ANSI C и в C99 это работает? 

Это пережиток еще перехода от K&R к ANSI C. Не уверен, что в С99 это изменили - пострадает совместимость и масса старых программ перестанет компилироваться

PM MAIL   Вверх
wowka19
Дата 3.10.2012, 12:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 30.11.2011

Репутация: нет
Всего: нет



Цитата(xvr @  2.10.2012,  21:17 Найти цитируемый пост)
Цитата(wowka19 @  2.10.2012,  16:27 )
Вообще странный ход разработчиков языка C не последовать примеру C++.

С вроде как бы раньше появился 


Я имел ввиду исправления в последующих стандартах, появившихся после C++ (аналогично //)



Цитата(xvr @  2.10.2012,  21:17 Найти цитируемый пост)

Цитата(wowka19 @  2.10.2012,  16:27 )
Может это пережиток ANSI C и в C99 это работает? 

Это пережиток еще перехода от K&R к ANSI C. Не уверен, что в С99 это изменили - пострадает совместимость и масса старых программ перестанет компилироваться


Почему же совместимость пострадает при установлении void по дефолту?

PM MAIL   Вверх
math64
Дата 3.10.2012, 13:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Комментарий // появился в C до того, как появился C++ (но может быть, не был включен в стандарт)
f() в C означает, что функция может иметь любые аргументы
в С++ это означает, что функция не имеет аргументов.
typedef void func(); - не переводимо на C++, у typedef void func(...); - немного другой смысл.
PM   Вверх
xvr
Дата 3.10.2012, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(wowka19 @  3.10.2012,  12:27 Найти цитируемый пост)
Почему же совместимость пострадает при установлении void по дефолту?

Потому что нельзя будет сделать функцию без прототипа, а в до-ANSI программах все функции были без прототипа. Так что все старые С библиотеки перестанут собираться.

PM MAIL   Вверх
wowka19
Дата 4.10.2012, 20:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 30.11.2011

Репутация: нет
Всего: нет



Цитата(xvr @  3.10.2012,  14:40 Найти цитируемый пост)
Потому что нельзя будет сделать функцию без прототипа, а в до-ANSI программах все функции были без прототипа. Так что все старые С библиотеки перестанут собираться.


не понял... можно пример
PM MAIL   Вверх
math64
Дата 5.10.2012, 07:27 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Код

typedef int func();
struct  A {
int i;
func* pfunc;
};
int f1() { return 0; }
int f2(int n) { return n; }

int main() {
struct A a1, a2;
a1.pfunc = f1;
a2.pfunc  = f2;
a1.i = a1.pfunc();
a2.i = a2.pfunc(a1.i);
return a2.i;
}


Это сообщение отредактировал(а) math64 - 5.10.2012, 07:30
PM   Вверх
xvr
Дата 5.10.2012, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(wowka19 @  4.10.2012,  20:59 Найти цитируемый пост)
не понял... можно пример 

Код

int func(); /* Это предварительное описание, НО НЕ ПРОТОТИП ! */

main()
{
  func(10);
}

int func(int a)
{
 ...
}
Абсолютно правильный код в ANSI C (да и в K&R тоже, если вынести описание типа параметра за скобки). Если не требовать наличие void при описании прототипа - это будет ошибкой. 99.9% всех С библиотек, созданных во времена K&R C перестанут собираться

PM MAIL   Вверх
wowka19
Дата 5.10.2012, 20:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 30.11.2011

Репутация: нет
Всего: нет



Цитата(xvr @  5.10.2012,  10:43 Найти цитируемый пост)
Код

int func(); /* Это предварительное описание, НО НЕ ПРОТОТИП ! */
main()
{
  func(10);
}
int func(int a)
{
 ...
}



так... получается, чтоб компилятор не поперхнулся, дойдя до неизвестной func(10) в main(), достаточно просто указать тип return'а + имя функции БЕЗ параметров (НЕ ПРОТОТИП)?

тогда в чем смысл прототипа? зачем вообще нужен прототип если компилятору хватит и имени?
например:
Код

int func(int); // не соберется?

main()
{
  func(10);
}
int func(int a)
{
 ...
}

PM MAIL   Вверх
mes
Дата 6.10.2012, 01:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(wowka19 @  5.10.2012,  19:52 Найти цитируемый пост)
 достаточно просто указать 

достаточно было

Цитата(wowka19 @  5.10.2012,  19:52 Найти цитируемый пост)
 зачем вообще нужен прототип 

для контроля соответствия типов и возможных перобразований..


--------------------
PM MAIL WWW   Вверх
xvr
Дата 6.10.2012, 18:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(wowka19 @  5.10.2012,  20:52 Найти цитируемый пост)
тогда в чем смысл прототипа? зачем вообще нужен прототип если компилятору хватит и имени?

В K&R прототипов не было. Там даже необязательно было давать предварительное описание функции, т.е. можно было сделать
Код

int main()
{
 return func(10);
}
Но потом, когда вдоволь находились по граблям с несоответствием типов параметров и вызова, ввели прототипы:
Код

int main()
{
 func(10); // Будет вызов с целым числом в качестве параметра, и как следствие - слом в процессе исполнения
}

void func(a)
 double a;
{
 ...
}

Если добавить прототип, все становится правильно
Код

void func(double);
int main()
{
 func(10); // Целое 10 будет преобразовано в double 10.0, и с ним и будет произведен вызов
}

void func(double a)
{
 ...
}


PM MAIL   Вверх
wowka19
Дата 10.10.2012, 02:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 30.11.2011

Репутация: нет
Всего: нет



Цитата(xvr @  6.10.2012,  18:23 Найти цитируемый пост)
Код

void func(a)
 double a;
{
 ...
}

- это что за синтаксис такой?
PM MAIL   Вверх
baldina
Дата 10.10.2012, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(wowka19 @ 10.10.2012,  02:34)
Цитата(xvr @  6.10.2012,  18:23 Найти цитируемый пост)
Код

void func(a)
 double a;
{
 ...
}

- это что за синтаксис такой?

устаревший K&R style
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

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


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0821 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.