web-dev-qa-db-fra.com

tableau de longueur fixe typedef

Je dois définir un type de données 24 bits. J'utilise char[3] pour représenter le type. Puis-je taper char[3] sur type24? Je l'ai essayé dans un exemple de code. Je mets typedef char[3] type24; dans mon fichier d'en-tête. Le compilateur ne s'en est pas plaint. Mais lorsque j'ai défini une fonction void foo(type24 val) {} dans mon fichier C, il s'est plaint. J'aimerais pouvoir définir des fonctions telles que type24_to_int32(type24 val) au lieu de type24_to_int32(char value[3]).

190
341008

Le typedef serait

typedef char type24[3];

Cependant, c'est probablement une très mauvaise idée, car le type résultant est un type de tableau, mais ses utilisateurs ne verront pas qu'il s'agit d'un type de tableau. S'il est utilisé comme argument de fonction, il sera passé par référence, pas par valeur, et la sizeof sera alors fausse.

Une meilleure solution serait

typedef struct type24 { char x[3]; } type24;

Vous voudrez probablement aussi utiliser unsigned char au lieu de char, car ce dernier possède une signature définie par l'implémentation.

283
R..

Tu veux

typedef char type24[3];

Les déclarations de type C sont étranges de cette façon. Vous mettez le type exactement là où le nom de la variable irait si vous déclariez une variable de ce type.

41
ysth

De réponse de R .. :

Cependant, c'est probablement une très mauvaise idée, car le type résultant est un type de tableau, mais ses utilisateurs ne verront pas qu'il s'agit d'un type de tableau. S'il est utilisé comme argument de fonction, il sera passé par référence, pas par valeur, et la taille de cet argument sera alors fausse.

Les utilisateurs qui ne voient pas qu'il s'agit d'un tableau écriront probablement quelque chose comme ceci (qui échoue):

#include <stdio.h>

typedef int twoInts[2];

void print(twoInts *twoIntsPtr);
void intermediate (twoInts twoIntsAppearsByValue);

int main () {
    twoInts a;
    a[0] = 0;
    a[1] = 1;
    print(&a);
    intermediate(a);
    return 0;
}
void intermediate(twoInts b) {
    print(&b);
}

void print(twoInts *c){
    printf("%d\n%d\n", (*c)[0], (*c)[1]);
}

Il compilera avec les avertissements suivants:

In function ‘intermediate’:
warning: passing argument 1 of ‘print’ from incompatible pointer type [enabled by default]
    print(&b);
     ^
note: expected ‘int (*)[2]’ but argument is of type ‘int **’
    void print(twoInts *twoIntsPtr);
         ^

Et produit la sortie suivante:

0
1
-453308976
32767
27
Gerhard Burger

Les tableaux ne peuvent pas être passés comme paramètres de fonction par valeur en C.

Vous pouvez mettre le tableau dans une structure:

typedef struct type24 {
    char byte[3];
} type24;

puis passez cela par valeur, mais bien sûr, il est moins pratique d’utiliser: x.byte[0] au lieu de x[0].

Votre fonction type24_to_int32(char value[3]) passe en fait par pointeur, pas par valeur. C'est exactement équivalent à type24_to_int32(char *value), et le 3 est ignoré.

Si vous êtes content de passer par un pointeur, vous pourriez coller avec le tableau et faire:

type24_to_int32(const type24 *value);

Cela transmettra un pointeur à un tableau, pas un pointeur au premier élément, de sorte que vous l'utilisez comme:

(*value)[0]

Je ne suis pas sûr que ce soit vraiment un avantage, car si vous écrivez accidentellement value[1], il se produit alors quelque chose de stupide.

11
Steve Jessop

Pour utiliser correctement le type de tableau en tant qu'argument de fonction ou paramètre de modèle, créez une structure au lieu d'un typedef, puis ajoutez un operator[] à la structure afin que vous puissiez conserver la fonctionnalité du tableau comme suit:

typedef struct type24 {
  char& operator[](int i) { return byte[i]; }
  char byte[3];
} type24;

type24 x;
x[2] = 'r';
char c = x[2];
11
Geronimo