IN3T01 Programmation C TP 3 corrigé. exercices rédigés et corrigés par J.C Georges et Michel Landschoot

Documents pareils
Introduction au langage C

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

I. Introduction aux fonctions : les fonctions standards

Algorithmique et Programmation, IMA


INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Seance 2: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu.

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

Quelques éléments de compilation en C et makefiles

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

Chap III : Les tableaux

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Introduction à la programmation Travaux pratiques: séance d introduction INFO0201-1

Travaux pratiques. Compression en codage de Huffman Organisation d un projet de programmation

Programmation C++ (débutant)/instructions for, while et do...while

Cours Programmation Système

Recherche dans un tableau

Le Langage C Version 1.2 c 2002 Florence HENRY Observatoire de Paris Université de Versailles florence.henry@obspm.fr

Le langage C++ est un langage de programmation puissant, polyvalent, on serait presque tenté de dire universel, massivement utilisé dans l'industrie

Cours d initiation à la programmation en C++ Johann Cuenin

Cours d Algorithmique et de Langage C v 3.0

Programme Compte bancaire (code)

1. Structure d'un programme FORTRAN 95

Le prototype de la fonction main()

Le langage C. Séance n 4

Licence Sciences et Technologies Examen janvier 2010

Programmation système I Les entrées/sorties

INITIATION A LA PROGRAMMATION

03/04/2007. Tâche 1 Tâche 2 Tâche 3. Système Unix. Time sharing

Brefs rappels sur la pile et le tas (Stack. / Heap) et les pointeurs

Cours de C++ François Laroussinie. 2 novembre Dept. d Informatique, ENS de Cachan

Algorithmique I. Algorithmique I p.1/??

Utilisation d objets : String et ArrayList

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Représentation d un entier en base b

Compression de Données - Algorithme de Huffman Document de Conception

Cours Langage C/C++ Programmation modulaire

TD3: tableaux avancées, première classe et chaînes

Initiation. àl algorithmique et à la programmation. en C

PROJET ALGORITHMIQUE ET PROGRAMMATION II

TP 1. Prise en main du langage Python

Bases de programmation. Cours 5. Structurer les données

Initiation à la programmation en Python

Architecture des ordinateurs

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

Quelques algorithmes simples dont l analyse n est pas si simple

INF2015 Développement de logiciels dans un environnement Agile. Examen intra 20 février :30 à 20:30

Algorithmique, Structures de données et langage C

Java Licence Professionnelle CISII,

Programmation système de commandes en C

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

MISE A NIVEAU INFORMATIQUE LANGAGE C - EXEMPLES DE PROGRAMMES. Université Paris Dauphine IUP Génie Mathématique et Informatique 2 ème année

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

Conventions d écriture et outils de mise au point

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

Analyse de sécurité de logiciels système par typage statique

Premiers Pas en Programmation Objet : les Classes et les Objets

Chapitre 10. Les interfaces Comparable et Comparator 1

Claude Delannoy. 3 e édition C++

OS Réseaux et Programmation Système - C5

Cours 1 : Introduction Ordinateurs - Langages de haut niveau - Application

Travaux Dirigés n 1 : chaînes de caractères

Les arbres binaires de recherche

Suivant les langages de programmation, modules plus avancés : modules imbriqués modules paramétrés par des modules (foncteurs)

INF111. Initiation à la programmation impérative en C amini/cours/l1/inf111/ Massih-Reza Amini

V- Manipulations de nombres en binaire

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Perl Orienté Objet BioPerl There is more than one way to do it

Les chaînes de caractères

as Architecture des Systèmes d Information

PIC EVAL Dev Board PIC18F97J60

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

Initiation à l algorithmique

SUPPORT DE COURS. Langage C

Algorithmique & Langage C IUT GEII S1. Notes de cours (première partie) cours_algo_lgc1.17.odp. Licence

Plan du cours. Historique du langage Nouveautés de Java 7

Derrière toi Une machine virtuelle!

