2013-07-08 5 views
7

Я прочитал письмо на стене, Избегайте глобалов. Что приводит к очевидному вопросу, как лучше всего это сделать?Как не использовать глобальные переменные в c

Я, очевидно, хочу сделать это с помощью текущего проекта. Цель состоит в том, чтобы позволить удаленному компьютеру отправлять «нажатия клавиш» на приложения, которые уже имеют считыватель stdin. Идея состоит в том, чтобы позволить существующему коду обнаружить отсутствие ожидающего нажатия клавиши, а затем проверить, есть ли «udp keystroke», и, если это так, введите его так, чтобы он выглядел как клавиатура. Минимально-инвазивные и не потребуют забора ретро-фитинга в коде других людей.

Я мощеный небольшой UDP-ридер сокета, который использует setup() функцию, чтобы открыть и связать порт, то в service() функцию в цикле, которая не использует Неблокирующий select() один раз, не цикла, просто проверить, есть ли что-нибудь, чтобы прочитать прямо сейчас. Если да, то читать данные из сокета и сделать что-то с ним, иначе вернуть 0.

// pseudo c 
char c; 

setup(); 
while (1) 
{ 
    c = check_for_keyboard_entry(); 
    if (c == 0) 
     c = service(); 
    handle_keypress(c); 
    do_a_bunch_of_other_stuff(); 
} 

Очевидный способ сделать это с помощью нескольких глобалов передать порт, тайм-аут, SOCKADDR-х и т.д. между две функции. Но ты будешь жадным глобалом, верно?

Итак, что является предпочтительным способом передачи шести или восьми варов между функциями?

Если бы я использовал статические вары в setup(), они были бы доступны в рутине service()?

Я полагаю, что структура, которая получает malloc-ed и передается, будет работать. Я должен иметь cleanup(), чтобы закрыть сокет и освободить память.

ПОМНИТЕ, ЭТО ВОПРОС C. NO C++!

+2

_ '' Я полагаю, что структура, которая получает malloc-ed и проходит вокруг, будет работать. '' - Вы получили это! –

+0

+1 для сырой скорости! Любые другие подходы? –

+1

Пожалуйста, исправьте \ 0 до 0 или '\ 0' –

ответ

3

Вы можете просто упаковать всю эту информацию в struct. Структура может быть видна клиенту или непрозрачным типом. Непрозрачный тип может быть лучшим выбором, поэтому вы можете скрыть данные (инкапсуляцию) для сложных типов.

typedef struct { 
port_t port; 
timeout_t timeout; 
sockaddr_t sockaddr; 
etc_t etc; 
} my_stuff; 

затем передавать его по ссылке:

void Foo(my_stuff*); 

Я полагаю, структуру, которая получает таНос-е изд и розданы будет работать. Я должен был очистить(), чтобы закрыть сокет и освободить память.

Как правило, структура не всегда должна быть malloc 'ed. Но да, это может быть случай, когда это необходимо.

+0

Но разве это не делает структуру глобальной? Или вы имели в виду, что 'foo()' возвращает указатель на 'my_stuff'? Если да, то как бы 'my_stuff' сохранялся при закрытии области' foo() '? Или вы статируете статику 'my_stuff' в' foo() '? –

+2

@WesMiller: вы можете поместить его в стек во внешнем пространстве. Итак, 'int main() {my_stuff stuff; stuff.port = 80; ...; Foo (& прочее); ...; return 0; } '. Статические переменные в функциях де-факто глобальны и имеют сходные проблемы. –

+0

@MaciejPiechotka +1. Применена хорошо заслуженная, самоуправляемая повязка. Ответ настолько очевиден, как только вы это увидите. –

Смежные вопросы