LangageC DiopUT
LangageC DiopUT
Efficacité -Rapidité?
- Lisible
- Structuré
int main(void)
{
void main(void): La fonction main ne prend
/* corps du programme*/
début aucun paramètre et ne retourne pas de valeur.
declaration des Cstes et Var ;
instruction1 ; int main(void): La fonction main retourne une
valeur entière à l'aide de l'instruction return (0
instruction2 ; si pas d’erreur).
….
int main(int argc, char *argv[]): On obtient
}
alors des programmes auxquels on peut
fin adresser des arguments au moment où on lance
le programme.
Entre accolades "{" et "}" on
mettra la succession d'actions à
réaliser.(Bloc)
void main()
{ /* début du bloc de la fonction main*/
int i; /* définition des variables locales */
Programme
i=0; principal
fonc1(i) ;
fonc2(i) ;
} /* fin du bloc de la fonction main */
int fonc1(int x) {
return x; Définitions des
}
fonctions
int fonc2(int x) {
return (x * x);
}
Langage C : Prof. PAPA DIOP 9
Indenter = lisibilté #include <Lib1.h>
#include <Lib2.h>
Prenez l'habitude de respecter (au moins au début) les #define X 0;
règles :
int fonc1(int x);
- une accolade est seule sur sa ligne, float fonc2(char a);
- { est alignée sur le caractère de gauche de la ligne
précédente, int main(void)
Inclusion de fichiers
#include <nom-de-fichier> /* répertoire standard */
#include "nom-de-fichier" /* répertoire courant */
SALAMALEK
printf(" SALAM ALEK ") ;
Exemple :
printf("Qu'il est agreable d’utiliser printf "
"en\t C,\nlorsqu'on l'utilise \"proprement\".\n");
Variables : initialisations
Les variables doivent être déclarées avant leur utilisation dans un début de bloc (juste après{),
zone des déclarations:
char c;
int i;
float x;
Exemple :
void main()
{ Le compilateur réserve de
const float PI = 3.14159; la place en mémoire (ici 4 octets).
const int JOURS = 5;
float perimetre, rayon = 8.7;
perimetre = 2*rayon*PI;
.... /*ERREUR !*/ On
JOURS = 3; ! ne peut changer la valeur
.... d’une constante.
}
Langage C : Prof. PAPA DIOP 21
Identificateurs
Les identificateurs nomment les objets C (fonctions, variables ... )
Identificateurs valides :
xx y1 somme_5 _position
Noms surface fin_de_fichier VECTEUR
Identificateurs invalides :
3eme commence par un chiffre
x#y caractère non autorisé (#)
no-commande caractère non autorisé (-)
taux change caractère non autorisé (espace)
Langage C : Prof. PAPA DIOP 22
Un identificateur ne peut pas être un mot réservé du langage :
+ addition
- soustraction
* multiplication
/ division
% modulo (reste de la division entière )
7/2 3
7.0/2
7/2.0
7.0/2.0
3.5
k = i / j;
h = f / g;
h = 5/4 = 1.0000 h = i / j;
}
i = 7; f = 5.5; c = 'w';
!expr1 est vrai si expr1 est faux et faux si expr1 est vrai ;
expr1&&expr2 est vrai si les deux expressions expr1 et expr2 sont vraies et
faux sinon. L'expression expr2 n'est évaluée que dans le cas où l'expression
expr1 est vraie ;
#include <stdio.h>
int main(void)
{
équivalent à:
int i, j = 5;
1. j++;
i = ++j;
2. i = j; !
printf("i=%d, j=%d\n", i, j);
j = 5; équivalent à:
i = j++; 1. i = j;
printf("i=%d, j=%d\n", i, j); 2. j++; !
return 0;
} i=6, j=6
i=5, j=6
Langage C : Prof. PAPA DIOP 30
Les Conversions de types
Le langage C permet d'effectuer des opérations de conversion de type.
On utilise pour cela l'opérateur de "cast" ().
#include <stdio.h>
#include <conio.h>
void main() Conversion float -> int: 89.67 -> 89
{
Conversion int -> float: 4660 -> 4660.00
int i=0x1234, j;
char d,e; Conversion int -> char: 1234 -> 34
float r=89.67,s; Conversion float -> char: 89.67 -> 89
j = (int)r;
Pour sortir frapper une touche
s = (float)i;
d = (char)i;
e = (char)r;
printf("Conversion float -> int: %5.2f -> %d\n",r,j);
printf("Conversion int -> float: %d -> %5.2f\n",i,s);
printf("Conversion int -> char: %x -> %x\n",i,d);
printf("Conversion float -> char: %5.2f -> %d\n",r,e);
printf("Pour sortir frapper une touche ");
getch(); // pas getchar
}
Langage C : Prof. PAPA DIOP 31
Les structures de contrôle en C
Alternative: if-else
Choix Multiple: switch-case
Itérations: for, while, do-while
Rupture de Contrôle: break, continue, return … goto
if(32)
printf("ceci sera toujours affiche\n");
if(0)
printf("ceci ne sera jamais affiche\n");
int main(void)
{
int i = 0;
return 0;
}
Quand i != de zero
int i = 100;
if(i > 0)
if(i > 1000)
printf("i > 1000\n");
else
printf("i is reasonable\n"); i is reasonable
int i = 100;
if(i > 0) {
if(i > 1000)
printf(" i > 1000 \n");
} else
printf("i is negative\n");
int i, j, k;
for( ; ; )
{ for(i = 0, j = 2, k = -1; (i < 20) &&(j==2); i++, k--)
............; /* bloc d'instructions */
............;
............;
}
int j = 5;
start
tant que, pas jusqu’à ce que! printf("start\n"); end
while(j == 0)
printf("j = %d\n", j--);
printf("end\n");
i=1;
while(i<5);
{ "tant que l'expression est vraie
printf(“Intérieur %d\n",i); attendre".
i++;
}
default : printf("\nCE CHOIX N'EST PAS PREVU "); /* pas de break ici */
}
Break;
# Continue; 8
int i, j=1; for (i = -10; i <= 10; i++)
char a; {
for (i = -10; i <= 10; i++){ if (i == 0)
continue;
while(j!=0) /* boucle infinie */ // pour éviter la division par zéro
{ printf(“ %f”, 1 / i);
a=getchar(); }
if(a= ='x')
break;
} return (expression);
} permet de sortir de la fonction qui la contient
Exemples:
enum couleur {bleu, blanc, rouge, vert, jaune, noir} ;
enum jour {Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi, Dimanche} ;
Après avoir défini un type énuméré, on peut l'utiliser pour déclarer une
ou plusieurs variables de ce type.
Exemples:
enum jour j1;
enum jour j2 = Mardi;
Langage C : Prof. PAPA DIOP 46
ENUMERATIONS (3/3)
Voici un programme qui manipule un type énuméré pour les jours de la semaine :
#include <stdio.h>
#include <conio.h>
enum Jour {lundi=1,mardi,mercredi,jeudi,vendredi,samedi,dimanche};
int main()
{
enum Jour un_jour ;
printf("Donnez un numéro de jour entre 1 et 7") ; scanf("%d", &un_jour) ;
switch(un_jour )
{
case lundi : printf("C’est Lundi"); break ;
case mardi : printf("C’est Mardi"); break ;
case mercredi : printf("C’est Mercredi"); break ;
default : printf("Ce n’est ni Lundi ni Mardi ni Mercredi");
}
getch() ;
return 0 ;
}
Langage C : Prof. PAPA DIOP 47
TABLEAUX : Introduction
Déclaration de tableaux
Un tableau (array) est une collection de variables de même type, appelées éléments
désignés par un identificateur unique.
On les déclare par un type, un nom et une dimension (CONSTANTE) placée entre [ ]
Le C alloue toujours un tableau dans une zone contigüe de la mémoire
Une fois déclaré, on ne peut redimensionner un tableau
Exemples
int tab[4]; déclare un tableau de 4 valeurs entières tab[0] tab[1] tab[2] tab[3]
!
#define SIZE 10
int a[SIZE]; /* a est un vecteur de 10 entiers */
le compilateur réserve SIZE places en mémoire pour ranger les éléments du tableau.
printf("Celsius\tFarenheit\n");
for(d = start; d <= end; d += step, lines++)
printf("%.1lf\t%.1lf\n", d, d * 1.8 + 32);
return lines;
}
Valeur renvoyée
Langage C : Prof. PAPA DIOP 53
Appeler une fonction
IMPORTANT: cette instruction spécifie comment la fonction est définie
#include <stdio.h>
void main(void)
{
int combien; Le compilateur attend des
double end = 100.0; doubles; les conversions sont
automatiques
combien = print_table(1.0,end,3);
print_table(end, 200, 15);
}
Ici, on ne tient pas compte de la valeur de retour
Val = addition();
printf(“val = %d”, Val);
}
int addition()
{
float tmp;
tmp = calcule(2.5,3) + calcule(5,7.2);
return (int)tmp;
}
void main(void)
{
int var = 5;
void change(int v)
{
v *= 100;
printf("change: v = %d\n", v);
}
void main(void){
int var = 5;
int valeur;
valeur = change(var);
change: v =
printf("main: var = %d\n", var); main: var =
printf("main: valeur = %d\n", valeur); main: valeur =
}
int change(int v)
{
v *= 100;
printf("change: v = %d\n", v);
return (v+1);
}
#include <stdio.h>
void main(void){
int var = 5;
int valeur;
valeur = return_Val(var);
return_Val : rien
printf("main: var = %d\n", var); main: var =
printf("main: valeur = %d\n", valeur); main: valeur =
}
int return_Val(int v)
{
if (v == 10) return (2*v);
else return (3*v);
}
void main(void){
int var = 5, int valeur;
valeur = return_Val(var);
printf("main: var = %d\n", var);
printf("main: valeur = %d\n", valeur); return_Val : rien
} main: var =
main: valeur =
int fact(int n) {
return (n<2?1:((int)n*fact(n-1));
}
(0)=0*fact(-1)
int return_Val(int v)
{ int temp=1;
if (v == 10) return (2*v); while(n>1) temp*=n--;
else return fact(v);
}
if (n<2 ) {
return 1;
} return(n<2?1:((int)n*fact(n-1));
else {
return ((int)n*fact(n-1));
}
7 12
void somme(int a[], int n){
11 18
int i;
for(i = n-1; i >0 ; i--)
a[i] += a[i-1];
}
Langage C : Prof. PAPA DIOP 65
Exemple: transposition d'une matrice
void transpose ( float a[][20], int m, int n);
void main(void)
{float matrice [100][20]; /* matrice (100,20) */
/*…*/
transpose (matrice, 3, 2);
}
A- Saisie et affichage
B- Moyenne
C- Suppression du Max et affichage
D- Suppression du Min et affichage
E- Ajout d’un entier à une position donnée
Q- Quitter
char other[] = "Tony Bloot"; 'T' 'o' 'n' 'y' 32 'B' 'l' ‘o' ‘o' 't' 0
char characters[7] = "No null"; 'N' 'o' 32 'n' 'u' 'l' 'l'
Pas de ‘\0’
Langage C : Prof. PAPA DIOP 69
Entrées/Sorties Standards
E F G H
• getchar() : 7 lire un caractère sur entrée standard (valeur -1 = EOF = fin)
main(){
char c; main(){
c = getchar(); char c;
while (c != EOF) { while ( (c=getchar())!= EOF)
putchar(c); putchar(c);
c = getchar(); }
}
}
• Fichiers stdin et stdout: Tout programme lit ou écrit sur ces fichiers (défaut clavier et écran).
int i = 0;
last_name[3] = ‘\0’; Min
while(last_name[i] != '\0')
printf("%c", last_name[i++]);
printf("\n");
} printf("%s\n", last_name);
puts(last_name);
Une chaîne : pas de symbole &. On utilisera de préférence la fonction gets non
!
formatée.
#include <stdio.h>
#include <string.h>
Affectation de strings :
Les strings peuvent être void main(void) {
initialisés avec “=”, char who[] = "Tony Bloot";
mais pas affectés avec “=”
(ce sont des tableaux!) who = "John Minor";
strcpy(who, "John Minor");
}
void main(void)
{
int L,i=0;
char s[9] = "midi", u[11] = "avant", v[10] = "soir";
char text[80]; text[i] = getchar();
while ( text[i] != EOL ) {
While ( (text[i] = getchar() ) != EOL ) i++; i++;
text[i] = getchar();
puts(text);
}
L = strlen(s); /* L = 4 */
for (i=0;i<L;i++) {
putchar(toupper(s[i])); /* M, I, D,I */
}
void main() {
int a = 5 , b = 8;
ech(a,b);
Syntaxe qui conduit à une erreur
printf(“ a=%d\n ”, a) ;
a=5
printf(“ b=%d\n ”, b) ;
} b=8
i=17
5A0F3 17
p=5A0F3 p i
Un pointeur est une adresse mémoire. On dit que le
pointeur p pointe vers i, puisque p pointe vers
l’emplacement mémoire où est enregistrée i.
Langage C : Prof. PAPA DIOP 78
Les pointeurs: pourquoi ?
Les pointeurs sont nécessaires pour:
nom_de_Pointeur = &nom_de_variable
void main(void)
p c
{
0x1132 'a'
char c = 'a', d = 'z';
0x1132
char *p;
p d
0x91A2 'z'
*p = c; 0x91A2
p = &c;
printf("%c\n", *p);
p = &d; L’opérateur * (“valeur pointée par”)
printf("%c\n", *p);
} a
z
Langage C : Prof. PAPA DIOP 81
#include <stdio.h>
void main() {
int *p, x, y;
p = &x; /* p pointe sur x */
x = 10; /* x vaut 10 */
y = *p - 1; printf(" y= *p - 1 =? = %d\n" , y); y vaut ?
*p += 1; printf(" *p += 1 =? *p = x= ? = %d %d\n" , *p, x); x vaut ?
(*p)++; printf(" (*p)++ =? *p = x= ? = %d %d alors y=%d \n" , *p, x, y);
incrémente aussi de 1 la variable pointée par p, donc x vaut ??.
y vaut 9
printf("%d\n", a[3]); 40
printf("%d\n", *(a + 3)); 40
printf("%d\n", *(p + 3)); 40
printf("%d\n", p[3]); 40
p a
1000 10 20 30 40 50 60 70 80
1000 1004 1008 1012
1002 1006 1010 1014
pointeur
char *adr;
printf("TAPER UNE LETTRE: ");
scanf("%c",adr);
adr1 = (float*)malloc(4*sizeof(float));
La réservation d'espace est à la adr2 = (float*)malloc(10*sizeof(float));
charge du programmeur qui doit texte = (char*)malloc(10);
le faire de façon explicite, en
utilisant les fonctions standard *adr1 = -37.28;
*adr2 = 123.67;
malloc(), … qui sont
printf("adr1 = %p adr2 = %p r1 = %f
prototypées dans <stdlib.h> et r2 = %f\n",adr1,adr2,*adr1,*adr2);
<alloc.h> free(adr1); // Libération de la mémoire
free(adr2);
free(texte);
}
Langage C : Prof. PAPA DIOP 94
sizeof
void main()
{
int i;
char c;
caractère : 1
float f;
entier : 2 ou 4
double d;
réel : 4
printf (‘’caractère : %d \n ‘’, sizeof c);
double : 8
printf (‘’entier : %d \n ‘’, sizeof i);
printf (‘’réel : %d \n ‘’, sizeof f);
printf (‘’double : %d \n ‘’, sizeof d);
}
void main(){
int i , dim; // compteur et taille du tableau
long* tableau; // pointeur pour stocker l’adresse du tableau
Exemple:
Valable pour réserver de l'espace pour les autres types de données int, float, …
Elles retournent le pointeur NULL (0) si l'espace disponible est insuffisant.
Langage C : Prof. PAPA DIOP 98
Structures en C
Concepts
Créer un type de structure
Créer une instance de structure
Initialiser une instance
Accéder aux membres d’une instance
Passer les structures comme paramètres
Listes chaînées
struct Membre m;
printf(”amendes: ");
for(i = 0; (i < 10) && (m.amende[i] > 0.0); i++)
printf("%.2f Euros", m.amende[i]);
temp = m;
Langage C : Prof. PAPA DIOP 106
Passer des structures comme
paramètres de fonction
Une structure peut être passée, comme une autre
variable, par valeur ou par adresse
Passer par valeur n’est pas toujours efficace
(recopiage à l’entrée)
Passer par adresse ne nécessite pas de recopiage
void Par_valeur(struct Membre m);
void Par_reference(struct Membre *m);
Par_valeur(m);
Par_reference(&m);
Langage C : Prof. PAPA DIOP 107
Quand la structure est un pointeur !
Utiliser p->name
L’écriture p->name est synonyme de (*p)->name,
! où p est un pointeur vers une structure
return result;
}
c3 = add(c1, c2); /* c3 = c1 + c2 */
Langage C : Prof. PAPA DIOP 109
TP
Enoncé
Ecrire un programme permettant de :
struct {
char nom_pren[40]; // nom+pren
char nom[20];
char pren[20];
int NH[NM_max] ; // NM_max=3 : nbre d’heures pr NM_max matières
}
1- Saisie et affichage
2- Construction et affichage
3- Modifier et affichage
4- Tri et affichage
5- Quitter
Langage C : Prof. PAPA DIOP 110
Tri à bulles
while(???){
for j = 0 to …. {
if tab[j] > tab[j+1] {
<on échange tab[j] et tab[j+1]>
}
} 0 1 2 3 4 5 6 j
} 2 6 4 8 12 13 0 tab[j]
6 2
6 4 2 tab[j] < tab[j+1]
6 4 8 2
6 4 8 12 2 ……
13 12 8 6 4 2 0 6 4 8 12 13 2 0
Fonctions d’écriture
int fprintf(FILE* stream, const char* format, ...);
int fputc(int ch, FILE* stream);
int fputs(const char* buffer, FILE* stream);
int feof(FILE *f); /*renvoie une valeur non nulle si fin de fichier*/
La constante NULL (définie comme 0 dans stdio.h) réfère à une adresse non définie
Langage C : Prof. PAPA DIOP 115
Compilation Séparée et édition de Lien
Cas I Cas II
void main()
{ /* début du bloc de la fonction main*/
int i; /* définition des variables locales */
Programme
i=0; principal
fonc1(i) ;
fonc2(i) ;
} /* fin du bloc de la fonction main */
int fonc1(int x) {
return x; Définitions des
}
fonctions
int fonc2(int x) {
return (x * x);
}
Langage C : Prof. PAPA DIOP 117
Structure d'un programme C
#include <stdio.h>
#define DEBUT -10
#define FIN 10
#define MSG "Programme de démonstration\n" Fichier.h
int fonc1(int x);
int fonc2(int x);
#include ‘’Fichier.h’’
void main()
{ /* début du bloc de la fonction main*/
int i; /* définition des variables locales */
Programme
i=0; principal
fonc1(i) ;
fonc2(i) ;
} /* fin du bloc de la fonction main */
int fonc1(int x) {
return x; Définitions des
}
fonctions
int fonc2(int x) {
return (x * x);
}
Langage C : Prof. PAPA DIOP 118
MANIPULATION DES FICHIERS
glob++; }
f += glob; Appel 1 : 0
return f;
} Appel 2 : 1
Langage C : Prof. PAPA DIOP 119
Variables et fonctions externes
Le fichier impose lui aussi un domaine de visibilité. Une variable définie globale au fichier
(en dehors de toute fonction) ne sera alors visible que par les fonctions de ce fichier. Le
problème est de savoir comment exporter cette variable pour d’autres fonctions du
programme (externes au module) si le besoin s’en fait ressentir ?
#include "module.h"
extern int a;
int a = 0;
void fct();
void fct() { a++; }
Fichier "main.c"
#include <stdio.h>
#include "module.h"
void main(void) {
fct();
a++;
printf("%d\n",a); // Résultat affiché : 2
}
#ifndef (BOOL)
#define BOOL char /* type boolean */
#endif
#ifdef (BOOL)
BOOL FALSE = 0; /* type boolean */
BOOL TRUE = 1; /* définis comme des variables */
#else
#define FALSE 0 /* définis comme des macros */
#define TRUE 1
#endif Utile pour les fichiers include.
#ifndef _STDIO_H_
#define _STDIO_H_
texte a compiler une fois
…
#endif
return p;
}
Langage C : Prof. PAPA DIOP 124
Nouvelle cellule dans une liste chaînée vide
cellule *debut; Denis\0
debut = (cellule *) malloc (sizeof(cellule)); NULL
strcpy ( debut->name, “Denis”); debut
debut->next = NULL;
Le début de la liste est indiqué par un pointeur indépendant (debut) et la fin par NULL
debut
Langage C : Prof. PAPA DIOP
prec 125
Nouvelle cellule après la
cellule prec
cellule *p;
p = (cellule *) malloc (sizeof(cellule));
strcpy ( p->name, “Alfred”);
p->next = prec->next;
prec->next = p;
Alfred
OK?
p Denis
Claire
Claire Denis
debut NULL
NULL
prec
debut
debut
Langage C : Prof. PAPA DIOP 127
void liberation(liste L){
if (L) {
liste temp = L-
>suivant;
free(L);
liberation(temp);
}
}
• Opérations:
Créer la pile,
Ajouter un élément (Push),
Effacer un élément (Pop),
Eliminer la pile .
Langage C : Prof. PAPA DIOP 129
PUSH procédure
Push(5) 7 3 9 5
Push(9)
NULL
Push(3)
Top Top Top Top
Push(7)
Pop(7) 7 3 9 5
Pop(3)
Underflow risk NULL
Pop(9) si la pile est vide !!!
Top Top
Top Top
Top Top
Top
Pop(5)
{
int data; /* les informations */
struct Node *next; /* le lien : pointeur sur la cellule suivante */
}
Push(6) 0 2 4 6
Push(4)
NULL
Push(2)
debut Top Top Top
Push(0)
2 : Sauvegarde la liste dans le fichier Liste1
3 : Insère dans la liste –1, puis 1, puis 3, … et en fin 2n-1.
(Liste finale : -1,0,1,2,3,4,5,6,7,8,9,…2n)
2’ : Sauvegarde la nouvelle liste dans le fichier Liste2
4 : Libère la mémoire avant de quitter le programme.
Langage C : Prof. PAPA DIOP 135
Listes doublement chaînées
struct Node {
int data; /* les informations */
struct Node *prev; /* lien vers le précédent */ data prev next
struct Node *next; /* lien vers le suivant */
};
NULL NULL
debut fin
NULL NULL
debut fin
NULL NULL
act fin
debut
Langage C : Prof. PAPA DIOP 138
Insérer un élément dans la liste pos=qlq
Cell *tmp;
data prev next
tmp = (Cell *) malloc(dim);
tmp->prev = act->prev ;
act->prev->next = tmp;
tmp->next = act;
act->prev = tmp;
tmp
NULL NULL
act
debut fin
NULL NULL
debut fin
NULL NULL
fin
debut