Решено: Функции в C (Ещё вопрос...)

Модератор: Модераторы разделов

_Gleb_
Сообщения: 467
ОС: Kubuntu 12.04 LTS

Решено: Функции в C

Сообщение _Gleb_ »

Ещё вопрос: у Кернигана и Ритчи приводятся такие примеры, как надо пользоваться функциями:

Код: Выделить всё

int my_function(int m, int n)

main() {
  /*Чего-то там....*/
}

int my_function(int var1, int var2) {
  /*Сама_функция*/
  return l;
}

Я не понял: зачем объявлять функцию сразу в двух местах и при том с разными именами аргументов? Это необходимо, или просто так принято? Какой в этом смысл? Или когда сначала пишется, что один из аргументов -- заранее определённая константа, а потом, что этот же аргумент -- переменная такого-то типа. К. и Р. пишут (если я правильно их понял), что первый раз -- это просто так, программе всё равно, что там сказано, но так надо, а вот потом и надо написать, что положено. Это зачем так?
В общем, совсем запутался...
Изображение
Спасибо сказали:
Аватара пользователя
Voice
Сообщения: 1073
Статус: столлманист
ОС: Debian GNU/Linux

Re: Решено: Функции в C

Сообщение Voice »

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

Зачем прототипы? В современных компиляторах они не обязательны, а раньше видно были обязательными и служили для облегчения работы компиляторов.

Это как в Паскале, функцию нужно объявить до ее вызова, а тут прототипы это решали.
"И может собственных Платонов и быстрых разумом Невтонов российская земля рождать."
М. В. Ломоносов
Спасибо сказали:
Аватара пользователя
Uncle_Theodore
Сообщения: 3339
ОС: Slackware 12.2, ArchLinux 64

Re: Решено: Функции в C

Сообщение Uncle_Theodore »

_Gleb_ писал(а):
28.07.2007 18:53
Ещё вопрос: у Кернигана и Ритчи приводятся такие примеры, как надо пользоваться функциями:

Код: Выделить всё

int my_function(int m, int n)

main() {
  /*Чего-то там....*/
}

int my_function(int var1, int var2) {
  /*Сама_функция*/
  return l;
}

Я не понял: зачем объявлять функцию сразу в двух местах и при том с разными именами аргументов? Это необходимо, или просто так принято? Какой в этом смысл? Или когда сначала пишется, что один из аргументов -- заранее определённая константа, а потом, что этот же аргумент -- переменная такого-то типа. К. и Р. пишут (если я правильно их понял), что первый раз -- это просто так, программе всё равно, что там сказано, но так надо, а вот потом и надо написать, что положено. Это зачем так?
В общем, совсем запутался...

Нет, функция объявляется перед main()'ом, аналогично объявлению переменной, чтобы потом ее можно было вызывать в main()'е, и компилятор понимал, что имеется в виду. А саму функцию поместить после main()'а. Типа, приучаться к структурированному программиолванию. :) Но при объявлении функции достаточно просто указать тип аргумента, указывать переменную не надо.

Код: Выделить всё

#include<stdio.h>

void privet(int, int);

int main()
{
  int n, m;
  scanf("%d", &n);
  scanf("%d", &m);

  privet(n,m);

  return 0;
}

void privet(int nn, int mm)
{
  printf("%d Privetov marnyshke i %d privetov sloniku\n", nn, mm);
}


А можно сразу написать тело функции перед main()'ом

Код: Выделить всё

#include<stdio.h>

void privet(int nn, int mm)
{
  printf("%d Privetov marnyshke i %d privetov sloniku\n", nn, mm);
}

int main()
{
  int n, m;
  scanf("%d", &n);
  scanf("%d", &m);

  privet(n,m);

  return 0;
}
Спасибо сказали:
_Gleb_
Сообщения: 467
ОС: Kubuntu 12.04 LTS

Re: Решено: Функции в C

Сообщение _Gleb_ »

Uncle_Theodore писал(а):
28.07.2007 19:05
А можно сразу написать тело функции перед main()'ом

Код: Выделить всё

#include<stdio.h>

void privet(int nn, int mm)
{
  printf("%d Privetov marnyshke i %d privetov sloniku\n", nn, mm);
}

int main()
{
  int n, m;
  scanf("%d", &n);
  scanf("%d", &m);

  privet(n,m);

  return 0;
}

А! Ну, если так можно, то мне только этого и надо. Спасибо!
Изображение
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Решено: Функции в C

