Previous Next Up Index Contents

9.3.3. Pointeurs et chaînes de caractères


De la même façon qu'un pointeur sur int peut contenir l'adresse d'un nombre isolé ou d'une composante d'un tableau, un pointeur sur char peut pointer sur un caractère isolé ou sur les éléments d'un tableau de caractères. Un pointeur sur char peut en plus contenir l'adresse d'une chaîne de caractères constante et il peut même être initialisé avec une telle adresse.

A la fin de ce chapitre, nous allons anticiper avec un exemple et montrer que les pointeurs sont les éléments indispensables mais effectifs des fonctions en C.

- Pointeurs sur char et chaînes de caractères constantes

Affectation

a) On peut attribuer l'adresse d'une chaîne de caractères constante à un pointeur sur char:

Exemple

  char *C;
  C = "Ceci est une chaîne de caractères constante";

Attention!

Nous pouvons lire cette chaîne constante (p.ex: pour l'afficher), mais il n'est pas recommandé de la modifier, parce que le résultat d'un programme qui essaie de modifier une chaîne de caractères constante n'est pas prévisible en ANSI-C.

Initialisation

b) Un pointeur sur char peut être initialisé lors de la déclaration si on lui affecte l'adresse d'une chaîne de caractères constante:


      char *B = "Bonjour !";

Attention !

Il existe une différence importante entre les deux déclarations:


      char A[] = "Bonjour !";   /* un tableau  */
      char *B  = "Bonjour !";   /* un pointeur */

A est un tableau qui a exactement la grandeur pour contenir la chaîne de caractères et la terminaison '\0'. Les caractères de la chaîne peuvent être changés, mais le nom A va toujours pointer sur la même adresse en mémoire.

B est un pointeur qui est initialisé de façon à ce qu'il pointe sur une chaîne de caractères constante stockée quelque part en mémoire. Le pointeur peut être modifié et pointer sur autre chose. La chaîne constante peut être lue, copiée ou affichée, mais pas modifiée.

Modification

c) Si nous affectons une nouvelle valeur à un pointeur sur une chaîne de caractères constante, nous risquons de perdre la chaîne constante. D'autre part, un pointeur sur char a l'avantage de pouvoir pointer sur des chaînes de n'importe quelle longueur:

Exemple

   char *A = "Petite chaîne";
   char *B = "Deuxième chaîne un peu plus longue";
   A = B;   

Maintenant A et B pointent sur la même chaîne; la "Petite chaîne" est perdue:

Attention !

Les affectations discutées ci-dessus ne peuvent pas être effectuées avec des tableaux de caractères:

Exemple

Solution incorrecte!

  char A[45] = "Petite chaîne";
  char B[45] = "Deuxième chaîne un peu plus longue";
  char C[30];
  A = B;             /* IMPOSSIBLE -> ERREUR !!! */
  C = "Bonjour !";   /* IMPOSSIBLE -> ERREUR !!! */

Dans cet exemple, nous essayons de copier l'adresse de B dans A, respectivement l'adresse de la chaîne constante dans C. Ces opérations sont impossibles et illégales parce que l'adresse représentée par le nom d'un tableau reste toujours constante.

Pour changer le contenu d'un tableau, nous devons changer les composantes du tableau l'une après l'autre (p.ex. dans une boucle) ou déléguer cette charge à une fonction de <stdio> ou <string>.


Conclusions:


Perspectives et motivation

- Avantages des pointeurs sur char

Remarque avancée

Comme la fin des chaînes de caractères est marquée par un symbole spécial, nous n'avons pas besoin de connaître la longueur des chaînes de caractères; nous pouvons même laisser de côté les indices d'aide et parcourir les chaînes à l'aide de pointeurs.

Cette façon de procéder est indispensable pour traiter de chaînes de caractères dans des fonctions. En anticipant sur la matière du chapitre 10, nous pouvons ouvrir une petite parenthèse pour illustrer les avantages des pointeurs dans la définition de fonctions traitant des chaînes de caractères:

Pour fournir un tableau comme paramètre à une fonction, il faut passer l'adresse du tableau à la fonction. Or, les paramètres des fonctions sont des variables locales, que nous pouvons utiliser comme variables d'aide. Bref, une fonction obtenant une chaîne de caractères comme paramètre, dispose d'une copie locale de l'adresse de la chaîne. Cette copie peut remplacer les indices ou les variables d'aide du formalisme tableau.

Discussion d'un exemple

Reprenons l'exemple de la fonction strcpy, qui copie la chaîne CH2 vers CH1. Les deux chaînes sont les arguments de la fonction et elles sont déclarées comme pointeurs sur char. La première version de strcpy est écrite entièrement à l'aide du formalisme tableau:

