Глобальные переменные и возвращают несколько массивов переменной длины (указатели) в функции C - PullRequest
2 голосов
/ 25 января 2012

У меня есть некоторый опыт программирования, но не так много с C.

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

Эта программа выполняетмного вычислений на нескольких длинных массивах типа double с переменной длиной, поэтому все они являются указателями.Два вопроса:

1) Переменные, которые рассчитываются один раз с начала, а затем служат входными данными для многих последующих функций. Должен ли я сделать их глобальными переменными внутри этого файла?Из моего опыта программирования на языках более высокого уровня глобальные переменные не очень хороши.Разве это не так для C и почему?

2) Когда 1 из моей функции хочет вернуть несколько указателей (например, каждый указывает на двойной массив длины n), скажем double * p1, double * p2, double * p3, которые связаны, я могу объединить их в структуру:

struct pointers {
    double *p1, *p2, *p3;
} ptr;

foo1 будет принимать в качестве ввода double * input и вычислять ptr-> p1, ptr-> p2, ptr-> p3, а затем ptr будет позже служить вводом для foo2.Должен ли я написать

struct pointers *foo(double *input)

или

void foo1(double *input, struct pointers ptr)

или

void foo1(double *input, struct pointers *ptr)

Почему функции C обычно являются "пустыми" функциями, если только они не возвращают простоint или двойные переменные?Имея вход и выход в качестве параметров - это сбивает с толку?

Должен ли я инициализировать ptr-> p1, ptr-> p2, ptr-> p3 внутри или снаружи foo1?

Обратите внимание, что foo () - это основная функция, которая будет вызывать foo1, foo2 последовательно.

Ответы [ 4 ]

1 голос
/ 25 января 2012

Ответить на вопрос

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

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

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

Чтобы ответить на вопрос 2) лучше написать сигнатуру функции

struct  {
    double output1; 
    double output2; 
    double output3;
 } output_t;

и подпись функции как:

ReturnCode foo ( double input , struct output_t * output);  

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

1 голос
/ 25 января 2012

1 - Глобальные переменные также не приветствуются в Си. Это две важные причины:

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

Но в вашем случае, как вы сказали ptr.p1, ptr.p2, ptr.p3 станут входными данными для многих других последующих функций, возможно, будет лучшим решением сделать его глобальным. В этом случае, если вы определяете глобальный (только в этом файле), вы должны попробовать модификатор static. Здесь вы можете прочитать о статических (это может иметь 2 различных значения)

2. Я думаю, что ваш второй вопрос "Наличие входных и выходных данных как параметров - это сбивает с толку?" на самом деле это зависит от разработчика, язык дает вам оба варианта, но это зависит от вас, чтобы сделать ясный код.

0 голосов
/ 25 января 2012

Глобальные переменные также не рекомендуются в Си. Что я могу понять из вашего вопроса, так это то, что foo1 создаст структуру, а foo2 примет ее в качестве входных данных.

Так что, по моему мнению, вы должны заставить foo1 возвращать структуру, а затем передать всю структуру в качестве параметра в foo2

0 голосов
/ 25 января 2012

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

Вот пример кода, который я написал, он касается работы со структурами. здесь только объявления функций, но вы понимаете,

struct elem {
    void *data;
    struct elem *next;
};

struct binky {
    struct elem *root;
    int elem_size;
};

void Initialize(struct binky * b, int elem_size);
int add(struct binky * b, const void * data);
void *get(const struct binky * b, const void * data);
void freeMap(struct binky * b);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...