Les structures de données. Rajae El Ouazzani

Outils pour la pratique

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

1 Définition et Appel d une fonction. V. Phan Luong. Cours 4 : Fonctions

ARDUINO DOSSIER RESSOURCE POUR LA CLASSE

TP : Gestion d une image au format PGM

Langage Éric Guérin 5 octobre 2010

Introduction à la Programmation Parallèle: MPI

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

Programmation en langage C d un µcontrôleur PIC à l aide du compilateur C-CCS Sommaire

Le langage C. Introduction, guide de reference

Programmation C. J.-F. Lalande. 15 novembre 2012

Département Automatisation et Informatisation Année Programmation en C++ Institut des Sciences et Techniques de l Ingénieur d Angers

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Rappel. Analyse de Données Structurées - Cours 12. Un langage avec des déclaration locales. Exemple d'un programme

Programmation en langage C

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

Cours Informatique Master STEP

Programmation système en C/C++

Algorithmes et Programmes. Introduction à l informatiquel. Cycle de vie d'un programme (d'un logiciel) Cycle de vie d'un programme (d'un logiciel)

Transcription:

ESIEE 2011 2012 IN3T01 Programmation C TP 3 corrigé exercices rédigés et corrigés par J.C Georges et Michel Landschoot http://www.esiee.fr/~landschm/in3t01/ Objectifs: réussir ses premiers pas sur les chaînes de caractères en langage C, Notions abordées: pointeurs, chaînes de caractères, fonctions avec un pointeur de caractères en paramètre Écrivez un programme pour tester toutes les fonctions programmées dans les exercices suivants. Déclarations prototypes des fonctions: fichier chaine.h. Définition des fonctions: fichier source chaine.c. Programme de test avec les appels des fonctions sur les chaînes: fichier source testchaine.c Penser à inclure chaine.h dans les 2 fichiers sources. Directives de compilation: gcc -c chaine.c gcc -c testchaine.c gcc chaine.o testchaine.o -o testchaine ==> génération du binaire chaine.o ==> génération du binaire testchaine.o ==> édition de liens et génération de l'exécutable testchaine. NOTATION TABLEAU fichier chaine.h #ifndef CHAINE_H #define CHAINE_H int chaine_vers_entier (char * s); char * miroir (char * s); int debute_par (char * chaine1, char * chaine2); int presence (char * chaine1, char * chaine2); int compte (char c, char * s); int compte2 (char c, char * s); char * cherche_remplace (char c, char r, char * s); #endif

fichier chaine.c #include <stdio.h> #include "chaine.h" Exercice 1: Conversion chaîne de caractères en entier Écrivez une fonction qui prend en argument une chaîne de caractères représentant un entier en décimal et retourne l entier équivalent ( "123"! 123). On supposera que la chaîne est correcte et représente bien un entier. Prototype : int chaine_vers_entier (char * s); Une chaîne représentant un entier est composée d'une suite de caractères chiffres (compris entre '0' et '9'), éventuellement précédée d'une caractère '-' ou '+'. L'entier correspondant à un caractère chiffre est égal à ce caractère moins le caractère '0'. ('2 '- '0' ==> 2) S'il y a un signe, on le mémorise sous la forme d'une variable valant 1 ou +1. Puis, on accumule dans un résultat le nombre représenté selon le principe suivant : pour chaque chiffre, on multiplie par 10 la valeur accumulée et on ajoute la valeur du chiffre. En fin de calcul, on retourne le résultat multiplé par le signe. int chaine_vers_entier (char * s) int i = 0,signe = 1, res = 0; if (s[i] == '+') ++i; else if (s[i] == '-') signe = -1; ++i; for ( ; s[i]!= '\0'; ++i ) res = res * 10 + (s[i] - '0'); return signe * res;

