Cours:PointeursCpp : Différence entre versions
(→Tableaux et pointeurs) |
|||
| (10 révisions intermédiaires par 2 utilisateurs non affichées) | |||
| Ligne 5 : | Ligne 5 : | ||
<source lang=cpp> | <source lang=cpp> | ||
| − | |||
int main() | int main() | ||
{ | { | ||
| − | int n1=10; // on supposera que n1 est à l'@ 0x10 | + | int n1 = 10; // on supposera que n1 est à l'@ 0x10 |
| − | int *n2=nullptr; | + | int *n2 = nullptr; |
| − | int n3=20; // on supposera que | + | int n3 = 20; // on supposera que n3 est à l'@ 0x12 |
| − | int *n4=nullptr; | + | int *n4 = nullptr; |
cout << &n1 << " " << n2 << " " << &n3 << " " << n4 << endl; | cout << &n1 << " " << n2 << " " << &n3 << " " << n4 << endl; | ||
cout << n1 << " " << *n2 << " " << n3 << " " << *n4 << endl; // crash du programme | cout << n1 << " " << *n2 << " " << n3 << " " << *n4 << endl; // crash du programme | ||
| + | // --------------------------------------------------------- | ||
n2 = &n1; | n2 = &n1; | ||
n4 = n2; | n4 = n2; | ||
| Ligne 22 : | Ligne 22 : | ||
cout << n1 << " " << *n2 << " " << n3 << " " << *n4 << endl; | cout << n1 << " " << *n2 << " " << n3 << " " << *n4 << endl; | ||
| + | // --------------------------------------------------------- | ||
n1 = 30; | n1 = 30; | ||
*n2 = 40; | *n2 = 40; | ||
| Ligne 51 : | Ligne 52 : | ||
{ | { | ||
struct struct_2int res; | struct struct_2int res; | ||
| − | res.n1=b; | + | res.n1 = b; |
| − | res.n2=a; | + | res.n2 = a; |
return res; | return res; | ||
} | } | ||
| Ligne 58 : | Ligne 59 : | ||
int main(int) | int main(int) | ||
{ | { | ||
| − | int a,b; | + | int a, b; |
struct struct_2int tmp; | struct struct_2int tmp; | ||
| − | tmp=permutte(a,b); | + | tmp=permutte(a, b); |
a=tmp.n1; | a=tmp.n1; | ||
b=tmp.n2; | b=tmp.n2; | ||
| Ligne 68 : | Ligne 69 : | ||
} | } | ||
</source> | </source> | ||
| + | |||
| + | {{Question|Tester le fonctionnement de ce programme}} | ||
Bon c'est pénible ! | Bon c'est pénible ! | ||
| Ligne 73 : | Ligne 76 : | ||
Du coup on va utiliser des pointeurs ou des références. | Du coup on va utiliser des pointeurs ou des références. | ||
| − | {{Question|Ecrire 2 fonctions permutte, l'une avec 2 paramètres de type pointeurs et l'autre avec 2 paramètres de type référence}} | + | {{Question|Ecrire 2 fonctions <code>permutte</code>, l'une avec 2 paramètres de type pointeurs et l'autre avec 2 paramètres de type référence}} |
L'utilisation sera la suivante : | L'utilisation sera la suivante : | ||
| Ligne 79 : | Ligne 82 : | ||
int main(int) | int main(int) | ||
{ | { | ||
| − | int a=5; | + | int a = 5; |
| − | int b=3; | + | int b = 3; |
// on peut utiliser cin !!! | // on peut utiliser cin !!! | ||
| − | permutte(a,b); // passage par référence | + | permutte(a, b); // passage par référence |
//ou | //ou | ||
| − | permutte(&a,&b);//passage par adresse ( pointeur ) | + | permutte(&a, &b);//passage par adresse ( pointeur ) |
return 0; | return 0; | ||
| Ligne 104 : | Ligne 107 : | ||
{ | { | ||
} | } | ||
| − | int maFonction(int a,int b) | + | int maFonction(int a, int b) |
{ | { | ||
} | } | ||
| Ligne 113 : | Ligne 116 : | ||
{{finAide}} | {{finAide}} | ||
| − | |||
=Tableaux et pointeurs= | =Tableaux et pointeurs= | ||
| Ligne 120 : | Ligne 122 : | ||
Un tableau est un pointeur vers la 1ère case de la zone mémoire allouée pour stocker ce tableau. | Un tableau est un pointeur vers la 1ère case de la zone mémoire allouée pour stocker ce tableau. | ||
| − | De ce fait | + | De ce fait <code>tab[3]</code> et <code>*(tab+3)</code> correspondent tous les 2 à la valeur de la même case mémoire. |
| Ligne 128 : | Ligne 130 : | ||
int main() | int main() | ||
{ | { | ||
| − | int tab[5]={1,2,3,4,5}; // on supposera que le tableau est à l'@ 0x5F | + | int tab[5] = {1,2,3,4,5}; // on supposera que le tableau est à l'@ 0x5F |
| − | int *pTab=tab; | + | int *pTab = tab; |
| − | cout << tab << " "<< pTab << endl; | + | cout << tab << " " << pTab << endl; |
| − | cout << tab[0] << " "<< *pTab << endl; | + | cout << tab[0] << " " << *pTab << endl; |
pTab++; | pTab++; | ||
| − | cout << tab << " "<< pTab << endl; | + | cout << tab << " " << pTab << endl; |
| − | cout << tab[1] << " "<< *pTab << endl; | + | cout << tab[1] << " " << *pTab << endl; |
pTab+=3; | pTab+=3; | ||
| − | cout << tab << " "<< pTab << endl; | + | cout << tab << " " << pTab << endl; |
| − | cout << tab[4] << " "<< *pTab << endl; | + | cout << tab[4] << " " << *pTab << endl; |
pTab++; | pTab++; | ||
| − | cout << tab << " "<< pTab << endl; | + | cout << tab << " " << pTab << endl; |
| − | cout << tab[5] << " "<< *pTab << endl; | + | cout << tab[5] << " " << *pTab << endl; |
// attention, ne surtout pas déborder d'un tableau en écriture, par ex | // attention, ne surtout pas déborder d'un tableau en écriture, par ex | ||
| Ligne 154 : | Ligne 156 : | ||
</source> | </source> | ||
| − | {{Question|En utilisant un pointeur, parcourir le tableau pour afficher | + | {{Question|En utilisant un pointeur, parcourir le tableau pour afficher son contenu}} |
| + | =Allocation mémoire= | ||
| − | = | + | {{Question|Comprendre le fonctionnement du programme suivant : }} |
| + | |||
| + | <source lang=cpp> | ||
| + | #include <iostream> | ||
| + | #include <string> | ||
| + | |||
| + | using namespace std; | ||
| + | |||
| + | void afficheTab(string *t[]) | ||
| + | { | ||
| + | int i=0; | ||
| + | while(t[i]!=nullptr) | ||
| + | { | ||
| + | cout << *t[i] <<endl; | ||
| + | i++; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | int main() | ||
| + | { | ||
| + | string *tab[99]; | ||
| + | |||
| + | for (int i=0; i<99; i++) tab[i] = nullptr; | ||
| + | |||
| + | tab[0] = new string("coucou"); | ||
| + | afficheTab(tab); | ||
| + | |||
| + | delete tab[0]; | ||
| + | tab[0] = nullptr; | ||
| + | return 0; | ||
| + | } | ||
| + | </source> | ||
| + | |||
| + | {{question|Le modifier pour :}} | ||
| + | *permettre la saisie d'une liste de nom (avec <code>cin</code> ) | ||
| + | *écrire une fonction qui réalise la désallocation du tableau | ||
Version actuelle datée du 23 novembre 2022 à 12:37
Sommaire
Analyse de code
Simuler le fonctionnement de ce programme :
int main()
{
int n1 = 10; // on supposera que n1 est à l'@ 0x10
int *n2 = nullptr;
int n3 = 20; // on supposera que n3 est à l'@ 0x12
int *n4 = nullptr;
cout << &n1 << " " << n2 << " " << &n3 << " " << n4 << endl;
cout << n1 << " " << *n2 << " " << n3 << " " << *n4 << endl; // crash du programme
// ---------------------------------------------------------
n2 = &n1;
n4 = n2;
cout << &n1 << " " << n2 << " " << &n3 << " " << n4 << endl;
cout << n1 << " " << *n2 << " " << n3 << " " << *n4 << endl;
// ---------------------------------------------------------
n1 = 30;
*n2 = 40;
n4 = &n3;
n3 = 5;
cout << &n1 << " " << n2 << " " << &n3 << " " << n4 << endl;
cout << n1 << " " << *n2 << " " << n3 << " " << *n4 << endl;
return 0;
}
Fonction de permutation
Une fonction ne pouvant retourner qu'une valeur, il est difficile d'écrire une fonction sans utiliser ni pointeurs ni référence.
Il faut passer par une structure, ce qui donne qqch du genre :
struct struct_2int
{
int n1;
int n2;
};
struct struct_2int permutte(int a, int b)
{
struct struct_2int res;
res.n1 = b;
res.n2 = a;
return res;
}
int main(int)
{
int a, b;
struct struct_2int tmp;
tmp=permutte(a, b);
a=tmp.n1;
b=tmp.n2;
return 0;
}
Tester le fonctionnement de ce programme
Bon c'est pénible !
Du coup on va utiliser des pointeurs ou des références.
Ecrire 2 fonctions permutte, l'une avec 2 paramètres de type pointeurs et l'autre avec 2 paramètres de type référence
L'utilisation sera la suivante :
int main(int)
{
int a = 5;
int b = 3;
// on peut utiliser cin !!!
permutte(a, b); // passage par référence
//ou
permutte(&a, &b);//passage par adresse ( pointeur )
return 0;
}
|
Remarquons qu'il est possible d'avoir plusieurs fonctions du même nom, du moment qu'elles ont des signatures (paramètres d'entrée) différentes :
int maFonction(int a)
{
}
int maFonction(int a, int b)
{
}
int maFonction(float a)
{
}
|
Tableaux et pointeurs
Un tableau est un pointeur vers la 1ère case de la zone mémoire allouée pour stocker ce tableau.
De ce fait tab[3] et *(tab+3) correspondent tous les 2 à la valeur de la même case mémoire.
Indiquez ce qu'affiche ce programme :
int main()
{
int tab[5] = {1,2,3,4,5}; // on supposera que le tableau est à l'@ 0x5F
int *pTab = tab;
cout << tab << " " << pTab << endl;
cout << tab[0] << " " << *pTab << endl;
pTab++;
cout << tab << " " << pTab << endl;
cout << tab[1] << " " << *pTab << endl;
pTab+=3;
cout << tab << " " << pTab << endl;
cout << tab[4] << " " << *pTab << endl;
pTab++;
cout << tab << " " << pTab << endl;
cout << tab[5] << " " << *pTab << endl;
// attention, ne surtout pas déborder d'un tableau en écriture, par ex
tab[5] = 3;
return 0;
}
En utilisant un pointeur, parcourir le tableau pour afficher son contenu
Allocation mémoire
Comprendre le fonctionnement du programme suivant :
#include <iostream>
#include <string>
using namespace std;
void afficheTab(string *t[])
{
int i=0;
while(t[i]!=nullptr)
{
cout << *t[i] <<endl;
i++;
}
}
int main()
{
string *tab[99];
for (int i=0; i<99; i++) tab[i] = nullptr;
tab[0] = new string("coucou");
afficheTab(tab);
delete tab[0];
tab[0] = nullptr;
return 0;
}
- permettre la saisie d'une liste de nom (avec
cin) - écrire une fonction qui réalise la désallocation du tableau