Сообщение v04bvs »

_Gleb_ писал(а):
28.07.2007 18:53
Я не понял: зачем объявлять функцию сразу в двух местах и при том с разными именами аргументов?

Сверху функция объявляется, чтобы компилятор знал, что это имя обозначает функцию (объявленную ниже, или вообще в другом модуле), а также мог проверить типы аргументов при её вызове. То, что у аргументов разные имена, стандарту не противоречит, но вносит путаницу.
Кстати, именно на этом факте основана вся модульность в C.

Или когда сначала пишется, что один из аргументов -- заранее определённая константа, а потом, что этот же аргумент -- переменная такого-то типа. К. и Р. пишут (если я правильно их понял), что первый раз -- это просто так, программе всё равно, что там сказано, но так надо, а вот потом и надо написать, что положено. Это зачем так?
В общем, совсем запутался...

Я тоже запутался. Пример можно?
Спасибо сказали:
_Gleb_
Сообщения: 467
ОС: Kubuntu 12.04 LTS

Re: Решено: Функции в C

Сообщение _Gleb_ »

v04bvs писал(а):
28.07.2007 20:06
Сверху функция объявляется, чтобы компилятор знал, что это имя обозначает функцию (объявленную ниже, или вообще в другом модуле), а также мог проверить типы аргументов при её вызове. То, что у аргументов разные имена, стандарту не противоречит, но вносит путаницу.
Кстати, именно на этом факте основана вся модульность в C.

Ясно

Я тоже запутался. Пример можно?

Про константу? Ну, например, в моём издании К. и Р. стр. 46-47:
(с пропусками)

Код: Выделить всё

...
#define MAXLINE 1000

int getline(char line[], int MAXLINE);
...
main()
{
...
}
...
int getline(char s[], int lim)
{
...
}
Изображение
Спасибо сказали:
Аватара пользователя
Uncle_Theodore
Сообщения: 3339
ОС: Slackware 12.2, ArchLinux 64

Re: Решено: Функции в C

Сообщение Uncle_Theodore »

_Gleb_ писал(а):
28.07.2007 20:34
Я тоже запутался. Пример можно?

Про константу? Ну, например, в моём издании К. и Р. стр. 46-47:
(с пропусками)

Код: Выделить всё

...
#define MAXLINE 1000

int getline(char line[], int MAXLINE);
...
main()
{
...
}
...
int getline(char s[], int lim)
{
...
}


Информация к размышлению. :)
#define -- это не константа. Константа -- это const
И еще раз. То, что написано в качестве имени аргумента в объявлении функции, не имеет никакого значения. Имеют значения только типы аргументов.


Маленький пример на тему того, что такое #define

Код: Выделить всё

#define nu_poehali main
#define verni_emu return
#define niherasebe void

#include<stdio.h>

niherasebe privet(int nn, int mm)
{
  printf("%d Privetov marnyshke i %d privetov sloniku\n", nn, mm);
}

int nu_poehali()
{
  int n, m;
  scanf("%d", &n);
  scanf("%d", &m);

  privet(n,m);

  verni_emu 0;
}
Спасибо сказали:
_Gleb_
Сообщения: 467
ОС: Kubuntu 12.04 LTS

Re: Решено: Функции в C

Сообщение _Gleb_ »

Uncle_Theodore писал(а):
28.07.2007 20:40
Информация к размышлению. :)
#define -- это не константа. Константа -- это const

Ну хорошо, именованная константа.
И еще раз. То, что написано в качестве имени аргумента в объявлении функции, не имеет никакого значения. Имеют значения только типы аргументов.

Т.е. про проверку типов компилятором -- это не так?
Изображение
Спасибо сказали:
Аватара пользователя
Uncle_Theodore
Сообщения: 3339
ОС: Slackware 12.2, ArchLinux 64

Re: Решено: Функции в C

Сообщение Uncle_Theodore »

_Gleb_ писал(а):
28.07.2007 20:52
Uncle_Theodore писал(а):
28.07.2007 20:40
Информация к размышлению. :)
#define -- это не константа. Константа -- это const

Ну хорошо, именованная константа.

НЕ хорошо. НЕ именованная константа, а директива препроцессору. С точки зрения компилятора, в тексте программы уже подставлены все дефайны. Смотри пример выше. :)
И еще раз. То, что написано в качестве имени аргумента в объявлении функции, не имеет никакого значения. Имеют значения только типы аргументов.

