2010-10-15 4 views
0

I a déclaré une structure normale en C:problème de déclaration variable à l'intérieur struct

typedef struct arr_struct{ 

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

quand compiler me donne:

test.c:11: error: ‘size’ undeclared here (not in a function)

une explication?

+0

J'aime 'size- (size/2)' pour les tailles impaires! :-) – pmg

+0

@pmg: merci: D – Aboelnour

+1

qu'en (taille + 1)/2 ?? –

Répondre

1

Vous recevez le message d'erreur parce que vous essayez d'utiliser le membre size de la structure illégalement. D'une part, la définition de type struct n'est pas complète jusqu'à la fermeture }, donc jusque-là le compilateur ne sait pas qu'il y a un membre size dans la structure.D'autre part, vous ne pouvez pas faire référence à un membre struct sans une instance struct; Lorsque vous avez utilisé l'expression size les déclarants pour first et second, le compilateur recherchait une variable nommée sizeen dehors de de la définition de structure.

est possible d'utiliser un VLA dans un type struct, mais ce n'est vraiment pas l'approche que vous voulez prendre ici si vous faites ce que je pense que vous faites. Il est préférable de placer les pointeurs first et second sur int et de les allouer si nécessaire (comme démontré par quelques réponses ci-dessus).

4

Vous ne pouvez pas définir de tableaux en fonction d'une taille variable. La taille doit être connue au moment de la compilation. Vous devez créer des pointeurs first et second et les allouer dynamiquement une fois que size est connu.

+0

En fait, vous pouvez avoir des tableaux basés sur une taille variable, mais il semble qu'il ne s'applique pas à l'intérieur d'une structure. –

+0

dans gcc cela fonctionne – Aboelnour

+0

Oui, je me souviens de quelque chose dans C99 sur les tableaux de taille variable. Mais la dernière fois que j'ai fait de la programmation pure en C (pas en C++), j'étais sur un compilateur non-conforme donc je ne les ai jamais utilisés en pratique. – miked

1
int val; 
scanf("%d",&val); 
int a[val]; 

Le code ci-dessus se compile et s'exécute dans mon compilateur gcc. La raison de ne pas travailler à l'intérieur d'une structure peut être due à l'alignement des éléments à l'intérieur d'une structure dont la taille ne peut pas être déterminée au moment de la compilation. Je ne suis pas entièrement sûr à ce sujet cependant.

0

Une mise en œuvre et l'utilisation de ce que pourrait être miked dit (sans vérification d'erreur):

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)); 

rappelez-vous de free(foo.first) et free(foo.second) lorsque vous avez terminé, bien!

+0

j'ai fait cette solution mais je demandais une explication merci :) – Aboelnour

0

La taille que vous fournissez pour un tableau doit être une expression constante. Vous avez deux choix. On serait d'inclure quelques pointeurs et allouer l'espace dynamique:

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

Une autre possibilité serait d'utiliser un seul tableau, et de créer un pointeur au point approprié dans ce:

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

Cela utilise un membre de groupe flexible, ce qui est nouveau avec C99 - si vous utilisez un compilateur C obsolète (par exemple, MS VC++) il peut ne pas être pris en charge directement . Dans tous les cas, cela nécessite toujours une allocation dynamique, mais vous permet de faire une allocation importante pour toutes les données au lieu de trois allocations distinctes (une pour la structure et une pour chaque first et second).

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

En aparté, notez la syntaxe pour typedef - comme il était, votre typedef ne définissait pas un nom du tout.

La solution est triviale si - il suffit de définir first avec une taille de 1 et soustrayez 1 de la taille de votre allocation:

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

En théorie, ce n'est pas nécessaire de travailler, mais En fait, c'est très bien avec tous les vrais compilateurs, au moins AFAIK.

+0

Ce n'est pas un VLA, c'est un type de tableau * incomplet *. Il y a une différence. –

+0

@ John Bode: bien, à moitié à droite quand même. Merci d'avoir attiré mon attention sur le bordereau - j'ai édité le bon terme. –