проблема объявления переменной внутри структуры - PullRequest
0 голосов
/ 15 октября 2010

Я объявил нормальную структуру в C:

typedef struct arr_struct{  

 int* original;  
 int size;        
 int first[size/2];  
 int second[size-(size/2)];  
};  

при компиляции, это дает мне:

test.c: 11: ошибка: здесь не указано «размер» (нев функции)

есть объяснения?

Ответы [ 5 ]

4 голосов
/ 15 октября 2010

Вы не можете определять массивы на основе переменного размера.Размер должен быть известен во время компиляции.Вам нужно будет создать указатели first и second и динамически распределить их, когда станет известно size.

1 голос
/ 15 октября 2010

Вы получаете сообщение об ошибке, потому что пытаетесь использовать элемент size структуры незаконно.Во-первых, определение типа структуры не завершено до закрывающего }, поэтому до тех пор компилятор не знает, что в структуре есть член size.С другой стороны, вы не можете ссылаться на член структуры без экземпляра структуры;когда вы использовали выражение size для объявления first и second, компилятор искал переменную с именем size вне определения структуры.

можно использовать VLA в типе структуры, но на самом деле это не тот подход, который вы хотели бы использовать здесь, если вы делаете то, что я думаю, вы делаете.Лучше сделать указатели first и second на int и распределить их по мере необходимости (как продемонстрировано парой ответов выше).

1 голос
/ 15 октября 2010
int val;
scanf("%d",&val);
int a[val];

Приведенный выше код фактически компилируется и запускается в моем компиляторе gcc.

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

0 голосов
/ 15 октября 2010

Размер, который вы указываете для массива, должен быть константным выражением.У вас есть пара вариантов.Можно было бы включить пару указателей и динамически распределить пространство:

typedef struct {
    int* original;
    int size;
    int *first;
    int *second;
} arr_struct; 

Другая возможность состояла бы в том, чтобы использовать только один массив и создать в нем указатель на соответствующую точку:

typedef struct { 
    int* original;
    int size;
    int *second;
    int first[];
} arr_struct; 

При этом используется гибкий элемент массива, новый для C99 - если вы используете устаревший компилятор C (например, MS VC ++), он может не поддерживаться напрямую 1 .В любом случае это все еще требует динамического выделения, но позволяет вам сделать одно большое выделение для всех данных вместо трех отдельных выделений (одно для структуры и по одному для first и second).

arr_struct *my_struct = malloc(sizeof(*my_struct) + size * sizeof(int));
my_struct->second = my_struct->first + size/2;

Кроме того, обратите внимание на синтаксис для typedef - так как ваш typedef вообще не определял имя.

1 Обходной путьтривиально, хотя - просто определите first с размером 1 и вычтите 1 из размера в вашем распределении:

arr_struct *my_struct = malloc(sizeof(*my_struct) + (size-1) * sizeof(int));

Теоретически это не обязательно работает, но на самом деле это просто хорошовсе настоящие компиляторы, как минимум AFAIK.

0 голосов
/ 15 октября 2010

Реализация и использование того, что сказал miked, может быть (без проверки ошибок):

typedef struct
{
   int size;
   int* first;
   int* second;
} arr_struct;

// Prepare an arr_struct for use.
arr_struct foo;
foo.size = 1337;
foo.first = malloc(sizeof(int)*foo.size);
foo.second = malloc(sizeof(int)*(foo.size-foo.size/2));

Не забудьте free(foo.first) и free(foo.second), когда вы закончите, хотя!

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