Série 13: Chaîne de caractères, arguments de programme et

Transcription

Série 13: Chaîne de caractères, arguments de programme et
Série 13:
Chaîne de caractères, arguments de programme et
pointeur de pointeur
But : Le but de cette série est d'étudier les chaînes de caractères et les arguments de
programme.
Exercice 1 (document séparé / niveau 0): transmission d’arguments au
programme
Exercice 2 pointeur de pointeur illustré sur un tableau de chaînes de caractères
(niveau 2)
Un nom de tableau à un seul indice est équivalent à un simple pointeur (constant).
Un nom de tableau à deux indices tel que tab dans la déclaration suivante :
char tab[3][2]
doit être interprété comme « l’adresse du tableau des pointeurs des lignes» ; en effet
le langage C range un tableau à 2 indices ligne par ligne en mémoire. Chaque ligne
est vue comme un tableau à un indice.
Donc du point de vue du type, rappelons que le nom d’un tableau à un seul indice
contenant des char est un pointeur de type char*. Par exemple, avec la déclaration
suivante char t1[5], le type du nom du tableau utilisé seul, t1, est char*.
Il en est de même pour une ligne d’un tableau à deux indices de char tel que dans la
déclaration char tab[3][2]. Le nom d’une ligne est donné en utilisant un seul indice,
par exemple tab[0] désigne la première ligne du tableau tab et son type est : char *
Pour l’exemple char tab[3][2], le nom du tableau à deux indices tab a pour type
adresse de la première ligne (contenant 2 valeurs de type char), ce qui donne
(char [2]) * que l’on peut aussi écrire char [2] *.
Une illustration de la nature de ce type est que l’expression tab+1 est l’adresse de “la
ligne d’indice 1” ce qui montre bien que la taille de l’objet pointé par tab est une
ligne entière.
Nous allons maintenant voir un tableau qui ressemble au tableau tab mais présente
néanmoins des différences importantes. Il s’agit d’un tableau de pointeurs de
chaînes de caractères constantes, comme illustré par le tableau t dans le code
suivant. La première différence est que chaque chaîne peut avoir une longueur
différente des autres. Le type du tableau t est d’être l’adresse du premier élément du
tableau, ce qui donne (char *) * que l’on peut aussi écrire char**. C’est un pointeur de
pointeur.
Si on fait une seule indirection sur ce nom de tableau, avec l’expression *t, on obtient
la valeur du premier élément du tableau t ; la valeur de ce premier élément est aussi
obtenue avec l’expression t[0]. C’est l’adresse de la première chaîne de caractères
constante. Si on fait deux indirections, avec l’expression **t, c’est équivalent à *t[0],
ce qui fournit le premier caractère de la première chaîne constante.
Un but de cet exercice est de se familiariser avec la représentation avec boite et
flèche comme dans le cours. En effet l’adresse des variables n’est pas connue tant
que le code n’est pas compilé et de toutes façon une flèche suffit pour indiquer qu’un
pointeur pointe sur une variable ou un élément de tableau, ou un début de ligne de
tableau.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <string.h>
int main(void)
{
char * t[]= {"Rome","Oslo","Bern","Wien"};
char * a_ptr = t[1];
char * b_ptr = t[2];
char ** p = t;
a_ptr += 2;
printf("%d\n",strlen(a_ptr));
printf("%c\n",*b_ptr + 1);
p += 3 ;
printf("%s\n",*p);
printf("%c\n",**p);
return 0;
}
2.1) Dessinez à droite du code source, l’état initial correspondant aux déclarations
jusqu’à la ligne 10 incluse avec des boites et des flèches.
2.2) Dessinez l’état de toutes les variables après exécution des instructions jusqu’à la
ligne 21 incluse avec des boites et des flèches et ce qui est affiché par printf .
2.3) Que se passe-t-il si vous ajoutez l’instruction **p = ‘X’; , par exemple après
la ligne 21 du programme ? Compile-t-il ? y a t-il un warning ? Que se passe-t-il à
l’exécution?
Exercice 3 (niveau 1): Chaines de caractères
Déterminez le résultat de l'exécution du programme suivant sans le compiler:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (void)
{
char s1[] = "bonne";
char s2[] = "journee";
char resul[] = "...........";
strcpy( resul+2, s1 );
strncpy( resul+5, s2, 4
);
printf( "%s \n", resul );
}
return EXIT_SUCCESS;
Exercice 4 (niveau 1): Une petite calculatrice
Il est parfois intéressant de pouvoir passer des arguments directement à un
programme plutôt que de devoir les saisir après le lancement du programme. Vous
pouvez par exemple penser aux différentes commandes Linux que vous avez déjà
utilisées et qui ne sont rien d'autres que de petits programmes auxquels vous passez
directement les arguments dont ils ont besoin. Par exemple:
cp prog.c /home/dupond/serie1
Dans cet exemple, le programme cp est appelé en lui spécifiant que son premier
argument est "prog.c" et que le second est "/home/dupond/serie1".
Reprenez le programme de la série7 et modifiez le de manière à entrer l'expression à
calculer directement en ligne de commande.
Exemples:
calculatrice.x 789 + 486
Résultat: 1275.000000
calculatrice.x 789 o 486
ERREUR: opération invalide.
calculatrice.x 789.+ 486.
Le nombre d'arguments n'est pas correct!!
Remarques:
●
Vous devez séparer les arguments par un espace (c’est la raison de l’échec
signalé par le troisième exemple d’exécution: il manque un espace entre le . et
le +)
●
Utilisez un 'x' au lieu d'un '*' pour spécifier la multiplication pour éviter que le
shell ne l'interprète (et ne le considère comme indiquant tous les fichiers du
répertoire courant).
Les arguments de programme sont de type chaine de caracteres. Lisez le document
niveau0 qui expllique la conversion d’une chaine vers une valeur numérique.