c синтаксическая ошибка в общих переменных между разными .c файлами - PullRequest
3 голосов
/ 21 мая 2019

Возможно, я столкнулся с проблемой синтаксиса в c. У меня есть main.c и test.c Я пытаюсь использовать общие переменные.
файл main.c

extern int a;
extern int b;
uint8_t matrix[(a+1)*b][4];
testFunction(matrix, 10)

файл test.c

int a=1;
int b=2;
void testFunction(matrix[(a+1)*b][4], uint8_t z){
....}

Если я скомпилирую, я получаю сообщение об ошибке «изменено в области видимости». Я изменяю a + 1 на main.c на 2 и получаю ошибку множественных определений. Есть предложения?

Ответы [ 3 ]

3 голосов
/ 21 мая 2019

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

void testFunction (int x, int y, uint8_t matrix[x][y]);

Выполнить вычисление x и y в вызывающей стороне, а не как часть объявления функции.

(* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * .

1 голос
/ 21 мая 2019

Изменяемый массив в области видимости файла невозможен. В этом случае компилятор uint8_t matrix[(a+1)*b][4] не может определить значения a и b при генерации объектного файла. Даже если это возможно, это все еще проблема, так как массив предоставляется в начале в статической памяти, и переменные могут меняться в любое время. Однако вы можете иметь переменно модифицированный массив в blockcope.

Не уверен насчет ваших точных требований, но решением вашей проблемы в C99 может быть объявление testFunction как:

void testFunction(int x, uint8_t matrix[x][4], uint8_t z) { ... }

И назовите это как:

#define AVAL 1
#define BVAL 2
int a= AVAL;
int b= BVAL;
uint8_t matrix[(AVAL+1)*BVAL][4];
testFunction((a+1)*b, matrix, 10);
0 голосов
/ 21 мая 2019

Если размер вашей матрицы известен во время компиляции, то вы можете определить его как глобальный объект, но его размеры должны быть известны (C целочисленные константы ), где он определен.Если test.c знает размеры, он может определить матрицу, например:

#define a 1
#define b 2
uint8_t matrix[(a+1)*b][4];

Тогда к матрице можно обратиться в main.c, объявив (но не определив) ее там:

extern uint8_t matrix[][4];

Если main.c также необходимо знать a и b, вы можете поместить эти значения в глобальные объекты, хотя вам нужно будет использовать другие имена для этих объектов, чем для макросов препроцессора, которые я показал выше,(Технически существует способ использовать одни и те же имена для обоих, но это обычно не рекомендуется.)

Если размер вашей матрицы известен во время выполнения, а не во время компиляции, то вы можете создать егоиспользуя malloc.Например, в main.c вы могли бы иметь:

extern uint8_t (*matrix)[4];

int main(void)
{
    … Ensure the values of a and b have been set.

    matrix = malloc((a+1)*b * sizeof *matrix);
    if (!matrix) … Handle error

    … Rest of program.

    free(matrix); // (Not strictly necessary in typical multi-user systems.)
}

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

int main(void)
{
    … Ensure the values of a and b have been set.

    uint8_t (*matrix)[4] = malloc((a+1)*b * sizeof *matrix);
    if (!matrix) … Handle error

    testFunction(matrix, z);
    … Rest of program.

    free(matrix); // (Not strictly necessary in typical multi-user systems.)
}

Также можно определить матрицу внутри main:

int main(void)
{
    … Ensure the values of a and b have been set.

    uint8_t matrix[(a+1)*b)][4];

    testFunction(matrix, z);
    … Rest of program.
}

Однако,это следует использовать, только если известно, что a и b малы.Ресурсы, доступные для предоставления определений массива в рамках блока, как это, весьма ограничены в большинстве реализаций Си.

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