CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[C] Les pointeurs.

FitzChevaIerie
FitzChevaIerie
Niveau 10
02 février 2010 à 20:46:48

Voilà en fait on a commencé la programmation en élec, (en C), et j'ai un peu de mal pour ce qui est des pointeurs.
On a pas vu de cours sur le C, on a directement commencé avec un Tp où il y a 3 pages pour expliquer les grandes lignes, et un exemple avec un truc qui allume des LEDS.
Je précise que mon prof est (très) bordélique, assez évasif dans les explications comme s'il était toujours pressé... Et quand un truc est évident pour lui, il considère que ça l'est aussi pour nous... Du coup quand il attaque un chapitre comme la programmation, c'est assez dur de suivre :p)
Je précise aussi que j'ai quelques notions (je m'amusais à programmer des jeux sur ma Casio l'an dernier mais j'ai appris tout seul en essayant au hasard, alors ce sont pas forcément des bonnes bases...)

En fait le programme, c'est ça :

char *portb;
char SORTIE;
int PORTB;

void main()
{
PORTB=0x1004;
portb=PORTB;
SORTIE=0;

  • portb=SORTIE;
  • portb=0xE0;

}

(il y a quelques commentaires qui n'aident pas beaucoup, en fait la valeur 0 ou E0 va s'afficher en binaire sur des leds)
Dans la suite du TP le programme s'allonge un peu mais la seule partie qui me pose problème c'est ça.

Ce que j'avais compris de premier abord, et avec les fiches en début de TP, c'est que :
:d) *portb est un pointeur (à cause de l'étoile), SORTIE et PORTB sont des variables
:d) on donne la valeur 0x1004 à PORTB, puis on donne la valeur PORTB à portb, et enfin la valeur 0 à SORTIE
:d) à l'adresse indiquée par portb (0x1004), on met la valeur de SORTIE. Puis on y met la valeur 0xE0.
Donc selon moi, un pointeur aurait une valeur (0x1004 ici) qui correspond à l'adresse d'une autre variable. *portb désignerait la valeur de cette autre variable.

Quand j'ai demandé des précisions au prof, il m'a totalement embrouillé :( Ce que j'ai compris de ce qu'il m'a dit :
:d) les * ne servent à rien, on pourrait très bien les enlever (il l'a fait, le programme ne marchait plus, après 30 min à chercher dans les menus il les a remises et ça remarchait.)
:d) portb et SORTIE sont des variables, PORTB est un pointeur. Quand je lui ai demandé comment on reconnaissait les variables des pointeurs, il a répondu "c'est normal puisque c'est un pointeur!". Quand j'ai insisté, il m'a dit que les pointeurs étaient forcément sur 16 bits sur ce micro contrôleur. (car les adresses vont de 0000 à FFFF)
:d) on place la variable portb à l'adresse PORTB, puis on change sa valeur (d'abord 0, puis E0)

Voilà je suis un peu paumé, surtout l'histoire des * et de leur soi-disante inutilité, ça me paraît louche... En cherchant un peu sur le net, ça semble plutôt pencher de mon côté (enfin, du côté de la fiche dans son TP).

dnob700
dnob700
Niveau 10
02 février 2010 à 21:11:07

oui, évidemment, ça sert. Le mieux est que tu lise un vrai cours de C (il y a un topic pas loin en dessous avec des liens vers des cours).

Parce que tout t'expliquer là serait un peu long. Mais si après avoir lu le cours tu as des questions, n'hésite pas à les poser.

saleGauss
saleGauss
Niveau 9
03 février 2010 à 10:18:39

oui, ta manière de comprendre est bonne et ton prof à l'air assez mauvais en C (c'est surrement un bon spécialiste de l'elec, ça je n'en doute pas).

Bon, pour résumer, même si c'est dur :

(TYPE désigne un type quelconque : char, int, un type défini par toi même...)

TYPE a; // Déclare une variable de type TYPE
TYPE p_a; // Déclare un pointeur sur un objet de type TYPE.

Et tout ce qu'il faut bien comprendre, c'est que p_a sera une variable comme une autre, mais qui contiendra l'adresse de l'objet "pointé".

Pour connaitre l'adresse d'un objet, on utilise "&".
On peut donc faire ceci :
p_a = &a; // p_a contient l'adresse de a
// Il est équivalent de dire que p_a pointe sur a

Et comme tu l'as dit, pour accéder à un objet pointé par l'intermédiaire du-dit pointeur, on utilise "*".
On appelle cela "déréférencer".
Ainsi, (*a) représente l'objet pointé par p_a, et on s'en sert exactement comme s'il s'agissait de l'objet lui même.

Dernière précision, les adresses sont effectivement représentées en hexadécimal (base 16), et cela est stipulé par le "0x" en préfixe.
Donc pour ce qui toi te concerne, faire :
TYPE p_a = 0x1004;
c'est dire que p_a pointe sur l'objet qui est à l'adresse 1004 de ton espace d'adressage.

Tout le reste que tu pourras rencontrer sera spécifique aux controleurs extérieurs, "carte spéciales", matériel spécifique, ... que tu utilises en entrée ou en sortie.
A ce sujet, le morceau de code que tu as livré est très étrange :
- PORTB n'est pas déclaré
- L'affectation "*portb=0xE0;" alors que portb semble pointer sur un char vu l'affectation précédente "*portb=SORTIE"

Bref, pour conclure, et c'est ce qui t'interessera, garde juste à l'esprit que si tu dois ecrire quelque chose sur une sortie (reliée à une LED par exemple), tu auras toujours quelque chose du genre :

----
char* adresse_de_sortie = 0xQUELQUECHOSE
char le_motif_a_ecrire_sur_les_leds = AUTRECHOSE

// On écrit le motif à l'adresse qui va bien
(*adresse_de_sortie) = le_motif_a_ecrie_sur_les_leds
----

Voila, et bon courage avec un prof pareil...
Non mais j'te jures, le voir essayer d'enlever "l'étoile" et voir que ca ne marche pas, ... quelle quiche :D

N'hésites pas à reposter si tu n'as pas compris, il y a plein de gens compétents en C ici.

_skip
_skip
Niveau 10
03 février 2010 à 10:30:02

TYPE a; // Déclare une variable de type TYPE
TYPE p_a; // Déclare un pointeur sur un objet de type TYPE.

Tu voulais dire
TYPE* p_a?

dnob700
dnob700
Niveau 10
03 février 2010 à 11:13:58

"Tu voulais dire
TYPE* p_a? "

Même remarque aussi plus loin dans le code.

saleGauss : "A ce sujet, le morceau de code que tu as livré est très étrange :
- PORTB n'est pas déclaré
- L'affectation "*portb=0xE0;" alors que portb semble pointer sur un char vu l'affectation précédente "*portb=SORTIE" "

j'ai l'impression que ce n'est pas clair pour toi non plus. Voici un descriptif de ce qui se passe. Toutes les opérations sont correctes (même si elles n'ont de sens que dans le cas d'un contrôleur embarqué) et correctement défini.

char *portb;
portb sera un pointeur.
char SORTIE;
int PORTB;
SORTIE et PORTB sont des "variables normales".

void main()
{
PORTB=0x1004;
l'entier PORTB contient le nombre 0x1004.
portb=PORTB;
le pointeur portb pointe vers l'adresse 0x1004 (qui ne correcpond à aucune variable en particulier)
SORTIE=0;
l'entier SORTIE vaut 0

  • portb=SORTIE;

on enregistre la valeur 0 à l'adresse 0x1004

  • portb=0xE0;

on enregistre la valeur 0xE0 à l'adresse 0x1004
}

À noter que comme portb est un pointeur sur des char, les deux opérations du genre "*portb=???" ne vont copier qu'un char en mémoire et non pas 16 bits comme ce qui est annoncé par le prof. Pour ça, il faudrait que portb pointe vers une variable de 16 bits, par exemple un "short" ou peut-être un "int" selon la plateforme.

saleGauss
saleGauss
Niveau 9
03 février 2010 à 12:12:55

Méa culpa : j'ai fais trois erreurs :
1/ il s'agissait bien de TYPE* p_a et non TYPE p_a.
2/ De plus PORTB est effectivement déclaré, je n'avais pas les yeux en face des trous (deuxieme erreur de ma part).
3/ L'affectation "*portb=0xE0;" reste cohérente, E0 étant représenté sur 1 octet, donc ca reste cohérent avec l'affectation précédente.

Cependant il n'en reste pas moins que mes explications sur la manipulations de pointeurs restent valides, même si plus difficilement lisibles à cause de ces erreurs.

Je m'en excuse.

dnob700
dnob700
Niveau 10
03 février 2010 à 13:20:16

"3/ L'affectation "*portb=0xE0;" reste cohérente, E0 étant représenté sur 1 octet, donc ca reste cohérent avec l'affectation précédente. "

Ce n'est pas la question. la constante 0xFFFF serait tout aussi cohérente au regard de l'afectation précédante. Ce qui compte c'est que la déclaration de portb en fait un pointeur vers un char. Mais par contre, que l'affectation précédente soit l'enregistrement d'un char dans ce pointeur n'empêche pas, par la suite d'y mettre ce qu'on veut. Par exemple :

int* p;
char c;

p = une bonne adresse;
c = 12:

  • p = c;
  • p = 0x426da3;

Est une suite d'opération parfaitement normal (ça l'est aussi si p est un char*, mais la sémantique est plus complexe).

FitzChevaIerie
FitzChevaIerie
Niveau 10
03 février 2010 à 13:26:50

Ok merci tous les deux, je pense que j'ai bien compris :-)

Juste quand on écrit "char *portb", on déclare le format des variables vers lesquelles pointera portb ? Mais on ne déclare rien pour que portb puisse contenir une valeur 16 bits (0x1004) ?

dnob700
dnob700
Niveau 10
03 février 2010 à 13:52:29

En quelques sorte. Sur une machine donné, il est raisonnable de penser que les pointeurs font tous la même taille, qui doit être suffisante pour stocker toutes les adresses possibles en mémoire. Donc un char* ou un int* font la même taille, c'est effectivement la taille des données pointées qui diffère.

Sous forums
  • Aide à l'achat Mac
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Steam Deck
  • Macintosh
  • Hardware
La vidéo du moment