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?

10 réponses

1 2
Avatar
Samuel DEVULDER
Le 18/09/2010 23:37, Tanguy Briançon a écrit :

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

Une explication?



*t est un char, or GCC n'aime pas les indexation par des char. Ca peut
poser des pbs de portabilité je crois (char est parfois signé, parfois
pas). Par contre:

t = point[255 & *t].x

devrait mieux passer. Ce cas marche indépendamment du fait que *t soit
signé ou pas, et qu'on souhaite un indexe entre 0 et 255 (donc >=0). Si
on veut un indexe entre -128 et 127, alors on doit pouvoir faire quelque
chose du genre:

t = point[(int)(signed char)*t].x

Mais les indexes négatifs sont rarement utilisés en pratique et la
construction avec un masque à 255 est ce qu'on retrouve habituellement.

sam.
Avatar
Marc Boyer
Le 18-09-2010, Tanguy Briançon a écrit :
Bonjour,

int c;

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



Pourquoi un pluriel à ton nom de type ?

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



Jeter ? Moi il me dit juste
warning: array subscript has type ‘char’

Le fait est que char est parfois signé, parfois non... Et souvent, cela
n'est pas connu des programmeurs.
En fait, si tu explicites ton intention (avec un signed char ou un
unsigned char), le compilo ne dit plus rien.

Ceci dit, il semble bizarre ton code. C'est quoi ce char* qui code le type ?
C'est une chaine de caractère ? Si oui, pourquoi utiliser le premier caractère
comme indice ?

Idem avec tes couleurs. Est-ce que char est le bon type ? Tu veux un type
énuméré ou un codade de couleur 8bits (et autant utiliser un unsigned char
il me semble).

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
Avatar
Marc Boyer
Le 18-09-2010, Samuel DEVULDER a écrit :
Le 18/09/2010 23:37, Tanguy Briançon a écrit :

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


>
> Une explication?

*t est un char, or GCC n'aime pas les indexation par des char. Ca peut
poser des pbs de portabilité je crois (char est parfois signé, parfois
pas). Par contre:

t = point[255 & *t].x

devrait mieux passer. Ce cas marche indépendamment du fait que *t soit
signé ou pas, et qu'on souhaite un indexe entre 0 et 255 (donc >=0).



D'une part, tu fais l'hypothèse d'une machine en complément à deux
(mais ça reste raisonnable comme hypothèse).
Après, si sizeof(char) == sizeof(int), je ne garantirais pas
le résultat pour un *t négatif (faudrait regarder la norme).

Enfin, tout ça pour éviter un warning qui vient du fait que
la déclaration est semble-t-il mauvaise.

on veut un indexe entre -128 et 127, alors on doit pouvoir faire quelque
chose du genre:

t = point[(int)(signed char)*t].x



Autant déclarer directement t comme un
unsigned char*

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
Avatar
Tanguy Briançon
On 20/09/2010 10:47, Marc Boyer wrote:
Le 18-09-2010, Tanguy Briançon a écrit :
Bonjour,

int c;

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



Pourquoi un pluriel à ton nom de type ?



Pourquoi pas?
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



Jeter ? Moi il me dit juste
warning: array subscript has type ‘char’



Oui bien sur mais comme je n'y connais pas grand chose en C je veux
essayer d'éviter au maximum les avertissements...

Le fait est que char est parfois signé, parfois non... Et souvent, cela
n'est pas connu des programmeurs.


C'est mon cas...

En fait, si tu explicites ton intention (avec un signed char ou un
unsigned char), le compilo ne dit plus rien.



Ok merci...

Ceci dit, il semble bizarre ton code. C'est quoi ce char* qui code le type ?
C'est une chaine de caractère ? Si oui, pourquoi utiliser le premier caractère
comme indice ?


type n'est pas une chaine de caractère au sens strict du terme:
je m'en sers pour stocker des données associées à chaque point:
le premier "caractère" me donne le type de point et les deuxième,
troisième des infos (qui sont souvent un indice vers un tableau...).


la
Idem avec tes couleurs. Est-ce que char est le bon type ? Tu veux un type
énuméré ou un codade de couleur 8bits (et autant utiliser un unsigned char
il me semble).

Marc Boyer



A priori pour la couleur les fonctions que j'utilise sont déclarées
en demandant un char donc j'ai mis un char sans réfléchir...
couleur ne peut contenir que 0x00,0x11,...,0xFF (16 couleurs donc).

Je précise que mon programme n'est destiné qu'aux calculatrices
hp49g+/hp50 où la mémoire est très limitées. Je me suis mis
au C (via un petit livre de poche...) que pour continuer à programmer
ma calculatrice (avant je le faisais en assembleur sur un processeur 4
bits) maintenant le processeur est un ARM et il existe les librairies
qui vont bien pour programmer la calculatrice en C...

Tanguy Briançon

Bien sur pour moi programmer ma calculatrice est un loisir
(ce n'est pas plus idiot que de faire des mots croisés ou des
sudokus...)
Avatar
Marc Boyer
Le 23-09-2010, Tanguy Briançon a écrit :
On 20/09/2010 10:47, Marc Boyer wrote:
Le 18-09-2010, Tanguy Briançon a écrit :
Bonjour,

int c;

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



Pourquoi un pluriel à ton nom de type ?



Pourquoi pas?



Ben, parce que le nom d'un type doit correspondre à sa sémantique,
et que je vois rien dans ta déclaration qui spécifie que cela désigne
plusieurs points.

Jeter ? Moi il me dit juste
warning: array subscript has type ‘char’



Oui bien sur mais comme je n'y connais pas grand chose en C je veux
essayer d'éviter au maximum les avertissements...



Bonne démarche.

Le fait est que char est parfois signé, parfois non... Et souvent, cela
n'est pas connu des programmeurs.


C'est mon cas...

En fait, si tu explicites ton intention (avec un signed char ou un
unsigned char), le compilo ne dit plus rien.



Ok merci...

Ceci dit, il semble bizarre ton code. C'est quoi ce char* qui code le type ?
C'est une chaine de caractère ? Si oui, pourquoi utiliser le premier caractère
comme indice ?


type n'est pas une chaine de caractère au sens strict du terme:
je m'en sers pour stocker des données associées à chaque point:
le premier "caractère" me donne le type de point et les deuxième,
troisième des infos (qui sont souvent un indice vers un tableau...).



Et est-ce bien utile d'en faire un pointeur dans ce cas ?
Est-ce une information partagée ?
Et en plus un pointeur sur un tableau de char, c'est un peu brut
comme information. Pourquoi ne pas faire un type spécifique ?

Idem avec tes couleurs. Est-ce que char est le bon type ? Tu veux un type
énuméré ou un codade de couleur 8bits (et autant utiliser un unsigned char
il me semble).



A priori pour la couleur les fonctions que j'utilise sont déclarées
en demandant un char donc j'ai mis un char sans réfléchir...
couleur ne peut contenir que 0x00,0x11,...,0xFF (16 couleurs donc).



Si c'est l'API qui l'impose, en effet.

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
Avatar
Tanguy Briançon
On 23/09/2010 15:09, Marc Boyer wrote:
Le 23-09-2010, Tanguy Briançon a écrit :
On 20/09/2010 10:47, Marc Boyer wrote:
Le 18-09-2010, Tanguy Briançon a écrit :
Bonjour,

int c;

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



Pourquoi un pluriel à ton nom de type ?



Pourquoi pas?



Ben, parce que le nom d'un type doit correspondre à sa sémantique,
et que je vois rien dans ta déclaration qui spécifie que cela désigne
plusieurs points.



Certes...
Comme je débute en C (et que ce n'est pour moi qu'un loisir...) mon code
est surement bourré de "fautes" de ce genre...


Jeter ? Moi il me dit juste
warning: array subscript has type ‘char’



Oui bien sur mais comme je n'y connais pas grand chose en C je veux
essayer d'éviter au maximum les avertissements...



Bonne démarche.



J'ai déja des bugs sans avertissements, il me semble qu'avec
des avertissements cela va être pire...

