Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Помогите понять...  (Прочитано 16047 раз)
0 Пользователей и 1 Гость смотрят эту тему.
NIKE
Гость
« : 20-11-2003 11:07 » new

Объясните начинающему пожалуйста, зачем  заголовочный файл начинауют с такого объявления:

#if !defined __MY_HEADERFILENAME_H
#define  __MY_HEADERFILENAME_H
.....
.....
.....
#endif
Записан
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #1 : 20-11-2003 11:23 » 

Хмм, ну как я понимаю, то это проверка на то, существует ли уже константа с именем __MY_HEADERFILENAME_H, и если нет, то определяет эту константу.
Записан

MCP, MCAD, MCTS:Win, MCTS:Web
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #2 : 20-11-2003 11:26 » 

Просто у тебя в тексте могут стоять несколько #include с этим h файлом, таким образом ты можешь "предохраниться" от повторения кода при компиляции. Те если уже один раз было, то хватит.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
NIKE
Гость
« Ответ #3 : 20-11-2003 11:35 » 

ОК, спасибо!!! Последний вопрос...
У меня в проекте три модуля (*.срр), как и где мне необходимо объявлять глобальную переменную, чтобы она была видна во всех модулях проекта? Заранее благодарен!
Записан
Sommer
Молодой специалист

us
Offline Offline

« Ответ #4 : 20-11-2003 11:38 » 

NIKE, в том, который включают в себя все остальные
Записан

когда-нибудь, я верю, ты будешь ехать по этому городу и поймёшь, что хочешь увидеть меня за рулём мчащейся по соседней полосе машины.
но тогда меня уже не будет
в этом городе
forever yours.
NIKE
Гость
« Ответ #5 : 20-11-2003 11:58 » 

Предположим у меня два модуля:
1.срр и 2.срр
И общий заголовочный файл MyHeader.h
MyHeader.h я включаю и в 1.срр и в 2.срр так
#include MyHeader.h
#include MyHeader.h

В MyHeader.h объявляю:
int Data; (ксатати модификатор extern здесь нужен?)

Компилю 1.срр - ОК
Компилю 2.срр - ОК

Делаю Build проекта - получаю:
 1.obj : error LNK2005: "int data" (?data@@3HA) already defined in GetMot.obj
  2.obj : error LNK2005: "int data" (?data@@3HA) already defined in GetMot.obj

Что я делаю не верно и для чего используется модификатор extern?
Записан
Alf
Гость
« Ответ #6 : 20-11-2003 12:02 » 

Цитата: NIKE
ОК, спасибо!!! Последний вопрос...
У меня в проекте три модуля (*.срр), как и где мне необходимо объявлять глобальную переменную, чтобы она была видна во всех модулях проекта? Заранее благодарен!

Объявить - во всех трех как extern, определить - в любом, где удобно. С остальным линкер разберется.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #7 : 20-11-2003 12:13 » 

В MyHeader.h:
extern int g_Data; // декларация

В одном из  срр (любом)
int g_Data = 0; // определение и инициаллизация
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
NIKE
Гость
« Ответ #8 : 20-11-2003 12:18 » 

Спасибо - всё работает, правдо так и не понял почему  :?:
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #9 : 20-11-2003 12:48 » 

Ну..
Цитата: MSDN

The extern keyword declares a variable or function and specifies that it has external linkage (its name is visible from files other than the one in which it's defined).


Лучше я не скажу. Ага
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Sashok
Молодой специалист

us
Offline Offline
Пол: Мужской

« Ответ #10 : 20-11-2003 20:39 » 

Я попытаюсь сказать лучше. :?

Переменные могут связываться либо компилятором, либо линкером. Компилятор следит за тем, чтобы не осталось неразрешенных ссылок и, если таковые остались - ругается. В этом правиле есть одно исключение: если программист в явном виде сообщает компилятору, что ссылка на переменную должна остаться неразрешенной, поскольку разрешать ее будет линкер. Другими словами, если компилятору ясно сказано, что эта переменная определена в другом исходнике, и, стало быть, только линкер сможет проверить, действительно ли она объявлена. Именно для этого и служит слово extern. То есть extern - это НЕ ОБЪЯВЛЕНИЕ ПЕРЕМЕННОЙ, а информация компилятору, что переменная будет объявлена где-то еще!

С другой стороны, каждое объявление глобальной переменной остается доступным линкеру.

Теперь, что получилось у тебя? С точки зрения компилятора, текст #include "MyHeader.h" ровно ничего не значит. Все равно, содержимое этого файла подставляется в твой .срр препроцессором до того, как это блюдо подается на стол компилятору. Таким образом, в приведенном тобой примере текст int Data; оказался как в 1.срр, так и в 2.срр.  Компилятор в обоих случаях определил, что объявлена глобальная переменная Data. С точки зрения компилятора для обоих модулей все в порядке, но линкеру пришли два объявления с одним и тем же именем, вот он и ругается.

Если бы ты в своем MyHeader.h написал extern, линкеру не пришло бы НИ ОДНОГО объявления переменной, соответственно, он опять ругался бы.

Резюме. Глобальная переменная должна объявляться без слова extern в одном и только в одном модуле. Во всех остальных, где она используется, должно стоять extern.

Надеюсь, теперь будет понятнее.
Записан

Если бы окружающие нас объекты содержали столько же ошибок, сколько программы, цивилизация обрушилась бы от первого порыва ветра...
grozny
Гость
« Ответ #11 : 20-11-2003 21:17 » 

нынче удобнее использовать конструкцию

#pragma once
...
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines