Developpement Amateur de SpixSh@dow |
|
| [Cours 03] Les pointeurs et les tableaux | |
| | Auteur | Message |
---|
Sekoda Admin
Nombre de messages : 1631 Date d'inscription : 04/01/2007
| Sujet: [Cours 03] Les pointeurs et les tableaux Dim 25 Fév - 20:47 | |
| Bonjour a tous pour ce troisieme cours Aujourd'hui, nous allons aborder un point important du C, a savoir, la manipulation de pointeur - Code:
-
int main() { int *a; int *b;
return (0); }
Dernière édition par le Dim 25 Fév - 21:10, édité 2 fois | |
| | | Sekoda Admin
Nombre de messages : 1631 Date d'inscription : 04/01/2007
| Sujet: Re: [Cours 03] Les pointeurs et les tableaux Dim 25 Fév - 20:48 | |
| Definition Pointeurs ??? Kesako A savoir, toutes les valeurs que vous manipulez dans votre code, doivent etre prealablement stockees quelque part. Pour la plus grande partie de celles-ci, elles sont stockees, dans ce qu'on appelle la memoire vive, ou RAM. Ainsi, quand on manipule des valeurs, le programme doit connaitre l'adresse de chaque valeur. Quelle adresse On peut modeliser la memoire vive comme un gigantesque carre remplie elle-meme de case. Chaque case represente une maison. Et comme toute maison, il y a une adresse postale associee . Sauf qu'ici, il n'est pas question d'envoye une lettre, donc on retire le mot postale Ce qui nous donne donc, de la memoire vive, contenant des cases de memoire (une case = un octet), pouvant acceuillir des variables. Selon le type de variable utilisee, celle-ci prend plus ou moins de place. Comme une villa ou un chateau qui ont plus d'espace, mais qui ont la meme adresse Voila ce qu'est une adresse. C'est l'emplacement de l'information dans la memoire . | |
| | | Sekoda Admin
Nombre de messages : 1631 Date d'inscription : 04/01/2007
| Sujet: Re: [Cours 03] Les pointeurs et les tableaux Dim 25 Fév - 20:52 | |
| Utilite Ok, mais c'est quoi le rapport avec les pointeurs Les pointeurs, comme leur nom l'indique, pointent vers quelque chose Ici, ils pointent vers une adresse, a savoir celle de la variable qui leur est associee. Whoa c'est cool ! Mais a quoi ca sert A savoir, c'est que les variables declarees dans une fonction, sont locales. En gros, elles ne sont connues que de la fonction ou elles ont ete appelees. Ainsi : - Code:
-
int exemple() { int a;
a = 10; return (a); }
int main() { int a;
a = 5; return (0); } La variable "a" de la fonction "main" est totalement differente de la variable "a" de la fonction "exemple". De plus, si on veut modifier la valeur de "a" de la fonction "main", suite a une appelle de fonction, on doit proceder ainsi : - Code:
-
int function() { int a;
a = 10; return (a); }
int main() { int a;
a = 5; a = function(); return (0); } dans le cas ou on veut lui donner une nouvelle valeur, ou comme ceci : - Code:
-
int add50(int a) { a += 50; return (a); }
int main() { int a;
a = 5; a = add50(a); return (0); } si on veut qu'a chaque appelle, on ajoute 50 a notre variable "a". Quelle est la valeur de "a" ? Mais jusqu'a la, je ne vous apprends rien. On envoie une variable et on recupere une nouvelle valeur de la variable. Et c'est la le probleme ! Et oui ! Autant on peut envoyer autant de valeur que l'on veut, autant on ne peux en retourner qu'une seule ! - Code:
-
int add50(int a, int b) { a += 50; b += 50; return (a, b); }
int main() { int a; int b;
a = 5; b = 10; a, b = add50(a, b); return (0); } Ce code la serait l'ideal, mais il ne faut pas trop rever . Cela ne marche pas. Donc comment allez-vous faire pour ajouter 50 en meme temps a "a" et "b" ? Appeler deux fois la fonction ? - Code:
-
int add50(int a) { a += 50; b += 50; return (a); }
int main() { int a; int b;
a = 5; b = 10; a = add50(a); b = add50(b); return (0); } Dans un cas aussi simple qu'ici, oui, pourquoi pas... Deux appelles de fontions... Mais si on veut faire des operations plus complexes qui requiert x variables et qui a besoin de tous les modifier en meme temps, vous faites comment ? Me rappelez autant de fois la fonction qu'il y a de variables, au point d'avoir un gros copier coller sur des lignes entieres ? C'est la qu'intervient (enfin !) les pointeurs .
Dernière édition par le Dim 25 Fév - 20:57, édité 2 fois | |
| | | Sekoda Admin
Nombre de messages : 1631 Date d'inscription : 04/01/2007
| Sujet: Re: [Cours 03] Les pointeurs et les tableaux Dim 25 Fév - 20:52 | |
| Le pouvoir des pointeurs - Code:
-
int add50(int a, int b) { a += 50; b += 50; return (0); }
int main() { int a; int b;
a = 5; b = 10; add50(a, b); return (0); } Quelqu'un peu me dire combien vaudra a et b ? Bon, comme j'ai envie de continuer le cours, avant que quelqu'un me dise la reponse, ben je vais vous donner la reponse - Code:
-
a = 5 b = 10 Non, non, tu as truque les resultat : a vaut 55 et b vaut 60, non Et ben non . Car quand vous faites une appelle de fonction, vous ne faites que passer une copie des variables passees en parametres. Une sorte de "return", a l'envers. Donc dans la fonction, vous pourrez modifie ce que vous voulez sur les variables, les modifications ne seront valables que pour cette fonction, et non pour la fonction source. Par contre, en utilisant ca : - Code:
-
int add50(int *a, int *b) { *a += 50; *b += 50; return (0); }
int main() { int a; int b;
a = 5; b = 10; add50(&a, &b); return (0); } vos variables "a" et "b" valent effectivement 55 et 60.
Dernière édition par le Dim 25 Fév - 20:58, édité 1 fois | |
| | | Sekoda Admin
Nombre de messages : 1631 Date d'inscription : 04/01/2007
| Sujet: Re: [Cours 03] Les pointeurs et les tableaux Dim 25 Fév - 20:53 | |
| Explication Qu'as-tu fait Deja, lors de l'appelle de fonction, j'ai donnee l'adresse des variables a la fonction "add50". Pour cela, j'ai utilise le prefixe "&". Ainsi, si on affiche la valeur de "a", on obtient la valeur qui lui a ete assignee, et si on affiche la valeur de "&a", on obtient donc la valeur de son adresse. C'est quelque chose que vous connaissez bien ! Vous savez, quand Windows plante et qui montre des valeurs comme "0x6111a101" et autres... Donc, a une fonction devant recevoir une adresse : - Code:
-
int add50(int *a, int *b) on lui envoie l'adresse qu'il veut - Code:
-
add50(&a, &b); Cependant, vous serez souvent amene a envoye l'adresse d'une variable, qui appellera elle-meme une autre fonction utilisant les premieres variables. Pour cela, il ne faudra pas envoyer l'adresse du pointeur, mais juste le pointeur en lui-meme. Exemple : - Code:
-
int add100(int *a, int *b) { *a += 100; *b += 100; return (0); }
int add50(int *a, int *b) { *a += 50; *b += 50; add100(a, b); return (0); }
int main() { int a; int b;
a = 5; b = 10; add50(&a, &b); return (0); } Tout simplement parce que la fonction qui attends des pointeurs peut soit recevoir une adresse memoire, soit des pointeurs qui leur donneront une copie de l'adresse. Mais une adresse, qu'elle soit une copie ou non, mene a un meme emplacement . Je vous laisse deviner la valeur de "a" et "b" Remarque : vous pouvez egalement faire comme ceci : - Code:
-
int add50(int *a, int *b) { *a += 50; *b += 50; return (0); }
int main() { int a; int b; int *pa; int *pb;
a = 5; b = 10; pa = &a; pb = &b; add50(pa, pb); return (0); } cela marche, car vous associe l'adresse de la variable au pointeur dans la fonction, avant de transmettre les pointeurs. Mais c'est, pour vous dire, completement inutile . C'etait juste pour vous dire que vous pouviez faire ca . | |
| | | Sekoda Admin
Nombre de messages : 1631 Date d'inscription : 04/01/2007
| Sujet: Re: [Cours 03] Les pointeurs et les tableaux Dim 25 Fév - 21:10 | |
| UtilisationIl faut faire tres attention, avec la manipulation des pointeurs. Combien de fois, de nombreux programmeurs se sont emmeles les pinceaux, car en plus d'avoir un code mal presente, ils utilisent a tout bout de champs les pointeurs avant un manque de rigueur qui les ammene a des resultats errones, soit parce qu'ils ont mal passe une adresse, soit parce qu'ils inversent certains pointeurs entre eux. Vous comprendrez rapidement avec ce qui suivra . Donc, grace aux pointeurs, nous avons des espaces memoires qui se creent et qui sont attribues aux pointeurs qui affichent le point de depart de ces espaces. Graces aux pointeurs, nous pourrons utiliser ce que l'on appelle : les tableaux. | |
| | | Sekoda Admin
Nombre de messages : 1631 Date d'inscription : 04/01/2007
| Sujet: Re: [Cours 03] Les pointeurs et les tableaux Dim 25 Fév - 21:17 | |
| Les Tableaux C'est quoi un tableau A savoir, c'est que jusqu'a la, nous avons vu des variables a valeur simple. Je veux dire par la, que a une variable de type "char", nous lui avons donne un seul caractere, a une variable de type "int", nous lui avons donne une seule valeur, et ainsi de suite. Nous prendrons l'exemple du type "char". Si on veut stocke une chaine de caractere, comment allons-nous proceder ? Une chaine de caractere, est comme son nom l'indique, un ensemble de caractere qui sont lies, comme les maillons d'une chaine . Plus concretement : "Voici une chaine de caractere." Une phrase, un mot, quelque chose qui est constitue de plusieurs caracteres . C'est la ou les tableaux intervient . | |
| | | Sekoda Admin
Nombre de messages : 1631 Date d'inscription : 04/01/2007
| Sujet: Re: [Cours 03] Les pointeurs et les tableaux Dim 25 Fév - 21:23 | |
| Utilisation des tableauxJe vous ai dit tout a l'heure, que l'on pouvait modeliser la memoire, comme un gigantesque carre constitue de case. C'est un tableau geant en quelque sorte . Un tableau, c'est donc une table contenant des cases de memoire, mais dont le type est le meme pour toutes les cases du tableau. Ainsi, si je declare une tableau de "char", je ne pourrai mettre uniquement des caracteres dans le tableau, et non des "int" (tout simplement parce qu'elles ne possedent pas la meme taille). Sachant qu'un "char" vaut 1 octet, soit une case memoire, un tableau de "char" de 2 cases vaudra 2 octet. Alors qu'un "int" valant 4 octets, soit 4 cases memoires pour chaque "int", un tableau de "int" contenant 2 cases, vaudra 8 octets de memoires, soit 8 cases memoires dans la RAM. C'est pour cela qu'il est deconseille d'attribue une autre valeur que celle predestinee. Le risque de crash n'en serait que plus grand . Donc en declarant un tableau de "char", je pourrai le remplir de caractere constituant ma phrase . | |
| | | Sekoda Admin
Nombre de messages : 1631 Date d'inscription : 04/01/2007
| Sujet: Re: [Cours 03] Les pointeurs et les tableaux Dim 25 Fév - 21:47 | |
| Declaration en dur et declaration dynamiqueIl y a deux facon de declarer des tableaux de char. - Declaration en dur : - Code:
-
char *tab;
tab = "Voici une declaration en dur." L'avantage est que vous n'avez pas besoin de connaitre le nombre de caracteres pour creer votre tableau. Cependant, vous pourrez toujours rever pour modifier votre tableau . En effet, de cette facon, vous ne pourrez pas modifier sa valeur, donc retirer des mots, la remplacer ou autre. Pour cela, il faut faire ceci : - Code:
-
char tab[10];
tab[0] = 'B'; tab[1] = 'o'; tab[2] = 'n'; tab[3] = 'j'; tab[4] = 'o'; tab[5] = 'u'; tab[6] = 'r'; tab[7] = ' '; tab[8] = '!'; Ainsi, vous pourrez remplacer n'importe quelle lettre de votre tableau. Cependant, vous aurez une taille fixe pour votre tableau, donc si vous avez fait une phrase trop grande, vous n'aurez pas assez d'espace pour cela, ou si vous avez faite une phrase trop courte, vous aurez gache de la memoire . De plus, vous avez pu constater que ce n'est pas l'ideal pour attribuez une phrase... Enfin, il y a la derniere methode (et la plus efficace ) : - Code:
-
char *tab; int size;
tab = malloc(size * sizeof(*tab)); ... free(tab); Attends ! Il y a trop de mot inconnu dedans He oui, dur dur la vie de programmeur . -"malloc" est une fonction systeme qui attribue dynamiquement la memoire. Ainsi, on peut avoir une taille personnalisable de l'espace, qui est attribuee cette fois par la variable "size". Ainsi, apres avoir utilisee une fonction permettant de savoir le nombre de caractere, on demande a "malloc" la juste taille qui faut avant de copier la chaine de caractere qu'il faut. -"sizeof" est une fonction qui calcul le poids de la variable passe en parametre. Ainsi, selon le type de variable utilisee (par default ou personnalisee), il attribue le nombre de case memoire necessaire au "malloc". C'est donc une fonction tres interessante. -"free", fonction extrement importante. En effet, combien de fois les ordinateurs des developpeurs de jeux video doivent reboote car il crash suite a une mauvaise manipulation de la memoire, de memoire saturee et autre. A savoir, contrairement aux deux premiers methodes, "malloc" attribue un emplacement memoire au pointeur "*tab". Et il l'attribue de maniere permanente. Donc tant que l'on a pas libere la memoire, cette espace restera occupee. Et si par malheur vous modifiez l'adresse du pointeur, cette espace sera perdue si vous ne l'avez pas au prealable "free-er". On parle ici de fuite memoire. Exemple : - Code:
-
char *tab;
tab = malloc(5 * sizeof(*tab)); tab = "On modifie l'adresse de tab, afin qu'il ne pointe plus sur l'espace attribue par malloc, mais par celui qu'on lui donne en ce moment." La, non seulement vous avez perdu 5 octets de memoire, mais en plus, vous ne pourrez plus modifie le contenu du tableau . Par contre si vous faites : - Code:
-
char *tab;
tab = malloc(5 * sizeof(*tab)); free(tab); tab = "C'est beaucoup mieux, car vous avez au prealable libere l'espace attribue par malloc, avant de pointer sur un nouvel emplacement. Pas de fuite memoire ^^." | |
| | | Sekoda Admin
Nombre de messages : 1631 Date d'inscription : 04/01/2007
| Sujet: Re: [Cours 03] Les pointeurs et les tableaux Dim 25 Fév - 22:05 | |
| Utilisation des tableauxVoila, si vous avez compris l'utilisation des tableaux de "char", vous avez compris l'utilisation de tous les tableaux. J'ai pris l'exemple du "char" car c'etait le plus simple a comprendre avec des exemples concrets. Mais a savoir, vous pouvez faire exactement la meme chose avec des "int" ou autre. Exemple : un tableau de "int" pour recuperer les statistiques d'un personnage, ou pour faire du triage parmi une liste de nombre. -Quand vous utilisez "malloc", placer immediatement votre "free" afin d'etre sur de ne pas oublier la liberation de l'espace. -Vous avez pu remarquer qu'un tableau de 10 cases, commence a la case 0 et se termine a la case 9. On commence a compte a partir de 0 . -Idem pour les "malloc". Ainsi : - Code:
-
char *tab;
tab = malloc(10 * sizeof(*tab)); pourra contenir des caracteres de la case "tab[0]" a "tab[9]". -Ne jamais realiser d'operation avec les tableaux : - Code:
-
char *tab1; char *tab2;
tab1 = malloc(10 * sizeof(*tab1)); tab2 = malloc(5 * sizeof(*tab2)); tab1 += tab2; cela va modifier les adresses et non le contenu. Vous pourrez par contre realiser des operations avec les contenus des tableaux. Par contre, avec le C++, vous pourrez réaliser ce genre d'opération dans certains cas. Mais pour l'instant, oubliez ce cas de figure, et dites-vous que c'est de la folie . -Le nombre de * devant la variable determine le nombre de dimension que le tableau possede. Ainsi : - Code:
-
char **tab; donnera un tableau a deux dimensions (vous savez, comme les emplois du temps ou les tables de multiplications ). Mais je vous en dirai davantage dans un prochain cours . -Ne pas confondre les *var en tant que pointeur et les *tab, en tant que tableau. Dans le premier cas, cela permet de manipuler des variables dans une autres fonctions, dans le deuxieme cas, c'est pour obtenir un tableau contenant un certains nombre de variable. Cependant, le principe du pointeur reste le meme : on pointe sur un espace memoire. -Pour ceux qui ont du mal a comprendre le principe des pointeurs, dites-vous que c'est comme un raccourci Windows. Vous avez votre icone de raccourci sur le bureau, et quand vous cliquer dessus, il va executer le programme cible, qui se trouve quelque part sur votre disque dur, non ? Ici, c'est pareil . Quand vous attribuez une adresse a un pointeur, vous donnez en quelque sorte la cible a votre raccourci, ainsi, toutes les modifications que vous faites sur le pointeur, affectera la variable cible (tant que vous utilisez bien un * derriere votre pointeur : "*a += 50", autrement vous modifier le pointage et non la cible ). -Si vous passez un tableau déjà "malloc-é", vous n'avez pas besoin d'envoyer l'adresse du tableau, car vous envoyez une copie de l'adresse à la fonction appelée. Et vu qu'une adresse donne toujours sur la même maison, il n'y a donc pas de problème . Cependant, si vous n'avez pas utilisez de malloc et que vous voulez obtenir un tableau, vous avez deux façon de faire : - Code:
-
// Cas du premier cas : tableau deja malloc-é
/* ** Cours_03 for Cours 03 ** Sekoda ** 25/02/07 */
int func(char *tab) { tab[0] = 'a'; tab[1] = 'b'; return (0); } int main() { char *tab;
tab = malloc(2 * sizeof(*tab)); func(tab); //tab[0] contient 'a' et tab[1] contient 'b' free(tab); return (0); }
-------------------------------------------------------------------------------------
// Deuxième cas : tableau non malloc-é
/* ** Cours_03 for Cours 03 ** Sekoda ** 25/02/07 */
char *func() { tab = malloc(2 * sizeof(*tab)); tab[0] = 'a'; tab[1] = 'b'; return (tab); } int main() { char *tab;
tab = func(); //tab[0] contient 'a' et tab[1] contient 'b' free(tab); return (0); }
-------------------------------------------------------------------------------------
// Autre méthode possible
/* ** Cours_03 for Cours 03 ** Sekoda ** 25/02/07 */
int func(char **tab) { (*tab) = malloc(2 * sizeof(*(*tab))); (*tab)[0] = 'a'; (*tab)[1] = 'b'; return (0); } int main() { char *tab;
func(&tab); //tab[0] contient 'a' et tab[1] contient 'b' free(tab); return (0); } Soit on passe l'adresse du tableau, soit on fait un retour de valeur. Cependant, on "free" quoiqu'il en soit .
Dernière édition par le Mar 6 Mar - 3:40, édité 3 fois | |
| | | Sekoda Admin
Nombre de messages : 1631 Date d'inscription : 04/01/2007
| Sujet: Re: [Cours 03] Les pointeurs et les tableaux Dim 25 Fév - 22:16 | |
| ConclusionVoila, le cours est fini. Je ne sais pas si j'ai ete assez clair, mais j'espere que vous avez compris ^^' A savoir, le chapitre sur les pointeurs est le chapitre le plus complique qui soit dans le C. Le jour ou vous comprendrez leur utilisation, non seulement vous pourrez vous considerez comme un developpeur confirme, mais en plus, vous verrez bientot la fin de votre apprentissage . Il reste quelques points a abordes sur les cours de C, mais la comprehension des pointeurs est imposee pour poursuivre. Pour ceux qui n'ont pas compris, ou qui on du mal a comprendre le principe des pointeurs, ne vous inquietez pas, cela vient en manipulant. Ce n'est pas avec de la theorie que vous pourrez reussir a faire quoi que ce soit. Je vous recommande donc de faire les exercices afin de mieux comprendre les pointeurs. Au pire, n'hesitez pas a poser vos questions. Car a chapitre difficile, explication difficile ^^' Donc j'ameliorerai le cours au fur et a mesure des questions que vous me poserez, car je dois avouer que moi, j'ai compris le principe des pointeurs, et j'ai surement omis des details banals, mais primordiaux. Donc ne surtout pas hesitez ! La partie avec le "malloc" va vous servir pour comprendre plus facilement la manipulation de tableaux. Bon courage . Prochain chapitre : Tableaux a x dimensions, structures de variables et pointeurs sur fonctions (qui annonce la presque fin de l'apprentissage ). | |
| | | Contenu sponsorisé
| Sujet: Re: [Cours 03] Les pointeurs et les tableaux | |
| |
| | | | [Cours 03] Les pointeurs et les tableaux | |
|
| Permission de ce forum: | Vous ne pouvez pas répondre aux sujets dans ce forum
| |
| |
| |
|