Т.е. про проверку типов компилятором -- это не так?

Не понял вопроса.
Спасибо сказали:
_Gleb_
Сообщения: 467
ОС: Kubuntu 12.04 LTS

Re: Решено: Функции в C

Сообщение _Gleb_ »

Uncle_Theodore писал(а):
28.07.2007 20:40
Маленький пример на тему того, что такое #define

А, ясно.
Изображение
Спасибо сказали:
_Gleb_
Сообщения: 467
ОС: Kubuntu 12.04 LTS

Re: Решено: Функции в C

Сообщение _Gleb_ »

Uncle_Theodore писал(а):
28.07.2007 20:56
НЕ хорошо. НЕ именованная константа, а директива препроцессору. С точки зрения компилятора, в тексте программы уже подставлены все дефайны.

Но тогда получается, что

Код: Выделить всё

#define MAXLINE 1000
int MAXLINE

то же самое, что:

Код: Выделить всё

int 1000

Что смотрится ещё более странно.
Изображение
Спасибо сказали:
Аватара пользователя
Uncle_Theodore
Сообщения: 3339
ОС: Slackware 12.2, ArchLinux 64

Re: Решено: Функции в C

Сообщение Uncle_Theodore »

_Gleb_ писал(а):
28.07.2007 21:04
Uncle_Theodore писал(а):
28.07.2007 20:56
НЕ хорошо. НЕ именованная константа, а директива препроцессору. С точки зрения компилятора, в тексте программы уже подставлены все дефайны.

Но тогда получается, что

Код: Выделить всё

#define MAXLINE 1000
int MAXLINE

то же самое, что:

Код: Выделить всё

int 1000

Что смотрится ещё более странно.

Таки да, но ты посмотри, где оно написано. В имени аргумента в декларации функции. То есть именно в том месте, где что ни напиши -- разницы совершенно никакой нет. И где поэтому никто ничего и не пишет.
Спасибо сказали:
_Gleb_
Сообщения: 467
ОС: Kubuntu 12.04 LTS

Re: Решено: Функции в C

Сообщение _Gleb_ »

Ну теперь вообще полное просветление по этому вопросу!
Изображение
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: Решено: Функции в C

Сообщение v04bvs »

_Gleb_ писал(а):
28.07.2007 20:34
Про константу? Ну, например, в моём издании К. и Р. стр. 46-47:
(с пропусками)

Код: Выделить всё

...
#define MAXLINE 1000

int getline(char line[], int MAXLINE);
...
main()
{
...
}
...
int getline(char s[], int lim)
{
...
}

Процитированный код невалиден. На этапе препроцессирования это превращается в
int getline(char line[], int 1000);
и не может компилироваться. Либо вы неправильно переписали пример, либо в книжке ошибка\опечатка.
Спасибо сказали:
_Gleb_
Сообщения: 467
ОС: Kubuntu 12.04 LTS

Re: Решено: Функции в C

Сообщение _Gleb_ »

Консенсус не складывается...
Изображение
Спасибо сказали:
Аватара пользователя
Uncle_Theodore
Сообщения: 3339
ОС: Slackware 12.2, ArchLinux 64

Re: Решено: Функции в C

Сообщение Uncle_Theodore »

Ха! Я нашел, где ошибка...

Кстати, я был немного неправ. Признаю, каюсь и прочее...

1. Код скопирован из руского перевода книжки правильно. Вот он
http://www.intelstudio.ru/courses/2006su/KR/ch1kr.html#p19
2. Код действительно не компилится компилятором gcc

Код: Выделить всё

error: expected ';', ',' or ')' before numeric constant

3. В английском оригинале книжки, однако, код другой:
http://www.fis.cinvestav.mx/~jccorona/manu...nguageAnsiC.pdf страница 30 (это PDF файл)

Код: Выделить всё

#include <stdio.h>
#define MAXLINE 1000   /* maximum input line length */
int getline(char line[], int maxline);

Почувствуйте, блин, что называется, разницу... :)

Так что переводчики напартачили.
Спасибо сказали:
_Gleb_
Сообщения: 467
ОС: Kubuntu 12.04 LTS

Re: Решено: Функции в C

Сообщение _Gleb_ »

Uncle_Theodore писал(а):
28.07.2007 23:45
Так что переводчики напартачили.

Да уж...
Изображение
Спасибо сказали: