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

pointeur sur structure

27 réponses
Avatar
Québec
struct maStructure{
char data;
struct maStructure;
};
typedef maStructure MaStructure;
typedef MaStructure *MaStructure;

versFonction(& MaStructure);

Fonction(* MaStructure)

Et voici la question:

* MaStructure déréférence quoi? Quelle valeur?

data?


Jean Pierre

10 réponses

1 2 3
Avatar
Anthony Fleury
Québec wrote:

En général, mes posts comportent un bonjour,

mais pour comprendre
l'intêret de ce struct ListNode**,
Je ne voyais pas ce 'pointeur sur pointeur'

En général déjà il est déconseillé, sauf quand on sait vraiment ce qu'on

fait et qu'on documente bien son code, de cacher des pointeurs dans un
typedef, ca obscurci le code et sa lecture. Mais dans ce cas, tu avais ca :

typedef struct listNode ListNode;
typedef ListNode *ListNodePtr;


et tu cherchais à savoir ce qu'est un ListNodePtr*.

Il suffit tout simplement dans des cas comme ca de remonter les différents
typedefs, sachant que tu pars toujours du plus bas, car tout ce qu'un
typedef utilise doit être déjà connu avant.

Donc, ListNodePtr* se transforme car ListNodePtr c'est un ListNode* donc
ListNodePtr* <==> ListNode**
Ensuite ListNode se transforme en struct listNode, donc ListNodePtr* <==>
struct listNode**

Anthony
--
Alan Turing thought about criteria to settle the question of whether
machines can think, a question of which we now know that it is about as
relevant as the question of whether submarines can swim.
-- Dijkstra


Avatar
Anthony Fleury
Québec wrote:

Et si je n'étais pas québécois?


Avec un francais tel que celui ci :

"Et ça, s'tu t'un gag?"

C'est quand même trop visible ! (plus traitre qu'un accent encore)

Par contre si tu pouvais répondre _en dessous_ de ce à quoi tu réponds, ca
serait bien !

Anthony
--
Alan Turing thought about criteria to settle the question of whether
machines can think, a question of which we now know that it is about as
relevant as the question of whether submarines can swim.
-- Dijkstra

Avatar
Pierre Maurette
Anthony Fleury a écrit:

Québec wrote:

En général, mes posts comportent un bonjour,

mais pour comprendre
l'intêret de ce struct ListNode**,
Je ne voyais pas ce 'pointeur sur pointeur'

En général déjà il est déconseillé, sauf quand on sait vraiment ce qu'on

fait et qu'on documente bien son code, de cacher des pointeurs dans un
typedef, ca obscurci le code et sa lecture. Mais dans ce cas, tu avais ca :

typedef struct listNode ListNode;
typedef ListNode *ListNodePtr;


et tu cherchais à savoir ce qu'est un ListNodePtr*.
(Je passe sur le post initial)

En général, le choix est laissé entre :
tipe * Var;
tipe* Var;
tipe *Var;

- Le premier préfère ne pas se prononcer.
- Le second est celui que je préfère. Var est un (type*).
- Le troisième est ambiguë par rapport à * opérateur de
déréférencement. Effectivement, (*Var) a pour type tipe.

Le problème de la seconde écriture est la tentation d'écrire:

tipe* Var1, Var2; // erreur probable

Dans le cas du typedef, ce danger disparait, et il me semble que la
meilleure écriture est:

typedef tipe* ptipe;

puisqu'on définit un type ptipe équivalent à tipe*.

D'autant que ça permet de corriger le problème évoqué précédemment:

ptipe Var1, Var2;

A partir du moment où on écrit les typedef de cette manière, et où on
ne nomme pas les types utilisateur n'importe comment, ça devient plus
facile à suivre:

typedef unsigned char Byte;
typedef Byte* pByte;
typedef pByte* ppByte;

Il est des cas où le typedef est indispensable.
--
Pierre



Avatar
cedric
Mais foutez lui la paix enfin....
Avatar
Québec
Oui. C'est plus clair...
Moi, j'apprends, et le code vient d'un livre (Deitel&Deitel). Alors si le
livre est embrouillé et que j'ai pris mes pilules pour la presion un peu
tard...
C'est mon OS qui paye... ha ha.

C'est comme cette ligne:
newPtr->nextPtr = *sPtr;

ça veut dire(et il, le livre, devrait le spécifier, enfin je le pense)?
newPtr->nextPtr = l'adresse &sPtr, la valeur de sPtr->data, l'adresse de
sPtr->data ou l'adresse de la structure que réfère *sPtr.
J'opte pour cette dernière.

Si je printf("%c%", *sPtr);, j'obtiens la valeur de sPtr->data ??

Avec mes salutations distinguées,

Jean


"Pierre Maurette" a écrit dans le message de
news:
Anthony Fleury a écrit:

Québec wrote:

En général, mes posts comportent un bonjour,

mais pour comprendre
l'intêret de ce struct ListNode**,
Je ne voyais pas ce 'pointeur sur pointeur'

En général déjà il est déconseillé, sauf quand on sait vraiment ce qu'on

fait et qu'on documente bien son code, de cacher des pointeurs dans un
typedef, ca obscurci le code et sa lecture. Mais dans ce cas, tu avais ca
:



typedef struct listNode ListNode;
typedef ListNode *ListNodePtr;


et tu cherchais à savoir ce qu'est un ListNodePtr*.
(Je passe sur le post initial)

En général, le choix est laissé entre :
tipe * Var;
tipe* Var;
tipe *Var;

- Le premier préfère ne pas se prononcer.
- Le second est celui que je préfère. Var est un (type*).
- Le troisième est ambiguë par rapport à * opérateur de
déréférencement. Effectivement, (*Var) a pour type tipe.

Le problème de la seconde écriture est la tentation d'écrire:

tipe* Var1, Var2; // erreur probable

Dans le cas du typedef, ce danger disparait, et il me semble que la
meilleure écriture est:

typedef tipe* ptipe;

puisqu'on définit un type ptipe équivalent à tipe*.

D'autant que ça permet de corriger le problème évoqué précédemment:

ptipe Var1, Var2;

A partir du moment où on écrit les typedef de cette manière, et où on
ne nomme pas les types utilisateur n'importe comment, ça devient plus
facile à suivre:

typedef unsigned char Byte;
typedef Byte* pByte;
typedef pByte* ppByte;

Il est des cas où le typedef est indispensable.
--
Pierre





Avatar
Québec
"cedric" a écrit dans le message de
news:414b344f$0$303$
Mais foutez lui la paix enfin....


Merci à mon allié. Car en effet, ce n'est pas du C.

Il eut peut être été préférable que j'eusse pris mes 'wake up' avant de
poster t'en France.

Jean

Avatar
Pierre Maurette
"Québec" a écrit:


"cedric" a écrit dans le message de
news:414b344f$0$303$
Mais foutez lui la paix enfin....


Merci à mon allié. Car en effet, ce n'est pas du C.

Il eut peut être été préférable que j'eusse pris mes 'wake up' avant de
poster t'en France.
Vous écoutez Linda Lemay ? (guaranted joke-free).

--
Pierre


Avatar
Anthony Fleury
Québec wrote:

Oui. C'est plus clair...
Moi, j'apprends, et le code vient d'un livre (Deitel&Deitel). Alors si le
livre est embrouillé et que j'ai pris mes pilules pour la presion un peu
tard...
C'est mon OS qui paye... ha ha.


Ce genre de code _doit_ être documenté, j'espère que le livre le fait ! (je
ne le connais pas).

C'est comme cette ligne:
newPtr->nextPtr = *sPtr;

ça veut dire(et il, le livre, devrait le spécifier, enfin je le pense)?
newPtr->nextPtr = l'adresse &sPtr, la valeur de sPtr->data, l'adresse de
sPtr->data ou l'adresse de la structure que réfère *sPtr.
J'opte pour cette dernière.


C'est ca, mais précisons quand même. Déjà c'est l'adresse de *sPtr->data car
sPtr est l'adresse de l'adresse d'une structure, y'a un niveau
d'indirection de trop pour que tu puisses utiliser ->. En fait, sPtr est un
pointeur sur startPtr de ta fonction main, qui lui même est le début de la
liste chainée, ok ? Donc si sPtr est un pointeur sur cette valeur, *sPtr
est cette valeur, c'est à dire que *sPtr c'est le début de ta liste
chaînée, l'adresse de la première structure de la liste.

En fait, comme tu insères un élement par le début, tu dis que le suivant de
l'élement que tu viens de créer est l'ancienne valeur du début de la liste,
donc startPtr qui est aussi égal à *sPtr,

Ensuite il va y avoir un *sPtr = newPtr afin de dire que la nouvelle tête de
liste est l'élement que l'on vient de créer.

Pas facile les listes chainées, j'espère être clair...

Si je printf("%c%", *sPtr);, j'obtiens la valeur de sPtr->data ??


oula, tu as tenté ? parce que sPtr->data n'a pas de sens, étant donné que
sPtr est un ListNode**. (*sPtr)->data a un sens, et a la même valeur que
**sPtr (au bon cast prêt), tout simplement car la norme assure que le
premier élement d'une structure a toujours la même adresse que la
structure. Il n'y a pas de remplissage au début d'une structure.

Anthony
--
Alan Turing thought about criteria to settle the question of whether
machines can think, a question of which we now know that it is about as
relevant as the question of whether submarines can swim.
-- Dijkstra

Avatar
Emmanuel Delahaye
Québec wrote on 17/09/04 :
C'est comme cette ligne:
newPtr->nextPtr = *sPtr;

ça veut dire(et il, le livre, devrait le spécifier, enfin je le pense)?


Je pense qu'avant d'aborder des notions complexes commes les listes
chainées, tu devrais commencer par maîtriser les bases du C et par
conséquent les pointeurs.

Si tu avais étudié à fond le Kernighan & Ritchie, par exemple, tu
saurais que si 'p' est un pointeur initialisé, alors '*p' est la valeur
pointée.

C'est le B.A. BA du C.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"C is a sharp tool"

Avatar
Emmanuel Delahaye
(supersedes )

Québec wrote on 17/09/04 :
C'est comme cette ligne:
newPtr->nextPtr = *sPtr;

ça veut dire(et il, le livre, devrait le spécifier, enfin je le pense)?


Je pense qu'avant d'aborder des notions complexes commes les listes
chainées, tu devrais commencer par maîtriser les bases du C et par
conséquent les pointeurs.

Si tu avais étudié à fond le Kernighan & Ritchie, par exemple, tu
saurais que si 'p' est un pointeur initialisé, alors '*p' est la valeur
à l'adresse pointée.

C'est le B.A. BA du C.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"C is a sharp tool"

1 2 3