Как несколько переменных могут быть переданы функции чисто в C?

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

Я не должен передавать Всех их слишком часто, но я надеялся иметь функцию, которая считает входные данные (в этом случае из сети TCP) и затем проанализирует данные (IE, 3-й байт содержит состояния 8 из цифровых вывод (согласно которому бит в том байте является высоким или низким)), и поместите это в переменную, где я могу затем использовать в другом месте в программе.

Я хотел, чтобы та функция была отдельной от основного (), функция, но сделать так потребует передающих указателей приблизительно на приблизительно 20 переменных, в которые это записало бы. Я знаю, что мог сделать переменные глобальными, но я пытаюсь помочь отладить путем создания этого очевидным, когда функции позволяют отредактировать ту переменную путем передачи его функции.

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

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

6
задан aquanar 12 April 2010 в 21:09
поделиться

5 ответов

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

0
ответ дан 10 December 2019 в 02:44
поделиться

Передача указателя на структуру обычно является "чистым" путем. Интеллектуальное определение структуры данных может дать этому методу мощность и гибкость. Например, возьмите структуру данных:

struct func_params {
    int type;
    union {
        struct {
            int    port;
            int    direction;
            long   target_addr;
        } digital_io;
        struct {
            int    channel;
            long   sample_rate;
        } analog_in;
        struct {
            int    channel;
            int    async;
            int    hold_output;
        } analog_out;
        struct {
            int    port;
            int    direction;
            int    encoding;
        } serial_io;
    };
};

Определите вашу функцию с чем-то вроде

my_function (struct func_params* pStruct, size_t length)

При использовании функции сначала создайте буфер, достаточно большой, чтобы содержать структуру данных плюс размер любых данных потенциально переменной длины, которые вы будете отправлять в функцию (например, данные для отправки порта). Первая часть буфера данных будет состоять из определенной вами структуры. Остальная часть буфера ( длина - sizeof (struct func_params) байт) будет местом, где вы храните свои данные. Ваша функция считывает член структуры типа и определяет, как интерпретировать остальную часть структуры, а после обработки структуры она может определить, как интерпретировать раздел данных переменной длины.

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

0
ответ дан 10 December 2019 в 02:44
поделиться

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

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

typedef struct a {
  struct b {
    int b1;
    int b2;
  } b_s;
  struct c {
    int c1;
    int c2;
  } c_s;
} a_s;
6
ответ дан 10 December 2019 в 02:44
поделиться

Я бы сказал, что лучше всего использовать структуру. Вы можете передать только один из членов функции, если вам не нужны все переменные в конкретной функции. Вы также можете воспользоваться битовым полем для этого 3-го байта, если вам нужно установить отдельные биты. Конечно, это битовое поле также может быть членом вашей структуры.

0
ответ дан 10 December 2019 в 02:44
поделиться

Это классическое использование «блока параметров» - просто указатель на известную структуру.

К достоинствам относятся: Эффективность, поскольку любой доступ к заданному параметру представляет собой адрес плюс смещение; Легкость отладки (вы можете увидеть все параметры в одной «печати»); Местность (кеширует красиво); Легко превратить в стекируемый набор вызовов, в котором вы не можете легко узнать, какие параметры могут потребоваться любой данной функции в стеке.

К недостаткам можно отнести: глядя на вызов функции , вы не можете сказать, какие параметры важны для вызываемого - вы должны знать или копаться в источнике этой функции; Легче вызвать побочные эффекты, особенно если вы позволяете вызываемым функциям изменять блок (плохо, плохо, плохо!); Увеличивает связь (каждая функция может видеть каждый параметр, что может привести к соблазну ...)

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

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