Pointeurs | Exercices 1-5

Enoncé exercice 1

Ecrire un programme C qui utilise la notion de pointeur pour lire deux entiers et calculer leur somme.

Correction exercice 1

Avant de commencer l’exercice il faut s’arrêter un peu sur la notion de pointeur. Un pointeur est une variable qui permet de stocker l’adresse d’une autre variable. C’est à dire l’emplacement de cette dernière au niveau de la mémoire.

Dans cet exercice on aura surtout besoin des pointeurs sur des variables entières sachant que c’est le même principe pour les autres types. Un tel pointeur p sera de type int *. Il sera déclaré alors de la façon suivante : int *p.

Imaginons pour l’instant qu’on veut pour une raison donnée que ce pointeur p pointe sur la variable entière a. Dans ce cas on a qu’à mettre l’adresse de a qui est &a dans p en utilisant l’instruction: p=&a. Et pour accéder à la valeur de la variable a à travers le pointeur p on doit utiliser *p. Ceci est rendu possible grâce au fait que l’adresse de a se trouve dans p.

En revenant à l’exercice, on doit déclarer trois variables entières a, b et s les deux premières pour les entiers pour lesquels l’utilisateur souhaite calculer la somme s, et trois pointeurs pa, pb et ps un pour chaque variable (ligne 6). Puis on mit les adresses des variables a, b et s, avant même de les lire, chacune dans le pointeur correspondant (lignes 7-9).

Après, on lit les variables a et b avec la fonction scanf en passant par les deux pointeurs. Et ceci en remplaçant les adresses &a et &b par leurs équivalents pa et pb (ligne 11). Et pour mettre la somme de ces deux entiers dans la variable s en peut aussi utiliser les pointeurs (ligne 12), cette somme peut être affichée en utilisant soit s ou *ps (ligne 13).

Solution exercice 1
#include<stdio.h>
#include<stdlib.h>
int main()
{
    int a,b,s;
    int *pa,*pb,*ps;
    pa = &a;
    pb = &b;
    ps = &s;
    printf("donnez deux entiers:\n");
    scanf("%d%d",pa,pb);
    *ps = *pa + *pb;
    printf("la somme est %d.\n",s);
    system("pause");
    return 0;
}
Enoncé exercice 2

Ecrire un programme C qui utilise la notion de pointeur pour la permuter le contenu de deux variables de type char.

Correction exercice 2

Dans cet exercice on va exploiter les pointeurs pour permuter le contenu de deux variables de type char. On commencera par la déclaration de ces deux variables (a et b) en plus de deux pointeurs (pa et pb) sur des variables de type char (ligne 5). Ces deux derniers vont recevoir les adresses des deux variables a et b sur lesquelles ils vont pointer (lignes 7-8).

Pour la lecture de a et b, on passe à la fonction scanf les adresses leurs adresse qui sont pa et pb (lignes 10 et 13). Et puisqu’il s’agit ici de deux caractères, il ne faut pas oublier de séparer les deux fonctions scanf par une instruction getchar() afin d’éviter la lecture du retour à la ligne, utilisé pour la validation de a, dans b (ligne 11).

La permutation sera effectuée en utilisant *pa et *pb au lieu de a et b qui est exactement la même chose et en s’appuyant sur la variable auxiliaire tmp de type char. Il est à noter qu’on pouvait n’utiliser que des pointeurs et ceci en remplaçant tmp par *ptmpptmp et un pointeur sur tmp.

Et pour s’assurer de la réussite de la permutation on a affiché les deux variables avant et après la permutation (lignes 14 et 18).

Solution exercice 2
#include<stdio.h>
#include<stdlib.h>
int main()
{
    char a,b,*pa,*pb;
    char tmp;
    pa = &a;
    pb = &b;
    printf("Entrez le premier charactere (a): ");
    scanf("%c",pa);
    getchar();
    printf("Entrez le deuxieme charactere (b): ");
    scanf("%c",pb);
    printf("a = %c et b = %c.\n",a,b);
    tmp = *pa;
    *pa = *pb;
    *pb = tmp;
    printf("a = %c et b = %c.\n",a,b);
    system("pause");
    return 0;
}
Enoncé exercice 3

Ecrire un programme C qui remplit un tableau d’entiers et calcule la somme de ses éléments en utilisant un pointeur pour son parcours.

