2013-11-20 1 views
2

Я изучаю C и изучаю функции. Итак, я прочитал, что когда я реализую свою собственную функцию, я должен объявить ее перед main(). Если я пропущу объявление, компилятор получит сообщение об ошибке.
Как я изучал этот пример (находит, если число является простым числом)Объявить функцию void в C?

#include <stdio.h> 

void prime();    //function prototype(declaration) 

int main() 
{ 
    int num,i,flag; 

    num = input();   // No argument is passed to input() 

    for(i=2,flag=i; i<=num/2; ++i,flag=i) 
    { 
     flag = i; 

     if(num%i==0) 
     { 
     printf("%d is not prime\n",num); 
     ++flag; 
     break; 
     } 
    } 

    if(flag==i) 
    printf("%d is prime\n",num); 

    return 0; 

}  

int input() /* Integer value is returned from input() to calling function */ 
{ 
    int n; 
    printf("\nEnter positive enter to check: "); 
    scanf("%d",&n); 
    return n; 
} 

Я заметил, что функция штрих() объявлен, но в основном функция входа() вызывается, а также функция input() реализуется внизу. Хорошо, я подумал, что это ошибка, и я меняю имя от простого до ввода.
Однако если я удалю декларацию, и я ее не помещаю, программа скомпилируется без ошибок и работает гладко. (Я компилирую и запускаю его в Ubuntu)

Итак, мой вопрос: нужно ли объявлять функцию void без аргументов?

+1

Функция без аргументов должна быть 'void f (void)', IIRC. 'void f()' может принимать * любые * аргументы (да, это потрясающий язык C). –

+0

prime() никогда не называется, не так ли? поэтому нет прототипа, потому что он никогда не называется – Constantin

+0

. Похоже, вы не называете 'prime' нигде? Если вы его не называете, нет необходимости объявлять его (до). –

ответ

4

Если у вас нет прямого объявления вашей функции перед местом использования, компилятор создаст вам неявное объявление - с подписями int input() - он примет имя вызываемой функции, он предположит, что функция возвращает int и может принимать любые аргументы (как Bartek отмечено в комментарии).

Для этой функции неявное объявление соответствует реальному объявлению, поэтому у вас нет проблем. Тем не менее, вы всегда должны быть осторожны в этом, и вы всегда должны предпочитать форвардные декларации вместо неявных (независимо от того, являются ли они одинаковыми или нет). Таким образом, вместо того, чтобы просто иметь прямое объявление функции void prime() (предполагая, что вы будете использовать его где-то), вы также должны иметь объявление вперед int input().

Чтобы увидеть, как вы можете передать любое количество аргументов, подумайте:

#include <stdio.h> 

// takes any number of the arguments 
int foo(); 

// takes no arguments 
int bar(void) 
{ 
     printf("Hello from bar()!\n"); 
     return 0; 
} 

int main() 
{ 
     // both works 

     // However, this will print junk as you're not pushing 
     // any arguments on the stack - but the compiler will assume you are 
     foo(); 

     // this will print 1, 2, 3 
     foo(1, 2, 3); 

     // works 
     bar(); 

     // doesn't work 
     // bar(1, 2, 3); 

     return 0; 
} 

// definition 
int foo(int i, int j, int k) 
{ 
    printf("%d %d %d\n", i, j, k); 
    return 0; 
} 

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

+0

Еще один вопрос. Вы сказали, что void prime() может принимать любые аргументы. В этом случае, как я знаю, как будет сопоставление передаваемых аргументов с переменными внутри функции? - Nat95 2 мин назад @NemanjaBoric – yaylitzis

+1

@ Nat95 см. Мое редактирование! –

+0

Я подозреваю, что это скомпилируется. В C ** переопределение ** не допускается. – haccks

0

Если пробел не используется, пропустите объявление.

Код не компилируется как C++, потому что компилятор будет жаловаться, что функция input используется, но не объявлена. Компилятор C может выдать предупреждение, но C более расслаблен и делает неявное объявление ввода как int input(), что означает, что вы можете передать любое значение для ввода и ввода, возвращает int.

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

1

Не объявляя прототип и полагаясь на поощрение по умолчанию для аргумента/возврата, является опасным и является частью старого C. В C99 и далее незаконно вызывать функцию без предварительного объявления или определения функции ,

мой вопрос в том, нужно ли объявлять функцию void без аргументов?

Да. Для этого вам нужно поставить void в круглую скобку функции.

void foo(void); 

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

void foo(); 

означает, что она может принимать любое количество аргументов.

+0

Ещё один вопрос. Вы сказали, что 'void foo()' может принимать любое количество аргументов. В этом случае, как я знаю, как будет сопоставление передаваемых аргументов с переменными внутри функции? – yaylitzis

+0

@ Nat95; Все аргументы явно преобразуются в тип 'int'. – haccks