Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Question de débutant

16 réponses
Avatar
Tanguy Briançon
Bonjour,

int c;

struct points {
float x;
float y;
char couleur;
char *nom;
char *type;
char visible;
};

typedef struct points point;

point points[20];


Je fais

char *t;
t=points[c].type;
puis je veux faire quelque
chose avec points[*t].x je me fais
jeter par le compilateur (gcc). Par contre si je fais

char *t;
int p;
t=points[c].type;
p=*t;
puis je peux faire quelque
chose avec points[p].x Aucun problème...

Une explication?

6 réponses

1 2
Avatar
Samuel DEVULDER
Le 25/09/2010 07:47, Tanguy Briançon a écrit :
On 24/09/2010 15:23, Samuel DEVULDER wrote:
Le 23/09/2010 19:30, Tanguy Briançon a écrit :

Mon problème est le suivant: pour chaque point je voulais pouvoir
disposer de mémoire, plus ou moins grande, pour stocker des choses
variées (des indices, des réels, etc...). Donc un *char me semblait
une solution...



Pourquoi ne pas utiliser void* plutot que char*? Il est peut-être
possible de structurer ces choses variées en utilisant une union
contenant un double*, int*, etc. L'union évitera les casts et sera
beaucoup plus propre.

sam.


Pourquoi pas? C'est juste que je ne comprend pas de quoi vous
parlez...(Voir le sujet de la discussion...).



Void* veut dire pointeur sur n'importe quoi. C'est plus général que
char* et il n'y a pas besoin de cast pour le convertir en double*, int*,
etc.

struct points {
...
char *type; // pointeur sur char
...
} p;

double *dbl_ptr = (double*)p.type;
double value = ((double*)p.type)[15];

Comme tu le vois il te faut caster la valeur de p.type pour la convertir
en pointeur sur double. L'accès au 16eme element du tableau utilise
aussi un cast.

Maintenant avec un pointeur sur void:

struct points {
...
void *type; // pointeur banalisé
...
} p;

double *dbl_ptr = p.type; // pas de cast!
double value = ((double*)p.type)[15];

Comme tu le vois la conversion en double* est automatique, pas besoin de
cast. Par contre il faut toujours un cast pour acceder à l'index 15.

Enfin, avec une union:

struct points {
...
union {
double* as_double;
int* as_double;
unsigned char* as_byte;
} type;
...
} p;

double *dbl_ptr = p.type.as_double; // pas de cast
double value = p.type.as_double[15]; // pas de cast

Aucun cast et le code est beaucoup plus clair.

sam.
Avatar
Éric Lévénez
Le 25/09/10 10:51, Tanguy Briançon a écrit :

struct points {
float x;
float y;
char couleur;
char *nom;
char *type;
char visible;
};

typedef struct points point;

Pour moi le type est point (sans s). Je reconnais que ce n'est
pas très joli...



Si ce n'est pas joli et si tu le sais, pourquoi le faire ?

Autre solution :

typedef struct {
float x;
float y;
char couleur;
char *nom;
char *type;
char visible;
} point;


--
Éric Lévénez
FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Avatar
Tanguy Briançon
On 25/09/2010 15:33, Éric Lévénez wrote:
Le 25/09/10 10:51, Tanguy Briançon a écrit :

struct points {
float x;
float y;
char couleur;
char *nom;
char *type;
char visible;
};

typedef struct points point;

Pour moi le type est point (sans s). Je reconnais que ce n'est
pas très joli...



Si ce n'est pas joli et si tu le sais, pourquoi le faire ?



Ca marche...

Autre solution :

typedef struct {
float x;
float y;
char couleur;
char *nom;
char *type;
char visible;
} point;





Je ne savais pas qu'on pouvait faire ça...
Merci de l'info en tout cas!
Avatar
Samuel DEVULDER
Le 25/09/2010 16:22, Tanguy Briançon a écrit :

Je ne savais pas qu'on pouvait faire ça...



Oui la structure est anonyme.. C'est la même chose pour l'union que je
t'avais indiqué pour éviter les casts avec "type":

typedef struct {
float x;
float y;
char couleur;
char *nom;
union /* pas de nom */ {
char* as_char;
unsigned char* as_byte;
int* as_int;
double* as_double;
} type;
char visible;
} point;

sam.
Avatar
-ed-
On 25 sep, 11:01, Samuel DEVULDER
com> wrote:
Void* veut dire pointeur sur n'importe quoi. C'est plus général que
char* et il n'y a pas besoin de cast pour le convertir en double*, int*,
etc.



void * pointe sur n'importe quelle *donnée*.
.
Avatar
Marc Boyer
Le 25-09-2010, Tanguy Briançon a écrit :
On 25/09/2010 15:33, Éric Lévénez wrote:
Le 25/09/10 10:51, Tanguy Briançon a écrit :

struct points {
float x;
float y;
char couleur;
char *nom;
char *type;
char visible;
};

typedef struct points point;

Pour moi le type est point (sans s). Je reconnais que ce n'est
pas très joli...



Si ce n'est pas joli et si tu le sais, pourquoi le faire ?



Ca marche...



Tu peux remplacer tous tes noms de type par t1, t2, t3 et tous
tes noms de variable par v1, v2, v3, et ça continuera de marcher.

C'est toute l'ambiguité d'un code qui est fait pour une machine
(faut que ça marche) et pour l'humain (faut le relire).

Je ne savais pas qu'on pouvait faire ça...
Merci de l'info en tout cas!



On peut aussi utiliser le même "nom"
struct point {
int x,y;
};
typedef struct point point;
ou tout faire d'un coup
typedef struct point {
int x,y;
} point ;


Marc Boyer
--
En prenant aux 10% des francais les plus riches 12% de leurs revenus,
on pourrait doubler les revenus des 10% les plus pauvres.
http://www.inegalites.fr/spip.php?article1&id_mot0
1 2