2013-03-03 3 views
4

Итак, это код от студента моего друга ...Дублированный идентификатор переменной в функции локальной области

#include <stdio.h> 

int main(){ 
    int hours; 
    int take_one_number(void);{ 
     scanf("%d",&hours); 
    } 
    int minutes; 
    int take_one_number(void);{ 

     scanf("%d",&minutes); 
    } 
    int seconds; 
    int take_one_number(void);{ 

     scanf("%d",&seconds); 
    } 
    int all; 
    printf("%d",all=hours*3600+minutes*60+seconds); 
    return all; 

} 

Ну, это ... компилирует ... и ... хмм, работает ... по просьбе учителя ...

Вопрос: Если я правильно понимаю, take_one_number здесь есть определение переменной для хранения указателя функции. Почему ни GCC, ни LLVM не жалуются на дублированный идентификатор в этих определениях?

+0

Если это должно быть объявление переменной для хранения указателя функции, не должно ли это быть int (* take_one_number) (void)? Я думаю, что это просто объявление прототипа функции внутри функции. – Jay

+0

@ Jay: Да, я пропустил, что нужна звезда для переменной-указателя. – liori

+0

@ lion: ваш комментарий: «Это не переменное определение, звезда отсутствует!» поскольку принятый ответ не является точным вообще, и не является вашим комментарием «звезда необходима для переменной-указателя к функции». Чтобы быть указателем на функцию, вам понадобится 'int (* take_one_number) (void);', для чего требуются две круглые скобки и звезда. Тогда у вас возникнут проблемы с попыткой определить одну и ту же переменную несколько раз, даже если переменная не используется. Скажем, код субоптимальный. Он должен проверить, что вызовы 'scanf()' преуспевают, например. Скобки остаются излишними после объявлений 'take_one_number()'. –

ответ

4

Функция take_one_number объявлена ​​3 раза, но не определена. В каждом случае; после (void) завершает объявление. Оператор зсапЕ затем просто обычный оператор внутри основной(), в окружении бессмысленной сферы {}

+0

И поскольку никто не называется 'take_one_number', ошибок нет. –

+0

Ах, да, так что это не переменное определение, звезда отсутствует! Благодарю. – liori

2
int take_one_number(void); 

Это объявление функции, чей возвращаемый тип int. Это не определение переменной. И область, которую вы сделали для переменных, имеет мало смысла здесь, поскольку в ней не происходит объявления переменной.

2

int take_one_number(void); является прототипом функции, чтобы сообщить компилятору, что есть функция, реализованная где-то с этим именем и свойством. Компилятор не жалуется, потому что вы не определяете новую функцию и не используете эту функцию.

Вы также должны заметить, что блоки, которые следуют за этим прототипом, не являются частью take_one_number, поскольку они разделены точкой с запятой. Создание блоков как независимых блоков области. Чтобы сделать вещи более ясными, возникла бы ошибка компиляции, если между прототипом функции и рядом с ним рядом с ней не было полуколонии.

+0

Дополнительная информация о прототипах функций и о том, следует ли указывать здесь, см. Здесь http://stackoverflow.com/questions/2575153/must-declare-function-prototype-in-c – hmatar

3

В приведенном выше коде,

int take_one_number (void); 

не указатель на функцию, то прототип функции или декларация, функция может быть объявлена ​​более чем один раз, но должны быть определены только один раз.

Смежные вопросы