Correction exercice 3

Cet exercice se concentre sur l’utilisation d’un pointeur pour le parcours d’un tableau. Il faut pour cet effet savoir deux choses essentielles: la première, est que le nom du tableau est un pointeur sur la première case du tableau et la deuxième est que les cases d’un tableau sont adjacentes au niveau de la mémoire. En plus, on peut effectuer les opérations arithmétiques sur les pointeurs comme l’addition et l’incrémentation sauf pour les pointeurs constants comme le nom d’un tableau qui ne tolère aucun changement de valeur.

En revenant à l’exercice, on a déclaré un tableau d’entiers t de taille n et un pointeur p qui va servir dans le parcours du tableau que ce soit lors de la lecture ou pour le calcul de la somme. Pour la lecture du tableau t on va utiliser une boucle for qui utilise un pointeur au lieu du compteur entier usuel (ligne 9). Et comme il a été déjà cité au début, le nom du tableau est un pointeur constant sur la première case du tableau. Donc p sera initialisé par la valeur de t et à chaque itération de la boucle, ce pointeur sera incrémenté par 1 pour passer d’une case à une autre adjacente du tableau. Et pour la condition de réitération de la boucle for il ne faut pas que p dépasse la dernière case du tableau qui a comme adresse t+n-1. A l’intérieur de la boucle, p pointe sur la case actuelle, donc pour sa lecture il suffira de mettre p comme adresse dans la fonction scanf (ligne 9).

Pour le calcul de la somme on va utiliser la même technique de parcours du tableau (ligne 10) où *p fait référence à la valeur de l’élément actuel du tableau et qui sera ajoutée à la variable som initialisée lors sa déclaration par 0. Le programme se termine par l’affichage de la somme calculée (ligne 11).

Solution exercice 3
#include<stdio.h>
#include<stdlib.h>
int main()
{
    int t[50];
    int n,*p,som=0;
    printf("Donnez le nombre d'elements: ");
    scanf("%d",&n);
    for(p=t;p<t+n;p++) scanf("%d",p);
    for(p=t;p<t+n;p++) som = som + *p;
    printf("%d\n",som);
    system("pause");
    return 0;
}
Enoncé exercice 4

Ecrire un programme C qui lit une chaîne de caractères et affiche cette chaîne à partir de la première occurrence d’un caractère entré par l’utilisateur. En utilisant pour ceci la fonction strchr et un pointeur pour le parcours de la chaîne.

Correction exercice 4

Dans cet exercice on va revoir le parcours d’un tableau à l’aide d’un pointeur. Et on va découvrir la fonction strchr de la bibliothèque standard string.h qui utilise les pointeurs. Ainsi que le cas particulier d’un pointeur qui ne pointe sur aucune variable.

Pour illustrer ces points, on a lit une chaîne de caractères s (ligne 10) et un caractère c (ligne 12). L’objectif donc est de trouver la position de c dans la chaîne s et afficher les caractères de s à partir de cette position. On peut facilement, à l’aide d’une boucle for, trouver la première occurrence de c, mais dans cet exercice on va se servir de la fonction strchr. Cette fonction prend deux paramètres: une chaîne de caractères et un caractère. Elle retourne comme résultat un pointeur sur la première position de la chaîne entrée en paramètre qui contient ce caractère.

Le pointeur renvoyé par strchr sera intercepté par le pointeur p (ligne 13). Et il est à noter que p a été déclaré comme étant un pointeur sur une variable de type char (ligne 7). Le pointeur p ainsi obtenu peut avoir deux valeurs: l’adresse de la position de la chaîne où se trouve c, ou NULL qui veut dire que le pointeur ne pointe sur aucune variable, ce qui sera interprété dans ce cas par l’absence du caractère dans s.

On procédera donc à un test sur la valeur de p: si elle est égale à NULL (ligne 14) on déduira que c n’existe pas dans la chaîne de caractères s et on affichera un message adéquat. Dans l’autre cas (ligne 15) on va parcourir à l’aide de la boucle for (ligne 16) et le pointeur p la chaîne de caractères s pour afficher les caractères à partir de l’adresse contenue dans p.