Exercice 2: Miroir Écrivez une fonction qui prend en argument une chaîne de caractères, la renverse sur elle-même et retourne l adresse de cette chaîne. Exemple: le miroir de "toto " est "otot". Prototype : char * miroir (char * s); Il faut déjà parcourir la chaîne pour accéder à son dernier caractère. Puis permuter les couples de caractères symétriques en évitant de le faire deux fois, ce qui laisserait la chaîne inchangée. char * miroir (char * s) int g, d; /* indices gauche et droit de parcours */ char c; for (d = 0; s[d]!= '\0'; ++d); for (g = 0, --d; g < d ; ++g, --d) c = s[g]; s[g] = s[d]; s[d] = c; return s;

Exercice 3: Recherche de motif (1) Écrivez une fonction qui prend en argument deux chaînes de caractères et retourne 1 si la première chaîne commence par la seconde et 0 sinon. Prototype : int debute_par (char * chaine1, char * chaine2); Il sufft de regarder pour chaque caractère de chaine2 s'il est égal au caractère correspondant de chaine1. Dès qu'il y a inégalité, on retourne 0 (faux). Si on arrive en bout de chaine2 sans avoir détecté d'inégalité, on retourne 1 (vrai). Note : ce programme renvoie toujours 1 si la chaine2 est vide. int debute_par (char * chaine1, char * chaine2) int i; for (i = 0; chaine2[i ]!= '\0'; ++i) if ( chaine1[i]!= chaine2[i]) return 0; return 1;

Exercice 4: Recherche de motif (2) Écrivez une fonction qui prend en argument deux chaînes de caractères et retourne la position de la première occurrence de la chaîne2 dans la chaîne1 si elle y est présente et 1 sinon. Prototype : int presence (char * chaine1, char * chaine2); Un appel itératif à debute_par permettra de détecter la présence de la sous-chaîne. Note : ce programme considère que la chaîne vide débute toute chaîne (retour 0). int presence (char * chaine1, char * chaine2) int i; for (i = 0; chaine1[i ]!= '\0'; ++i) if (debute_par(&chaine1[i], chaine2)) return i; return -1; Exercice 5: Fréquence Écrivez une fonction qui compte le nombre d occurrences d un caractère c dans une chaîne s. La fonction pourra être récursive. Écrivez un programme pour tester cette fonction. Prototype : int compte (char c, char * s); C'est encore un accumulateur : int compte (char c, char * s) int i, acc = 0; for (i = 0; s[i]!= '\0'; ++i) if (s[i] == c) ++acc; return acc;

Une fonction récursive peut être écrite selon le principe suivant : int compte2 (char c, char * s) if (*s == '\0') /* s [0] == '\0' */ return 0; return ((*s == c )? 1 : 0) + compte2 (c,s + 1); Exercice 6:. Chercher/remplacer Écrivez une fonction qui recherche dans une chaîne chaque caractère c pour le remplacer par un caractère r et retourne l adresse de la chaîne. Prototype : char * cherche_remplace (char c, char r, char * s); C'est un parcours simple avec remplacement lorsque l'on tombe sur le caractère à remplacer. char * cherche_remplace (char c, char r, char * s) int i; for (i = 0; s[i]!= '\0'; ++i) if (s[i] == c) s[i] = r; return s; fichier testchaine.c #include <stdio.h> #include "chaine.h" int main(void) int chaineversentier; char tab[] = "In girum imus nocte et consumimur igni: gag eht"; int debutepar, present, compteur, compteur2;

chaineversentier = chaine_vers_entier ("757"); printf("chaine: 757 convertie en nombre %d \n", chaineversentier); printf("chaine: %s \n", tab); // retour de miroir non utilisé cf strcpy... miroir (tab); printf("chaine inversée: %s \n", tab); // on se remet dans le bon sens de lecture! */ miroir(tab); debutepar = debute_par (tab, "In girum"); if (debutepar == 1) printf("%s débute par In girum \n", tab); else printf("%s ne débute pas par In girum \n", tab); present = presence (tab, "nocte"); if (present!= -1) printf("%s contient nocte \n", tab); else printf("%s ne contient pas nocte \n", tab); compteur = compte ('e', tab); printf("%d e dans %s \n", compteur, tab); compteur2 = compte2 ('e', tab); printf("%d e dans %s \n", compteur2, tab); // retour de cherche_remplace non utilisé cf strcpy... printf("chaine: %s \n", tab); printf("==> e à remplacer par E \n"); cherche_remplace ('e', 'E', tab); printf("chaine: %s \n", tab); return 0;

NOTATION POINTEUR Les algorithmes sont les mêmes que ceux de la notation tableau. L'arithmétique des pointeurs est mise en oeuvre. fichier chainenotationpointeur.h #ifndef CHAINE_NOTATIONPOINTEUR_H #define CHAINE_NOTATIONPOINTEUR_H int chaine_vers_entier_pointeur (char * s); char * miroir_pointeur (char * s); int debute_par_pointeur (char * chaine1, char * chaine2); int presence_pointeur (char * chaine1, char * chaine2); int compte_pointeur (char c, char * s); int compte2_pointeur (char c, char * s); char * cherche_remplace_pointeur (char c, char r, char * s); #endif fichier chainenotationpointeur.c #include <stdio.h> #include "chainenotationpointeur.h" int chaine_vers_entier_pointeur (char * s) int signe = 1, res = 0; if (*s == '+') ++s; else if (*s == '-') signe = -1; ++s;

for ( ; *s!= '\0'; ++s ) res = res * 10 + (*s - '0'); return signe * res; char * miroir_pointeur (char * s) char * g, * d; /* pointeurs gauche et droit de parcours */ char c; for (d = s; *d!= '\0'; ++d); for (g = s, --d; g < d ; ++g, --d) c = *g; *g = *d; *d = c; return s; int debute_par_pointeur (char * chaine1, char * chaine2) while(*chaine2!= '\0') if ( *chaine1!= *chaine2) return 0; chaine1++; chaine2++; return 1;

int presence_pointeur (char * chaine1, char * chaine2) while (*chaine1!= '\0') if (debute_par_pointeur(chaine1, chaine2)) return 1; chaine1++; return -1; int compte_pointeur (char c, char * s) int acc = 0; while (*s!= '\0') if ( *s == c) ++acc; s++; return acc; int compte2_pointeur (char c, char * s) if (*s == '\0') /* s [0] == '\0' */ return 0; return ((*s == c )? 1 : 0) + compte2_pointeur (c,s + 1); char * cherche_remplace_pointeur (char c, char r, char * s) int i; for (i = 0; s[i]!= '\0'; ++i) if (s[i] == c) s[i] = r;

return s; fichier testchainenotationpointeur.h #include <stdio.h> #include "chainenotationpointeur.h" int main(void) int chaineversentier; char tab[] = "In girum imus nocte et consumimur igni: gag eht"; int debutepar, present, compteur, compteur2; chaineversentier = chaine_vers_entier_pointeur ("757"); printf("chaine: 757 convertie en nombre %d \n", chaineversentier); printf("chaine: %s \n", tab); // retour de miroir non utilisé cf strcpy... miroir_pointeur(tab); printf("chaine inversée: %s \n", tab); // on se remet dans le bon sens de lecture! */ miroir(tab); debutepar = debute_par_pointeur(tab, "In girum"); if (debutepar == 1) printf("%s débute par In girum \n", tab); else printf("%s ne débute pas par In girum \n", tab); present = presence_pointeur (tab, "nocte"); if (present!= -1) printf("%s contient nocte \n", tab); else printf("%s ne contient pas nocte \n", tab);

compteur = compte_pointeur ('e', tab); printf("%d e dans %s \n", compteur, tab); compteur2 = compte2_pointeur ('e', tab); printf("%d e dans %s \n", compteur2, tab); // retour de cherche_remplace non utilisé cf strcpy... printf("chaine: %s \n", tab); printf("==> e à remplacer par E \n"); cherche_remplace_pointeur ('e', 'E', tab); printf("chaine: %s \n", tab); return 0;