void strcpy(char *CH1, char *CH2)
{
 int I;
 I=0;
 while ((CH1[I]=CH2[I]) != '\0')
      I++;
}

Dans une première approche, nous pourrions remplacer simplement la notation tableau[I] par *(tableau + I), ce qui conduirait au programme:

void strcpy(char *CH1, char *CH2)
{
 int I;
 I=0;
 while ((*(CH1+I)=*(CH2+I)) != '\0')
      I++;
}

Cette transformation ne nous avance guère, nous avons tout au plus gagné quelques millièmes de secondes lors de la compilation. Un 'véritable' avantage se laisse gagner en calculant directement avec les pointeurs CH1 et CH2 :

void strcpy(char *CH1, char *CH2)
{
 while ((*CH1=*CH2) != '\0')
       {
        CH1++;
        CH2++;
       }
}

Comme nous l'avons déjà constaté dans l'introduction de ce manuel, un vrai professionnel en C escaladerait les 'simplifications' jusqu'à obtenir:

void strcpy(char *CH1, char *CH2)
{
 while (*CH1++ = *CH2++) 
        ;
}

Assez 'optimisé' - fermons la parenthèse et familiarisons-nous avec les notations et les manipulations du 'formalisme pointeur' ...


Exercice 9.7

Ecrire un programme qui lit deux tableaux d'entiers A et B et leurs dimensions N et M au clavier et qui ajoute les éléments de B à la fin de A. Utiliser deux pointeurs PA et PB pour le transfer et afficher le tableau résultant A.


Exercice 9.8

Ecrire de deux façons différentes, un programme qui vérifie sans utiliser une fonction de <string>, si une chaîne CH introduite au clavier est un palindrome:

a) en utilisant uniquement le formalisme tableau

b) en utilisant des pointeurs au lieu des indices numériques

Rappel: Un palindrome est un mot qui reste le même qu'on le lise de gauche à droite ou de droite à gauche:

Exemples:

PIERRE
==>
n'est pas un palindrome

OTTO
==>
est un palindrome

23432
==>
est un palindrome


Exercice 9.9

Ecrire un programme qui lit une chaîne de caractères CH et détermine la longueur de la chaîne à l'aide d'un pointeur P. Le programme n'utilisera pas de variables numériques.


Exercice 9.10

Ecrire un programme qui lit une chaîne de caractères CH et détermine le nombre de mots contenus dans la chaîne. Utiliser un pointeur P, une variable logique, la fonction isspace et une variable numérique N qui contiendra le nombre des mots.


Exercice 9.11

Ecrire un programme qui lit une chaîne de caractères CH au clavier et qui compte les occurrences des lettres de l'alphabet en ne distinguant pas les majuscules et les minuscules. Utiliser un tableau ABC de dimension 26 pour mémoriser le résultat et un pointeur PCH pour parcourir la chaîne CH et un pointeur PABC pour parcourir ABC. Afficher seulement le nombre des lettres qui apparaissent au mois une fois dans le texte.

Exemple:

 Entrez un ligne de texte (max. 100 caractères) : 
 Jeanne
 La chaîne "Jeanne" contient :
 1   fois la lettre 'A'
 2   fois la lettre 'E'
 1   fois la lettre 'J'
 3   fois la lettre 'N'


Exercice 9.12

Ecrire un programme qui lit un caractère C et une chaîne de caractères CH au clavier. Ensuite toutes les occurrences de C dans CH seront éliminées. Le reste des caractères dans CH sera tassé à l'aide d'un pointeur et de la fonction strcpy.


Exercice 9.13

Ecrire un programme qui lit deux chaînes de caractères CH1 et CH2 au clavier et élimine toutes les lettres de CH1 qui apparaissent aussi dans CH2. Utiliser deux pointeurs P1 et P2, une variable logique TROUVE et la fonction strcpy.

Exemples:

Bonjour
Bravo
==>
njou

Bonjour
bravo
==>
Bnjou

abacab
aa
==>
bcab


Exercice 9.14

Ecrire un programme qui lit deux chaînes de caractères CH1 et CH2 au clavier et supprime la première occurrence de CH2 dans CH1. Utiliser uniquement des pointeurs, une variable logique TROUVE et la fonction strcpy.

Exemples:

Alphonse
phon
==>
Alse

totalement
t
==>
otalement

abacab
aa
==>
abacab


Previous Next Up Index Contents

Feedback - Copyright © 1993,1996,1997 F.Faber