Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.06.2013, 07:57   #1
el_gato_de_Ch
Пользователь
 
Регистрация: 21.05.2013
Сообщений: 13
По умолчанию модули, локальные и глобальные функции

Всем привет.

Объясните как это работает.

у меня есть модуль А

module_a.h

Код:
void global_func_a(void);
module_a.c
Код:
#include "module_a.h"

void local_func_a();

void global_func_a()
{
	local_func_a();
}

void local_func_a()
{
	
}
module_b.h

Код:
void global_func_b();
module_b.c
Код:
#include "module_b.h"

void local_func_a();

void global_func_b()
{
	local_func_a();
}
ну и собственно сам main

Код:
#include "module_a.h"
#include "module_b.h"

int main()
{
        global_func_a();
        global_func_b();
	return 0;
}
А теперь вопрос, почему я без определения функции в модуле B могу ей пользоваться, только лишь объявив её ??? А если я буду пытаться там её определить, то вылезет ошибка компиляции о переопределении функции ?? я думал, что эта функция должна быть локальной, а следовательно область её видимости должна ограничиваться этим *.c файлом ? или я ошибаюсь, или я неправильно определяю локальную функцию?

Из представленного кода получается, что если я отключу module_a.h у меня возникнет ошибка компиляции, т.к. local_func_a() не будет иметь определения, как предусмотреть такой вариант и заново переопределить функцию через #ifndef ?

P.S. я в модулях не ставил стражи. это просто пример а не рабочий код.

Последний раз редактировалось el_gato_de_Ch; 04.06.2013 в 08:02.
el_gato_de_Ch вне форума Ответить с цитированием
Старый 04.06.2013, 08:12   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
могу ей пользоваться, только лишь объявив её ?
А где ты ее вызываешь? Не вижу нигде чтоб она вызывалась из main().
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 04.06.2013, 08:17   #3
el_gato_de_Ch
Пользователь
 
Регистрация: 21.05.2013
Сообщений: 13
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
А где ты ее вызываешь? Не вижу нигде чтоб она вызывалась из main().
я её вызываю внутри модуля b

из main я её не вызываю, я думаю что это не получится, вопрос в том почему я этой локальной функцией модуля A, могу пользоваться в модуле B, получается я не смогу объявить локальную функцию в B с таким же именем.

Последний раз редактировалось el_gato_de_Ch; 04.06.2013 в 08:31.
el_gato_de_Ch вне форума Ответить с цитированием
Старый 04.06.2013, 08:50   #4
ROD
Linux C++ Qt ARM
Старожил
 
Аватар для ROD
 
Регистрация: 30.11.2008
Сообщений: 3,030
По умолчанию

Это не модули! Это просто кусок кода, вынесенный в другой файл (ну примитивно выражаясь). Соответственно (продолжая примитивно выражаться) при компиляции он все это пихает в файл с main и афигевает от кучи функций с одинаковыми именами (в данном случае это аш две функции local_func_a) Если вы так жаждете иметь по двадцать заголовочных файлов с кучей одинаково названных "Локальных" функций - пользуйтесь пространством имен (namespace).
Дилетант широкого профиля.

"Слова ничего не стоят - покажите мне код!" © Линус Торвальдс

Последний раз редактировалось ROD; 04.06.2013 в 08:53.
ROD вне форума Ответить с цитированием
Старый 04.06.2013, 09:03   #5
el_gato_de_Ch
Пользователь
 
Регистрация: 21.05.2013
Сообщений: 13
По умолчанию

тогда я что-то не пойму.

я создаю h файл, в нём объявляю интерфейс функции, я создаю с файл, в котором, подключаю заголовочный файл и определяю функцию. Затем через #include включаю h файл в проект, но весь код у меня вынесен в с файле.

объясните пожалуйста, как это работает

про модули я прочитал отсюда.

в моём понимании, модуль, это некая абстракция состоящая из заголовка и тела, заголовком является *.h файл, а телом *.c файл
при этом если я хочу обратится извне к этому модулю, то могу обращаться только к тому что написано в заголовке.

Последний раз редактировалось el_gato_de_Ch; 04.06.2013 в 09:12.
el_gato_de_Ch вне форума Ответить с цитированием
Старый 04.06.2013, 09:12   #6
Kukurudza
Форумчанин
 
Регистрация: 02.06.2011
Сообщений: 282
По умолчанию

чтобы void local_func_a() не были видны в других единицах компиляции, нада писать static:
Код:
//где-то внутри *.cpp-шника
static void local_func_a() {
}
тогда эта функция не будет видна в каком то другом месте. ну типа статическая функция внутри единицы компиляции.
Kukurudza вне форума Ответить с цитированием
Старый 04.06.2013, 09:26   #7
el_gato_de_Ch
Пользователь
 
Регистрация: 21.05.2013
Сообщений: 13
По умолчанию

Цитата:
Сообщение от Kukurudza Посмотреть сообщение
чтобы void local_func_a() не были видны в других единицах компиляции, нада писать static:
Код:
//где-то внутри *.cpp-шника
static void local_func_a() {
}
тогда эта функция не будет видна в каком то другом месте. ну типа статическая функция внутри единицы компиляции.
видимо static решает =)

