C - структура программы (без глобальных переменных, включений и т. Д.) - PullRequest
6 голосов
/ 09 июля 2010

Я использую C (не C ++) и не знаю, как избежать использования глобальных переменных.

Я достаточно хорошо разбираюсь в C, его синтаксисе и способах написания базового приложения, но я не уверен в правильном способе структурирования программы.

Как действительно большие приложения избегают использования глобальных переменных? Я почти уверен, что всегда должно быть хоть что-то, но для больших игр и других приложений, написанных на C, какой лучший способ сделать это?

Есть ли какое-нибудь хорошее программное обеспечение с открытым исходным кодом, написанное строго на C, на которое я мог бы взглянуть? Я не могу думать ни о чём, кроме меня, большинство из них похоже на C ++.

Спасибо.

Редактировать

Вот пример, где я бы использовал глобальную переменную в простом приложении для перехвата API, которое является просто DLL внутри другого процесса.

Это приложение, в частности, перехватывает функции API, используемые в другом приложении. Это делается с помощью WriteProcessMemory, чтобы перезаписать вызов оригинала и сделать вместо этого вызов моей DLL.

Однако, когда un перехватывает функцию API, мне приходится записывать исходную память / машинный код.

Итак, мне нужно поддерживать простой байтовый массив для этого машинного кода, по одному для каждой перехваченной функции API, и их много.

// Global variable to store original assembly code (6 bytes)
BYTE g_MessageBoxA[6];

// Hook the API function
HookAPIFunction ( "user32.dll", "MessageBoxA", MyNewFunction, g_MessageBoxA );

// Later on, unhook the function
UnHookAPIFunction ( "user32.dll", "MessageBoxA", g_MessageBoxA );

Извините, если это сбивает с толку.

Ответы [ 6 ]

7 голосов
/ 09 июля 2010

«Как действительно большие приложения избегают использования глобальных переменных?»

  1. Используйте статические переменные.Если функция должна что-то запомнить между вызовами, используйте это в сравнении с глобальными переменными.Пример:

    int running_total (int num) {
        static int sum  = 0;
        sum             += num;
        return sum;
    }
    
  2. Передача данных через параметры, так что значение определяется в одном месте, может быть main(), и передается туда, где оно необходимо.

  3. Если все остальное терпит неудачу, продолжайте и используйте глобальный, но попытайтесь смягчить потенциальные проблемы.

    1. Как минимум, используйте соглашения об именах, чтобы минимизировать потенциальные конфликты.Например: Gbl_MyApp_DeveloperName.Таким образом, все глобальные переменные начинаются с части Gbl_MyApp_ - где «MyApp» было чем-то описательным для вашего приложения.
    2. Попытайтесь сгруппировать функции по назначению, чтобы все, что нужно для данного глобала, было в одномфайл (в пределах разумного).Тогда глобальные переменные могут быть определены и ограничены этим файлом (остерегайтесь ключевого слова extern).
2 голосов
/ 09 июля 2010

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

2 голосов
/ 09 июля 2010

Есть несколько допустимых вариантов использования глобальных переменных.Школы начали учить, что они злые, чтобы программисты не ленились и не злоупотребляли ими.Если вы уверены, что данные действительно нужны глобально, используйте их.Учитывая, что вы беспокоитесь о том, чтобы хорошо выполнять свою работу, я не думаю, что вы слишком сильно ошибетесь, используя собственное мнение.

1 голос
/ 10 марта 2013

Я думаю, что то же самое, глобальные переменные плохие, ухудшают читаемость и увеличивают вероятность ошибок и других проблем.

Я объясню свой пример.У меня есть main (), который делает несколько вещей.Большая часть действия происходит от таймеров и внешних прерываний.Это функции без параметров, из-за платформы, которую я использую, 32-битный микроконтроллер.Я не могу передать параметры и, кроме того, эти прерывания и таймеры являются асинхронными.Самый простой способ - глобальный, представьте, прерывает заполнение буфера, этот буфер анализируется в таймере, а анализируемая информация используется, сохраняется, отправляется в другие таймеры.Хорошо, я могу установить флаг прерывания и обработать его в основной функции, но при выполнении критически важного программного обеспечения это плохая идея.

Это единственная глобальная переменная, которая не заставляет меня чувствовать себя плохо; -)

1 голос
/ 09 июля 2010

Лучшим программным обеспечением с открытым исходным кодом для изучения C в моем колледже была Linux, так что вы можете получить примеры из их источника.

0 голосов
/ 09 июля 2010

Глобальные переменные почти неизбежны. Тем не менее, они часто злоупотребляют. Они не являются заменой для передачи правильных параметров и проектирования правильных структур данных.

Каждый раз, когда вам нужна глобальная переменная, подумайте: а если мне понадобится еще одна такая?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...