web-dev-qa-db-fra.com

C typedef du pointeur vers la structure

J'étais tombé sur le code suivant:

typedef struct {
        double x;
        double y;
        double z;
} *vector;

Est-ce une définition de type valide? Le code se compile et s'exécute correctement. J'étais simplement curieux de savoir si c'était une pratique courante.

35
user187174

Absolument valable. Habituellement, vous pouvez tirer pleinement parti de cette méthode en définissant deux types ensemble:

typedef struct
{
 int a;
 int b;
} S1, *S1PTR;

Où S1 est une structure et S1PTR est le pointeur vers cette structure.

55
alexkr

Oui, ça l'est. Mais c'est à mon humble avis un mauvais style. Pas la déclaration directe de la structure, mais la déclaration directe d'un type de pointeur. Il s'agit d'obscurcissement, l'information selon laquelle une variable ou un paramètre donné est un pointeur (et dans une moindre mesure pour les tableaux) est extrêmement importante lorsque vous souhaitez lire du code.

Lors de l'examen du code, il est souvent difficile de voir à première vue quelle fonction peut avoir un effet secondaire ou non. Si les types utilisés masquent ces informations, cela ajoute un fardeau de mémorisation au lecteur.

int do_fancy(vector a, vector b); 

ou

int do_fancy(vector *a, vector *b);

dans le premier cas, je peux facilement manquer que cette fonction puisse changer le contenu de a ou b. Dans la seconde, je suis prévenu.

Et lorsque j'écris du code, je sais aussi directement écrire a->x et que le compilateur ne me dise pas error: request for memberx 'dans quelque chose qui n'est pas une structure ou une union'.

Je sais, cela ressemble à une chose de goût personnel, mais après avoir travaillé avec beaucoup de code externe, je peux vous assurer que c'est extrêmement ennuyeux lorsque vous ne reconnaissez pas le niveau d'indirection des variables. C'est une des raisons pour lesquelles je n'aime pas non plus les références C++ (dans Java ce n'est pas parce que tous les objets sont passés par référence, c'est cohérent) et les types de types LPCSTR de Microsoft.

25
Patrick Schlüter

Il est valide, il définit un nouveau type. Comme l'a dit @Alex, il serait utile de définir un type et un type de pointeur.

Vous pouvez créer plus de pointeurs simplement en utilisant

S1PTR ptr1, ptr2, ptr3, ...;  

au lieu de

S1 *ptr1, *ptr2, *ptr3, ...;
2
Siva

Oui, il est valide comme décrit dans les réponses ci-dessus. Une petite suggestion, il serait préférable que vous fournissiez également un nom de balise, comme suit. Cela aiderait certains IDE à mieux analyser votre code.

typedef struct vactor_tag {
        double x;
        double y;
        double z;
} *vector;
1
FIFO