мне сейчас объяснили что в С, объявления всех функций являются по умолчанию глобальными, поэтому так и выходит, что, не смотря на то, что функция явно объявлена и определена в *.с файле её область видимости - глобальная (поправьте если я ошибаюсь). Поэтому она будет видна везде где будет включаться соответствующий h файл. Но я делал по шпаргалке (см ссылку в предыдущем посте) там локальные функции определены вот как я показал, т.е. без модификатора static.

Но предыдущий вопрос про модули остаётся открытым.
el_gato_de_Ch вне форума Ответить с цитированием
Старый 04.06.2013, 10:51   #8
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Цитата:
А теперь вопрос, почему я без определения функции в модуле B могу ей пользоваться, только лишь объявив её ??? А если я буду пытаться там её определить, то вылезет ошибка компиляции о переопределении функции ?? я думал, что эта функция должна быть локальной, а следовательно область её видимости должна ограничиваться этим *.c файлом ? или я ошибаюсь, или я неправильно определяю локальную функцию?
Потому что вначале компилятор компилирует все .c-файлы в объектные модули. Если в .c-файле обнаруживается объявление чего-либо (local_func_a) без определения, то в объектом модуле будет пометка "при компоновке подставить значение local_func_a туда-то и туда-то". Если используется идентификатор, который даже не был объявлен в текущей единице компиляции, диагностируется ошибка этапа компиляции.
Затем компоновщик (Linker) собирает модули в исполняемый файл. На этом этапе происходит "окончательная" сшивка кода каждого модуля; если модуль требует идентификатор, определения которого нет ни в одной доступной единице компиляции, возникает ошибка. Если обнаруживается два неотличимых идентификатора - это тоже ошибка.
Цитата:
Из представленного кода получается, что если я отключу module_a.h у меня возникнет ошибка компиляции, т.к. local_func_a() не будет иметь определения, как предусмотреть такой вариант и заново переопределить функцию через #ifndef ?
Исходя из вышесказанного - никак. Препроцессор отрабатывает ещё до компилятора.
Однако Вы путаете. До тех пор, пока сценарий построения проекта включает компиляцию module_a.c, определение функции будет и компоновщик его подхватит. Другое дело, что перед использованием этой функции в любой единице компиляции нужно дать компилятору понять, что такое идентификатор local_func_a.

Цитата:
Если вы так жаждете иметь по двадцать заголовочных файлов с кучей одинаково названных "Локальных" функций - пользуйтесь пространством имен (namespace).
В языке Си нет пространств имён.
Цитата:
мне сейчас объяснили что в С, объявления всех функций являются по умолчанию глобальными, поэтому так и выходит, что, не смотря на то, что функция явно объявлена и определена в *.с файле её область видимости - глобальная (поправьте если я ошибаюсь). Поэтому она будет видна везде где будет включаться соответствующий h файл.
Неверно. Область видимости - концепция из совершенно другой оперы, она относится к тому, в каких местах кода допустимо использование идентификатора (скажем, статическая локальная переменная функции - глобальный по времени жизни объект, но область её видимости ограничена телом одной функции). То есть, да - область видимости любой функции в Си (в отличие от Pascal, к примеру) глобальная, но это не имеет отношения к рассматриваемому вопросу.

Можно включить .h-файл, содержащий
Код:
int func(int, double);
Можно вместо этого написать непосредственно в соответствующем файле
Код:
int func(int, double);
Результат идентичен: это "обещание" компилятору, что где-то (возможно, в другом модуле) существует идентификатор func, определяемый как функция от int и double, возвращающая int. На основании этого обещания компилятор строит код вызова функции, а вместо адреса в объектном файле создаёт пометку и предоставляет позаботиться об остальном компоновщику.
Abstraction вне форума Ответить с цитированием
Старый 04.06.2013, 11:36   #9
ROD
Linux C++ Qt ARM
Старожил
 
Аватар для ROD
 
Регистрация: 30.11.2008
Сообщений: 3,030
По умолчанию

Цитата:
В языке Си нет пространств имён.
Упс... ошибочка вышла.
Дилетант широкого профиля.

"Слова ничего не стоят - покажите мне код!" © Линус Торвальдс
ROD вне форума Ответить с цитированием
Старый 04.06.2013, 17:52   #10
el_gato_de_Ch
Пользователь
 
Регистрация: 21.05.2013
Сообщений: 13
По умолчанию

Цитата:
Сообщение от Abstraction Посмотреть сообщение
спасибо, за разъяснение, значит всё-таки static
el_gato_de_Ch вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
процедуры, модули и функции Smirnov Паскаль, Turbo Pascal, PascalABC.NET 3 02.03.2012 11:57
Локальные переменные vs Глобальные Sibedir Общие вопросы Delphi 27 01.01.2011 13:02
Глобальные и локальные переменные Kapitann JavaScript, Ajax 2 03.08.2010 14:24
Си++.Глобальные,локальные параметры. Медина Помощь студентам 0 02.06.2009 21:51
Локальные и глобальные переменные. Proger10 Общие вопросы Delphi 1 04.05.2009 05:55