Le fait est que char est parfois signé, parfois non... Et souvent, cela
n'est pas connu des programmeurs.


C'est mon cas...

En fait, si tu explicites ton intention (avec un signed char ou un
unsigned char), le compilo ne dit plus rien.



Ok merci...

Ceci dit, il semble bizarre ton code. C'est quoi ce char* qui code le type ?
C'est une chaine de caractère ? Si oui, pourquoi utiliser le premier caractère
comme indice ?


type n'est pas une chaine de caractère au sens strict du terme:
je m'en sers pour stocker des données associées à chaque point:
le premier "caractère" me donne le type de point et les deuxième,
troisième des infos (qui sont souvent un indice vers un tableau...).



Et est-ce bien utile d'en faire un pointeur dans ce cas ?
Est-ce une information partagée ?
Et en plus un pointeur sur un tableau de char, c'est un peu brut
comme information. Pourquoi ne pas faire un type spécifique ?




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...

Idem avec tes couleurs. Est-ce que char est le bon type ? Tu veux un type
énuméré ou un codade de couleur 8bits (et autant utiliser un unsigned char
il me semble).



A priori pour la couleur les fonctions que j'utilise sont déclarées
en demandant un char donc j'ai mis un char sans réfléchir...
couleur ne peut contenir que 0x00,0x11,...,0xFF (16 couleurs donc).



Si c'est l'API qui l'impose, en effet.

Marc Boyer



Tanguy Briançon
Avatar
Marc Boyer
Le 23-09-2010, Tanguy Briançon a écrit :
On 23/09/2010 15:09, Marc Boyer wrote:
Le 23-09-2010, Tanguy Briançon a écrit :
On 20/09/2010 10:47, Marc Boyer wrote:
Le 18-09-2010, Tanguy Briançon a écrit :
Bonjour,

int c;

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



Pourquoi un pluriel à ton nom de type ?



Pourquoi pas?



Ben, parce que le nom d'un type doit correspondre à sa sémantique,
et que je vois rien dans ta déclaration qui spécifie que cela désigne
plusieurs points.



Certes...
Comme je débute en C (et que ce n'est pour moi qu'un loisir...) mon code
est surement bourré de "fautes" de ce genre...



On a tous déclaré une variable toto ou un type truc. Mais quand il
faut relire, l'évidence du moment a disparu, et on se dit "mais, qu'est-ce
que c'est ?"

Ceci dit, il semble bizarre ton code. C'est quoi ce char* qui code le type ?
C'est une chaine de caractère ? Si oui, pourquoi utiliser le premier caractère
comme indice ?


type n'est pas une chaine de caractère au sens strict du terme:
je m'en sers pour stocker des données associées à chaque point:
le premier "caractère" me donne le type de point et les deuxième,
troisième des infos (qui sont souvent un indice vers un tableau...).



Et est-ce bien utile d'en faire un pointeur dans ce cas ?
Est-ce une information partagée ?
Et en plus un pointeur sur un tableau de char, c'est un peu brut
comme information. Pourquoi ne pas faire un type spécifique ?




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...



Disons que la zone de sockage pour "choses variées", ça ressemble
de loin à la fausse bonne idée. Mais il y a peut-être de bonnes raisons
de faire comme ça.

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
Avatar
Samuel DEVULDER
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.
Avatar
Tanguy Briançon
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...).

Tanguy
Avatar
Tanguy Briançon
On 24/09/2010 14:33, Marc Boyer wrote:

On a tous déclaré une variable toto ou un type truc. Mais quand il
faut relire, l'évidence du moment a disparu, et on se dit "mais, qu'est-ce
que c'est ?"



J'ai fait

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... En plus j'ai une variable points qui est un tableau
de point




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...



Disons que la zone de sockage pour "choses variées", ça ressemble
de loin à la fausse bonne idée. Mais il y a peut-être de bonnes raisons
de faire comme ça.

Marc Boyer



Disons que pour moi un *char c'est un peu comme écrire directement
en mémoire comme je le faisais en assembleur. J'ai une fonction qui
prend tout les points et recopie leur champs type sans poser de
question...
1 2