Le pointeur p, avant l’entrée dans la boucle, pointe déjà sur la case ou se trouve le caractère c donc le premier bloc d’initialisation dans la boucle ne va pas être rempli. Et en ce qui concerne la condition d’arrêt de la boucle il suffit d’ajouter la taille de la chaîne sur le pointeur constant s qui pointe sur la première case de la chaîne pour retrouver l’adresse de la dernière case que ne doit pas dépasser p.

A l’intérieur de la boucle for, et à chaque itération de cette dernière p pointera sur un élément de la chaîne, donc pour répondre à la question de l’exercice il suffit d’afficher à l’aide de la fonction printf le caractère *p (ligne 17).

Solution exercice 4
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    char s[50];
    char *p;
    char c;
    printf("Entrez une chaine de caractere:\n");
    gets(s);
    printf("Entrez un caractere: ");
    scanf("%c",&c);
    p = strchr(s,c);
    if(p == NULL) printf("Ce caractere n'existe pas.\n");
    else{
         for(;p < s+strlen(s);p++)
            printf("%c",*p);
         printf("\n");
    }
    system("pause");
    return 0;
}
Enoncé exercice 5

Ecrire un programme C qui définit une structure permettant de stocker le nom, le prénom et l’âge d’une personne. Lit ensuite ces informations pour deux personnes et affiche le nom complet de la moins âgée d’entre elles en utilisant une seule fonction printf pour l’affichage du résultat.

Correction exercice 5

Après la définition de la structure personne (lignes 3-7) qui a trois éléments: deux chaînes de caractères pour le nom et le prénom et un entier pour l’âge, vient la déclaration de deux variables a et b de type struct personne (ligne 10). Ces deux dernières vont représenter les deux personnes. Juste après vient la lecture des informations pour chaque personne avec six fonctions scanf (lignes 12-24).

Maintenant que les deux variables sont prêtes, on peut passer à la comparaison des âges des deux personnes et l’affichage du nom de la moins âgée. La manière la plus intuitive et d’utiliser un test if else avec une fonction printf dans chaque bloc. Ces deux fonctions printf vont faire la même chose pour deux variables différentes ce qui constitue une sorte de redondance au niveau du code. Cette redondance peut être évitée en utilisant une astuce basée sur les pointeurs. L’intérêt ici ne sera pas très visible puisqu’il s’agit d’une simple fonction printf. Mais l’effet de la technique qui sera introduite ci-après sera considérable en présence d’un traitement qui s’étale sur plusieurs lignes au lieu d’une seule.

Bien sûr on ne peut pas s’en passer de la comparaison des deux âges avec un test if esle. Par contre lors du test on ne va s’intéresser qu’à la comparaison et on va oublier le traitement qu’on veut effectuer sur la variable qui contient l’âge le plus petit, à savoir l’affichage du nom complet de la personne correspondante à cette variable.

L’objectif de cette comparaison sera de faire pointer un pointeur p sur la variable qui a la composante age la plus petite (lignes 26-27). Ce pointeur p est déclaré comme étant un pointeur sur une variable de type struct personne (ligne 11).

A ce stade du programme on a p qui pointe sur la variable qui correspond à la personne la moins âgée. Et qui peut être soit a ou b, chose qui n’est plus intéressante. Donc l’affichage sera indépendant des deux variables. Et puisque *p peut représenter a ou b alors, (*p).nom et (*p).pre sont deux chaînes de caractères représentant consécutivement le nom et le prénom de la personne ayant l’âge le plus petit et qui seront affichés à l’aide de la fonction printf (ligne 29).

Solution exercice 5
#include<stdio.h>
#include<stdlib.h>
struct personne{
       char nom[20];
       char pre[20];
       int age;
       };
int main()
{
    struct personne a,b;
    struct personne *p;
    printf("Entrez le nom de la personne 'A': ");
    scanf("%s",a.nom);
    printf("Entrez le prenom de la personne 'A': ");
    scanf("%s",a.pre);
    printf("Entrez l'age de la personne 'A': ");
    scanf("%d",&a.age);
 
    printf("Entrez le nom de la personne 'B': ");
    scanf("%s",b.nom);
    printf("Entrez le prenom de la personne 'B': ");
    scanf("%s",b.pre);
    printf("Entrez l'age de la personne 'B': ");
    scanf("%d",&b.age);
 
    if(a.age<b.age) p = &a;
    else p = &b;
 
    printf("La moins agee: %s %s.\n",(*p).nom,(*p).pre);
 
    system("pause");
    return 0;
}