Действительно ли возможно избежать глобальных переменных в строго процедурной программе?

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

10
задан nicael 21 May 2014 в 18:48
поделиться

8 ответов

Вы также можете писать объектно-ориентированный код на C. Вы не получите все плюсы C++, он уродлив, и вам придется вручную передавать этот указатель (я видел self, используемый для этого, чтобы сделать его совместимым с C++), но он работает. Итак, технически, вам не нужно глобальное состояние в чистых процедурных языках по тем же причинам, по которым оно не нужно в объектно-ориентированных языках. Вы просто должны передавать состояние явно, а не неявно, как в ОО-языках.

12
ответ дан 3 December 2019 в 16:09
поделиться

Вы можете, например, попробовать создать с помощью dia (инструмент построения диаграмм) простой класс (например, квадрат). {{1} }
http://projects.gnome.org/dia/
http://dia-installer.de/index_en.html

Затем вы можете преобразовать этот класс в код C, используя dia2code: {{ 1}}
http://dia2code.sourceforge.net/

В частности, скажем, вы создали квадрат класса внутри диаграммы square.dia. Затем вы набираете:

$ dia2code -t c square.dia

... и вы увидите, что любое объектно-ориентированное программирование можно преобразовать в программу на C без глобальных переменных. Изучите созданные файлы square.c и square.h

ПРИМЕЧАНИЕ: в Windows вам понадобится обходной путь, чтобы заставить dia2code работать. Перед использованием dia2code замените square.dia на square.zip, разархивируйте его и переименуйте результат в square.dia

0
ответ дан 3 December 2019 в 16:09
поделиться

Вы можете иметь переменные в стеке или куче, которые будут существовать в течение всего срока службы программы.

Передача указателей на структуру стиля объекта каждой функции - хороший способ получить стиль кодирования OO C.

(я бы посоветовал поискать исходники linux)

0
ответ дан 3 December 2019 в 16:09
поделиться

Конечно. Просто объявите где-нибудь struct , выделите для нее некоторую память, передайте указатель на выделенную память функции инициализации, и вперед. Просто передайте указатель на все функции, которые требуют использования структуры.

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

2
ответ дан 3 December 2019 в 16:09
поделиться

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

0
ответ дан 3 December 2019 в 16:09
поделиться

Как Например, посмотрите, как функции файлового ввода-вывода в стандартной библиотеке C работают с указателем на объекты FILE , которые (в основном) непрозрачны. Или посмотрите, как API ОС работают с дескрипторами и т. Д. Для инкапсуляции информации. Программа создает объекты, использует API-интерфейсы, которые воздействуют на эти объекты и закрывают / удаляют объекты - все с использованием прямого C.

6
ответ дан 3 December 2019 в 16:09
поделиться

Все ОО - это образ мышления и целая куча поддержки компилятора.

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

Например, я использовал функции/процедуры с префиксом их принадлежности к модулю, принимая первый параметр как связанную структуру модуля.

// System.h

typedef struct _System
{
    struct _System *owner;
    LinkedList *elements;
} System;

// System.c

int System_FindName ( System * system, char *name)
{
..
}

и т.д.

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

3
ответ дан 3 December 2019 в 16:09
поделиться

Глобальная переменная - это не что иное, как неявный аргумент процедуры. Сделайте его явным , и глобальная переменная исчезнет.

Примечание: тот факт, что вы больше не используете глобальную переменную , не означает, что вы больше не используете глобальное состояние ! То, что мы сделали выше, было чисто синтаксическим преобразованием, семантика программы вообще не изменилась. Он такой же несоставимый, немодульный, не потокобезопасный, непараллелизируемый, как и раньше.

3
ответ дан 3 December 2019 в 16:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: