Здраствуйте, подскажите как разбить части программы, распределить в другие файлы для удобства работы (например функцию a в файл A, а функцию b в файл B), куда их заносить (на диск С или не важно) и как их потом вызывать в main. Слышала что через include «name», но как?
Последний раз редактировалось Axrik; 30.01.2012 в 15:10 .
Регистрация: 02.01.2011
Сообщений: 3,322
Axtrik, что касается функций определённых в разных файлах, то нужны лишь прототипы (объявления) этих функций перед вызовом.
#include void funcfrom_file_A(int val1, int val2, int val3); void funcfrom_file_B(int val1, int val2, int val3); void funcfrom_file_C(int val1, int val2, int val3); int main ()
Файл file_A.c
#include void funcfrom_file_A (int m, int n, int p)
Файл file_B.c
#include void funcfrom_file_B (int m, int n, int p)
Файл file_C.c
#include void funcfrom_file_C (int m, int n, int p)
Теперь, что касается глобальных переменных объявленных со словом extern:
#include void funcfrom_file_A(); void funcfrom_file_B(); void funcfrom_file_C(); void func_init_variables (); int x, y, z; int main ()
Файл init_variables.c
Как разделить файл на части программой WinRAR
extern int x, y, z; // функция для инициализации переменных void func_init_variables ()
Файл file_A.c
#include extern int x, y, z; void funcfrom_file_A ()
Файл file_B.c
#include extern int x, y, z; void funcfrom_file_B ()
Файл file_C.c
#include extern int x, y, z; void funcfrom_file_C ()
Примечание — Только в одном из файлов должно быть объявление без extern, во всех остальных с extern.
А теперь, что касается глобальных переменных объявленных в заголовочных файлах name.h.
Создадим два заголовочных файла. В один поместим глобальные переменные. А в другой прототипы (объявления) функций.
#ifndef GLOBAL_VARIABLES_H #define GLOBAL_VARIABLES_H int x, y, z; #endif // GLOBAL_VARIABLES_H
Файл functions.h
#ifndef FUNCTIONS_H #define FUNCTIONS_H void funcfrom_file_A(); void funcfrom_file_B(); void funcfrom_file_C(); void func_init_variables (); #endif // FUNCTIONS_H
Файл init_variables.c
#include «global_variables.h» // функция для инициализации переменных void func_init_variables ()
Файл file_A.c
#include #include «global_variables.h» void funcfrom_file_A ()
Файл file_B.c
#include #include «global_variables.h» void funcfrom_file_B ()
Файл file_C.c
#include #include «global_variables.h» void funcfrom_file_C ()
P.S. Советую прочитать в книге Кернигана и Ритчи «Язык программирования С» полностью главу 4 «Функции и структура программы». Времени потратите немного, зато пользы будет.
Последний раз редактировалось 8Observer8; 02.03.2012 в 16:30 .
Источник: www.programmersforum.ru
Пирамида логики
Наступает момент , когда начинаешь задумываться как наиболее удобным образом разбить программу на несколько файлов для того , чтобы потом брать какую-то часть файлов (обычно это пары *.h + *.c) и легко и не принужденно использовать в другом проекте.
Язык C++ с нуля | #35 Разделение программного кода на несколько файлов в c++
Например надо выбрать функционал по работе с памятью AT45 и включить в другой проект.
Что мы на самом деле имеем ввиду : надо взять определенный функционал из одного проекта и добавить в другой.
И вот тут желательно , чтобы старые связи этого функционала со старым проектом никак не мешали в новом (точнее желательно чтобы их совсем не было). Имеется ввиду какие-то явные ссылки на объекты из других файлов должны быть минимальны.
И вот тут фишка вся в том , что если программа грамотно по логике разбита на функциональные части , то и связи будут минимальными, точнее они будут реализовываться через минимальное количество объектов.
И вот тут мы приходим к выгоде использования СТРУКТУР. Структуры — это по сути указатели на неограниченное количество объектов, которые можно реализовать через один объект , разделяемый в разных файлах (через extern).
Достаточно в программе сделать #include какого-то заголовочного H файла из другого проекта , где описана некая структура данных и тогда эти данные будут нормально поняты компилятором и доступны в вашем новом проекте.
Но так устроен язык программирования, что чтобы реально использовать эти данные их надо сначала инициализировать, а потом что-то с ними делать и эта задача решается в файле с аналогичным названием только с расширением С.
В чем тут идея : можно включать H файлы сколь угодно много , все скомпилируется нормально , но ничего реально происходить не будет, никакого кода генерироваться не будет.
Чтобы что-то реально начало происходить надо чтобы в коде, который начинается грубо говоря с функции main, вы начали где-то вызывать функции вашего функционала или начали работать с вашими объектами.
Структуры
Теперь хочется показать логический пример из 2 частей программы (2 пары *.h и *.c ) файлов, два функционала.
Сначала определим кто для кого поставляет информацию по объектам , кто будет донором ,а кто будет юзером. То есть всегда надо понять для кого мы предоставляем функционал (смотрим сначала со стороны донора). Если логика реализована правильно , то всегда выстраивается пирамида из кирпичей (это какой-то функционал), где снизу понятно доноры , выше юзеры и связь между ними через минимально количество объектов.
Причем в идеале каждый кирпич контактирует только с соседом и не пытается прыгнуть через ряды к другому кирпичу. Обратите внимание , что управление (использование) идет всегда сверху , а ресурсы предоставляются всегда снизу.
Самое трудное что понять? Правильно — какой кирпич сделать самым нижним, так как если не выделить правильно его функционал , то потом придется переделывать всю пирамиду.
И еще мы пытаемся так все продумать, чтобы кирпич из этой пирамиды с минимальными изменениями можно было легко вставить в другую пирамиду.
————— h ——————— typedef const struct DONOR2< uint32_t page; uint32_t offset; uint32_t size; >DONOR2; typedef const struct DONOR1< DONOR2wifi_ssid; DONOR2wifi_pw; DONOR2http_host; DONOR2http_port; >MEM_SETTINGS; ————— c ——————— сначала глобально сразу инициализируем структуру const DONOR1 don1 = < < 123, 0 , 456>, // здесь комментарии что это < 234, 789, 123>, // здесь комментарии что это < 456, 456, 234>, // < 567, 678, 012>// >; // const это для того , чтобы данные прОписались во FLASH память // (адреса 0х8ххххх), тогда экономится SRAM. // далее пишем функции для работы с этими данными , // какие изменения мы хотим производить.
И вот тут ВАЖНО понимать , что изменять мы будем именно с нашими данные в нашем файле С.
К чужим мы будем обращаться только если они находятся на ниже стоящем уровне пирамиды.
Второй файл (по очереди написания) — это файл юзера, то есть он находится на вышестоящей ступеньке пирамиды.
Во втором файле , который у нас будет использовать данные первого (ниже стоящего в пирамиде) , сначала ключаем через #include типы данных первого файла.
И что самое важно создаем свои структуры (абстракции), включая в них как элементы структуры из первого файла . Причем включать можно явно или как ссылки.
————————— H —————————— typedef struct USER1< uint8_t ii; DONOR1 don1; // явно >USER1; typedef struct USER2< const uint8_t yy; const DONOR1 *pDon1; // как ссылка >USER2; ————————— С —————————— extern const DONOR1 don1; const USER1 user1 = ; // и это уже не прокатывает // initializer element is not constant // = элемент инициализатора don1 не является постоянным. const USER2 user2 = ; // ПРОКАТИТ // а далее в коде можно будет : // присвоить user2. pDon1 = &don1; .
Тут уже инициализация user1 только через функцию и const у нее придется поэтому убрать.
Для user2 далее в любой функции можно присвоить pDon1 любое значение.
В итоге yy и user2.pDon1 попадут во FLASH [0х8ххххх] (обратите внимание внутри структуры USER2 все элементы объявлены const) , а user2 в SRAM .
Выводы : вариант с USER1 у нас не прокатит, а вариант с USER2 приемлем вполне , так как во SRAM будет использована только одна ячейка памяти (это адрес самой USER2). Экономия SRAM будет достигнута.
Что далее плохо с указателями — их можно путать. Думаешь , что присваиваешь указатель на один тип объекта , а он принадлежит другому на самом деле со всеми вытекающими последствиями.
Но надо выбирать — хочешь универсальности жертвуй помощью компилятора. Да вообще все есть указатель, главное их не путать.
Для чего мы все это делали — для того , чтобы взять теперь функционал первого файла легко и перенести во другой проект. Там в другом проекте объявляем extern const DONOR1 don1; и пользуемся на здоровье его функционалом. Сам перенесенный файл при этом править вообще не надо.
Источник: kkmspb.ru
Как я могу разделить приложение javascript на несколько файлов?
Я создал приложение javascript со всем кодом в одном файле. Приложение сильно выросло, и я думаю, что пришло время разделить его на несколько файлов, но мне сложно понять, как это сделать. Я думаю, что проблема заключается в том, как я решил создать приложение, которое использует следующий шаблон:
var myApp = function()< //there are several global variables that all of the modules use; var global1, global2, module1, module2; global1 = < prop1:1 >; //There are also several functions that are shared between modules function globalFunction() < >var ModuleOne = function() < function doSomething()< //using the global function globalFunction(); >return < doSomething:doSomething >>; var ModuleTwo = function() < function doSomething()< //module 2 also needs the global function globalFunction(); //Use the functionality in module 1 //I can refactor this part to be loosely coupled/event driven module1.doSomething(); >>; module1 = new ModuleOne(); module2 = new ModuleTwo(); >;
Даже если все модули были слабо связаны и управлялись событиями, я до сих пор не знаю, как бы я разделил это на несколько файлов, учитывая, что каждый модуль использует общие функции/переменные. У кого-нибудь есть предложения?
Mark Brown 06 янв. 2012, в 03:44
Поделиться
Если серьезно, инструменты, такие как module8, решают вашу проблему
Raynos 06 янв.
2012, в 02:25
Взгляните на шаблон проектирования в этой статье: адекватноgood.com /2010/3/JavaScript-Module-Pattern-In- Depth — вы можете разделить определение модуля на несколько файлов таким образом, чтобы общие свойства можно было использовать совместно, а также Вы создаете переменные или методы, которые являются частными только для определенного файла.
nnnnnn 06 янв. 2012, в 02:30
Mark Brown 06 янв. 2012, в 03:21
Mark Brown 10 янв. 2012, в 23:09
Если модули используют общие функции / переменные, то они не являются свободно связанными.
Michael Mior 10 янв. 2012, в 23:47
Показать ещё 3 комментария
Поделиться:
5 ответов
Лучший ответ
Взгляните на шаблон дизайна в этой статье: http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth — вы можете разделить определение своего модуля на несколько файлов таким образом, чтобы общие свойства были разделены но также позволяет создавать переменные или методы, которые являются частными только для определенного файла.
Основная идея заключается в том, что отдельные JS файлы добавляют к тому же модулю с таким кодом:
var MODULE = (function (my) < var privateToThisFile = «something»; // add capabilities. my.publicProperty = «something»; return my; >(MODULE || <>));
Где в каждом JS файле, если MODULE уже определен (из другого JS файла), вы добавляете его, иначе вы его создадите. Вы можете настроить его так, чтобы он (в основном) не имел значения, в какой порядок включены различные файлы.
В статье описаны несколько вариантов, и, конечно же, вы, вероятно, придумаете свои собственные твики.
nnnnnn 10 янв. 2012, в 23:58
Поделиться
после целого дня, ломая голову о том, как действовать, я рад, что нашел этот ответ.
Raja Khoury 08 апр. 2019, в 20:40
Не добавляйте к путанице, но, исходя из фона С++, я попытался построить что-то, похожее на нечто вроде пространства имен С++, описанным ниже. он работает, но я хотел бы знать, является ли это приемлемым шаблоном для OP?
var namespacename = function()<> namespacename.mainvalue = 5; namespacename.maintest = function()
namespacename.gamevalue = 15; namespacename.game = function() < this.callme = function()< console.log( «callme» ); >> namespacename.gametest = function()
testbed init = function()
Jochem Van Der Spek 20 нояб. 2012, в 13:46
Поделиться
Зачем объявлять namespacename как пустую функцию, которая никогда не вызывается? Вы можете объявить его как пустой объект с var namespacename = <>, и остальной код не нужно будет менять.
nnnnnn 10 сен. 2013, в 23:02
Это решение работает для меня!
Marco-dev 11 апр. 2016, в 14:46
Вы можете поместить общие функции и общие модули в объект myApp, чтобы они не загрязняли глобальное пространство имен, но могут быть доступны в любом месте, не находясь внутри одного и того же закрытия.
myApp.moduleOne = function() myApp.moduleTwo = function() myApp.globalFunction = function()
Затем вы можете определить их в любом файле и использовать их в любом файле.
Вы также можете просто разбить файл на несколько файлов, но потребовать, чтобы они были включены в определенный порядок, который сохраняет ваше закрытие. Если вы разбираете файлы по практическим причинам редактирования, но рекомбинируете и сворачиваете их для фактического развертывания, то это не будет стоить вам ничего с точки зрения того, как вы пишете код или как его развертываете, но даст вам множество небольших файлов для удобства редактирования.
jfriend00 06 янв. 2012, в 02:58
Поделиться
myApp не настоящее имя, я просто использовал его в качестве примера. Учитывая ваше предложение, мне нужно будет изменить каждый вызов globalFunction на myApp.globalFunction () правильно?
Mark Brown 06 янв. 2012, в 02:35
Источник: overcoder.net