UNIVERSITE ABDELHAMID IBN BADIS MOSTAGANEM
FACULTE DES SCIENCES EXACTES ET DE L’INFORMATIQUE
DEPARTEMENT DE MATHEMATIQUES ET INFORMATIQUE
Cours 1 : Rappel C
Mme Abid
eMail: abidm7475@[Link]
Programme type en C
Un programme C se présente de la manière suivante:
Directives au pré-processeur
Déclaration de variables globales
Déclaration de types composés (types utilisateurs)
Déclaration de fonctions utilisateur
int main ()
{
déclaration des variables internes
instructions
}
Définition fonction utilisateurs
M Abid 2
Exemple
# include <stdio.h>
# include <stdlib.h>
Commentaire
int main()
{
Indentation // display Hello world
printf("Hello world\n");
return EXIT_SUCCESS;
}
M Abid 3
Compilation d’un programme C
La compilation a pour objectif de transformer le code source en
code exécutable par une machine.
Ce traitement appelé compilation est réalisé par un programme
spécial appelé un compilateur.
Pré-compilation: applique les directives de préprocesseur (précédé
par un #) pour compléter le code source
Analyse lexicale: identifie les unités lexicales (lexèmes)
Analyse syntaxique: trouve la structure syntaxique (arbre
syntaxique) et teste l’appartenance au langage
Analyse sémantique: trouve le sens des différentes actions voulues
par le programmeur. Quels sont les objets manipulés? Leurs
propriétés? Les actions du programme sur ces objets?
Génération de code: convertit la représentation interne de l’arbre
syntaxique en séquence d’instructions exécutable (code objet)
Edition de lien: différents codes objet sont rassemblés pour
construire le fichier exécutable. Ils proviennent des différents
fichiers sources ou de fonctions externes (bibliothèques). C’est à ce
moment qu’est choisi le point d’entrée dans le programme (main).
M Abid 4
Compilation d’un programme C
Fichiers
sources
Preprocessing Inclut des fichiers .h dans les fichiers sources .c
Compilation Transforme les fichiers .c en fichiers binaires .o
Edition de lien Assemble les fichiers .o et les fichiers .a
(bibliothèques compilées)
Fichier
exécutable
M Abid 5
Bibliothèque
Un programme en C doit absolution contenir une
fonction main
Cette fonction est généralement contenu dans un fichier qui
porte le nom main.c
Le reste des fichiers est ce qu’on appelle des
bibliothèques
Une bibliothèque est une paire de fichiers .c et .h de
même nom et fournissant des fonctionnalités dans une
même thématique
Exemple : xxxx.c et xxxx.h
Les bibliothèques standards sont définies dans la
norme
Exemple : stdlib, stdio, math, time, …
M Abid 6
Fichiers d’une bibliothèque
Le fichier .h (ou header) contient les prototypes
des fonctions : uniquement les en-têtes pas el
corps
À l’inverse le fichier .c complète le .h avec les
définitions des fonctions déclarées dans le .h
M Abid 7
La directive # include
Permet d’utiliser les bibliothèque dans un ficher
source .c
Syntaxe :
# include ‘’ …...h ‘’ Pour une bibliothèque locale
# include < …..h > Pour une bibliothèque standard
include permet également de lier les fichiers .c et
.h formant une bibliothèque
Pour cela #include doit être inséré au début du
fichier .c
M Abid 8
Concepts élémentaires du C
Types , variables, affectation, opérateur de cast
Comparaison et logique
Instruction de contrôle (if, switch, boucles)
Les fonctions
Les pointeurs
Types composés
M Abid 9
Les types
Le C est un langage typé: toute variable ou
constante ou fonction est d’un type précis.
Chaque objet d'un certain type a une longueur de
codage spécifique.
Le type d’un objet définit la façon dont il est
représenté en mémoire.
Utilité: Comment distinguer en mémoire un entier
d'un réel par exemple ?
M Abid 10
Les types prédéfinis en C
Les types prédéfinis en C concernent les caractères,
les entiers et les flottants (les nombres réels)
Les caractères
Mot-clef : char
Les entiers
int
Précédé d’un attribut de précision: short ou long et/ou d’un
attribut de représentation unsigned
Les réelles
float, double et long double servent à représenter des
nombres en virgule flottante.
Ils correspondent aux différentes précisions possibles.
M Abid 11
Les variables
Comment manipuler des valeurs et les garder en
mémoire? c'est grâce aux variables.
une variable a un type, une valeur et un identificateur
une variable peut être vue comme une case mémoire
On peut lire et écrire des valeurs dans cette case
mémoire
En C, pour être utilisée, une variable doit d’abord être
déclarée.
Par exemple:
double x;
x=5.98;
M Abid 12
Identificateurs
Un identificateur est une suite de caractères :
Des lettres (en C les minuscules sont différenciées
des majuscules)
des chiffres
Il est important de choisir un identificateur
significatif
Attention: l'identificateur d'une variable ne
commence jamais par un chiffre (erreur de
compilation)
M Abid 13
Les variables en mémoire
Quand une variable est définie:
il lui est attribué une adresse qui correspond à une
zone mémoire dont la longueur (le nombre d'octets)
est fixée par son type
Une adresse est associée à chaque variable
L'adresse d'une variable var est notée : &var
L'adresse d'une variable n'est pas choisie par le
programmeur, elle est attribuée par le système
qui trouve à partir de cette adresse suffisamment
de place pour stocker cette variable.
M Abid 14
Portée d’une variable
La portée d’une variable est la portion de code
dans laquelle il est possible d’accéder à la variable
Lorsqu’une variable est déclarée à l’extérieur de
tout bloc → variable globale
Lorsqu’une variable est déclarée à l’intérieur d’un
bloc → variable locale
Si deux variables de même nom mais de portée
différente se croise : la variable la plus locale
masque l’autre
M Abid 15
Classes de variables et gestion de la mémoire
en C
En mémoire les variables sont stockés dans différentes
parties selon leurs classes
On distingue trois classes :
Classe statique (variables globales ou locales statiques)
Classe dynamique (variables créées et détruites par demande
explicite lors de l’exécution)
Classe automatique (variables locales + paramètres de
fonction + gestion appels de fonction)
Zone de code machine
Zone
Zone de données statique
Pile (stack)
Zone
Tas (Heap) dynamique
M Abid 16
L’affectation
En C l'affectation est effectuée grâce à
l'opérateur "="
var = val;
val est une expression
la variable var prend la valeur de l'expression val
Attention :
Ne pas confondre l’opérateur de comparaison " == "
avec l’opérateur d’affectation " = "
M Abid 17
La conversion de types
Les règles de conversion suivent les flèches
suivantes:
int -> long -> float -> double -> long double
Convertir un int en float ne fait pas perdre
d'informations car on code sur plus d'espace
Convertir un float en int fait perdre de
l'information (de la précision) puisque l'espace de
code est moindre.
M Abid 18
La conversion de type (2)
Peut-on additionner des int avec des float?
En théorie non car ce sont deux objets avec des
types différents
En pratique on peut grâce aux règles de
conversion
Exemple:
2+2=4 (entier+entier=entier)
5/2=2 (entier/entier=entier)
5.0/2.0=2.5 (la division est de type double)
2.6+3=5.6 (ici le 3 entier a été transformé en 3.0)
M Abid 19
Opérateur de cast
Si a et b sont de type int, comment retourner le
résultat a/b en type float
On peut forcer un changement de type en mettant
entre "()" le type à appliquer à une valeur (float)
(a/b)
Les règles de conversion ne sont valables que
localement.
Par exemple:
Si a est une variable entière alors en dehors de
l’opération de cast (float) a, cette variable reste de
type entier: la conversion n'est pas définitive.
M Abid 20
Comparaison et logique
C dispose des opérateurs classiques de comparaison:
<, <=, >, >=, ==, !=
Par contre, il ne dispose pas des valeurs de vérité vrai
et faux (pas de type booléen)
Le type du résultat de l'application de ces opérateurs
est un entier (type int)
La valeur du résultat est:
0 s'il est faux
toute valeur non nulle si le résultat de la comparaison est
vrai
Les opérateurs logiques en C:
et: &&
ou: ||
non: !
M Abid 21
Tables de vérité des opérateurs logiques
Valeur numérique Valeur de vérité
Non Nul (NN) vrai
0 faux
&& NN 0 || NN 0
NN 1 0 NN 1 1
0 0 0 0 1 0
! NN 0
0 NN
M Abid 22
Les structures conditionnelles
Permettent d'exécuter des instructions sous
certaines conditions
Branchement conditionnel if... else
if(expression) instruction 1 else instruction 2
Le branchement multiple switch
Permet le traitement d'une variable qui peut
prendre différentes valeurs.
switch (expression){
case valeur 1: instruction1; break;
case valeur 2: instruction2; break;
default: instruction;
};
M Abid 23
if…else
if (x % 2 == 0)
if ( x % 4 == 0)
y=2;
else
y = 1;
A quel if appartient le else ?
M Abid 24
if…else
Pour associer else avec un if extérieur il faudra
utiliser des accolades
if (x % 2 == 0) {
if ( x % 4 == 0)
y=2;
}
else
y = 1;
M Abid 25
switch
Ecrire un programme qui affiche le choix d’un
client dans le menu d'un fast food. Le client
choisit son plat à l'aide du numéro correspondant
à chaque plat.
Exemple d’affichage: === Menu ===
1. Cheese burger
2. Panini
3. Pizza
4. Sandwitch
Votre choix ?
2
Vous avez choisi le panini
M Abid 26
#include <stdio.h>
#include <stdlib.h>
int main()
{
int choixMenu;
printf("=== Menu ===\n\n");
printf("1. Cheese burger\n");
printf("2. Panini\n");
printf("3. Pizza \n");
printf("4. Sandwitch\n");
printf("\nVotre choix ? ");
scanf("%d", &choixMenu);
printf("\n");
switch (choixMenu)
{
case 1:
printf("Vous avez choisi le Cheese burger \n");
break;
case 2:
printf("Vous avez choisi le panini \n");
break;
case 3:
printf("Vous avez choisi la pizza\ n");
break;
case 4:
printf("Vous avez choisi le Sandwitch \n");
break;
default:
printf("Vous n'avez pas rentrer un nombre correct. Vous ne mangerez rien du tout !");
}
return EXIT_SUCCESS;
}
M Abid 27
Les boucles
Comment répéter un certain nombre de fois les
mêmes instructions?
En C, il existe trois boucles:
while
do … while
for
Attention aux risques de boucles infinies
M Abid 28
La boucle while
L'instruction while (tant que)
La boucle while permet d'exécuter une suite d'instructions tant que la condition
est vraie
#include <stdio.h>
main()
int a;
printf ("Entrez un entier strictement positifs \n");
scanf("%d", &a);
while(a<=0)
{
printf("Entrez un entier strictement positifs \n");
scanf("%d", &a);
}
printf("L'entier saisi est %d \n", a);
}
M Abid 29
La boucle do...while
do instruction while (expression)
#include <stdio.h>
#include <stdlib.h>
int main() {
int a;
do {
printf("Entrez un entier strictement positifs \n");
scanf("%d", &a);
}
while(a<=0);
printf("L'entier saisi est %d \n", a);
return EXIT_SUCCESS;
}
exécute les instructions (simple ou bloc) puis évalue l'expression
Similaire à while sauf que l'instruction est exécutée au moins une fois au début
M Abid 30
La boucle for
La syntaxe de la boucle for en C est la suivante:
for(expression1;expression2;expression3) instruction
expression 1: est évaluée une fois au début
expression 2: condition de poursuite de la boucle. évaluée avant chaque
exécution d'instruction. si elle est vraie alors on exécute instruction sinon
la boucle est terminée
expression 3: est évaluée à la fin de chaque exécution d'instruction
Equivalence entre while et for:
expression 1;
while (expression 2)
{
instruction;
expression 3;
}
M Abid 31
La boucle for
Que font les instructions suivantes:
int i, var = 0; for(i=0;i<10;var++) printf("%d ",var);
int i; for(i=7;i<12;i--) printf("%d ", i);
int i, a=6; for(i=2;i*i>a;i=i+4) printf("%d ",i);
Attention aux conditions d’arrêt des boucles !
M Abid 32
Les fonctions
Une fonction doit avoir:
un entête comprenant
un nom
un type de retour
un nombre fixe de paramètres (paramètres formels)
un corps comprenant
la déclaration des variables locales utilisables
uniquement dans le corps de la fonction
les instructions qui utilisent les variables locales et les
paramètres de la fonction
un ordre de retour du résultat
M Abid 33
Appel de fonction
Les paramètres effectifs sont évalués lors de l'appel de la fonction
#include<stdio.h> i et j sont les
int max (int i, int j) paramètres
formels
{
int diff;
diff=i-j;
if(diff >= 0)
return i;
else
return j;
}
void main ()
{
int a, b; a et b sont les
paramètres
printf("Entrez deux entiers \n");
effectifs
scanf ("%d%d",&a,&b);
printf ("Le plus grand des deux est: %d\n", max(a,b));
}
M Abid 34
Passage de paramètres
#include<stdio.h>
void modif(int i)
{
printf(" la valeur du paramètre au départ est %d\n", i);
i++;
printf(" la valeur du paramètre après modification est %d\n", i);
}
main()
{
int n=10;
n=10
printf("n=%d\n", n);
la valeur du paramètre au départ est 10
modif(n);
printf("n=%d\n", n); la valeur du paramètre après modification est 11
return 0;
} n=10
Qu’est-ce que cela affiche? Pourquoi?
Seule une copie du paramètre est transmise
M Abid 35
Variables globales
Une solution pour régler ce problème est d'utiliser des variables globales
Une variable globale est accessible dans n'importe quelle fonction
#include<stdio.h>
int i; /* i est une variable globale*/
void affiche()
{
printf("la valeur du paramètre est : %d,\n", i);
}
main()
la valeur du paramètre est : 1
{
for(i=1;i<5;i++) la valeur du paramètre est : 2
affiche();
return 0; la valeur du paramètre est : 3
}
Qu’est-ce que cela affiche? la valeur du paramètre est : 4
M Abid 36
Variables globales (2)
#include<stdio.h>
int i=10;
void modif()
{
printf(" la valeur du paramètre au départ est %d\n", i);
i++;
printf(" la valeur du paramètre après modification est %d\n", i);
}
i=10
main()
{ la valeur du paramètre au départ est 10
printf( " i=%d\n", i); la valeur du paramètre après modification est 11
modif();
printf(" i=%d\n", i); i=11
}
Qu’est-ce que cela affiche?
M Abid 37
Les variables globales (3)
Avantages:
On peut les utiliser dans n'importe quelle fonction
On peut les modifier dans n'importe quelle fonction
Inconvénients:
On peut les modifier dans n'importe quelle fonction
Entraine de nombreuses erreurs
Il est donc préférable de ne pas utiliser de
variables globales
M Abid 38
Passage de paramètres par adresse
Comment faire une fonction modifiant un de ses
paramètres?
Il suffit de passer en paramètre l'adresse de la variable à
modifier
Si var est une variable alors &var est son adresse
Le paramètre effectif passé lors de l'appel sera alors &var
Comment déclarer un paramètre formel qui est une
adresse?
les adresses ont des types particuliers ce sont des pointeurs
Le type d'un pointeur est fonction du type pointé
On s’appuie sur l’opérateur d’indirection *
Par exemple:
un pointeur pt sur un type entier sera déclaré par :
int *pt;
M Abid 39
Passage de paramètres par adresse (2)
Comment modifier la valeur d'un paramètre à
partir de son adresse?
Il suffit de préciser que l'on veut aller modifier
ce qui se trouve à cette adresse:
void modif(int * i)
i est l'adresse de la variable n qui se trouve dans la
fonction main
Pour cela on utilise l'opérateur *
*i est la variable (valeur) dont l'adresse est i
on peut la manipuler comme une variable *i=*i+1
M Abid 40
Passage de paramètres par adresse (3)
#include<stdio.h>
void modif(int *i)
{
printf(" la valeur du paramètre au départ est %d\n", *i);
*i=*i+1;
printf(" la valeur du paramètre après modification est %d\n", *i);
}
main()
{ n=10
int n=10;
la valeur du paramètre au départ est 10
printf("n=%d\n", n);
la valeur du paramètre après modification est 11
modif(&n);
printf("n=%d\n", n); n=11
return 0;
}
Qu’est-ce que cela affiche?
M Abid 41
A retenir sur les fonctions
Une fonction est un bout de programme qui peut être
utilisée plusieurs fois grâce aux appels.
Elle simplifie l’écriture des programmes et améliore leur
lisibilité.
Les types, l’ordre d’apparition et le nombre des paramètres
doivent être les mêmes entre la déclaration (paramètres
formels) et l’appel (paramètres effectifs)
En C, les paramètres sont passés par copie (passage par
valeurs).
Les paramètres effectifs sont évalués et une copie du
résultat de l’évaluation est transmise à la fonction.
Pour passer un adresse à une fonction il faut l’indiquer avec
les opérateurs d’indirection * et d’adresse & lors de la
définition de la fonction et de son appel respectivement.
M Abid 42
Les pointeurs
Les pointeurs sont des variables dont la valeur est
l'adresse d'autres variables.
En C, le passage de paramètres se fait par
valeurs: les pointeurs sont donc le moyen le plus
sûr de changer le contenu de variables déclarées
dans d'autres fonctions.
M Abid 43
Les opérateurs de base
Pour utiliser les pointeurs nous avons besoin de
deux opérateurs: l'opérateur d'indirection * et
l'opérateur d'adresse &
L'opérateur * permet la définition du type
pointeur. Exemple: float *pt
L'opérateur * permet l'obtention de la valeur
pointée. Exemple: *n est le contenu de la variable
pointée.
L'opérateur & permet d'avoir l'adresse d'une
variable. Exemple: &n est l’adresse de la variable n
en mémoire
M Abid 44
Exemple 1
int x=10;
int y=20;
x=10; y=20
int *px, *py;
px=&x;
y=*px+1; x=10; y=11
*px=0; x=0; y=11
py=px;
A chaque instruction, donnez les valeurs de x et y
M Abid 45
Exemple 2
int *ad1, *ad2;
int n=10, p=20;
n=10; p=20
ad1 = &n;
ad2 = &p;
*ad1 = *ad2 + 2; /* équivalent à n=p+2 ; */ n=22; p=20
*ad1+=3; /* équivalent à n=n+ 3; */ n=25; p=20
*ad2 = (*ad1)++; n=26; p=25
M Abid 46
Arithmétique de pointeurs
Les pointeurs représentent des adresses : ce sont
donc des nombres entiers.
Néanmoins, les opérations arithmétiques sur les
pointeurs sont limitées:
Incrémentation et décrémentation
Soustraction de 2 adresses de même type
Comparaison de 2 adresses
M Abid 47
Incrémentation et décrémentation de
pointeurs
Si int *ad est un pointeur sur une variable entière
alors l’expression ad + 1 est valide
Cela signifie que ad va pointer vers l’entier suivant
La différence entre ad + 1 et ad est de sizeof(int)
octets et non pas 1
On peut incrémenter ou décrémenter de n’importe
quelle valeur
Exemple:
Ad++;
Ad+=10;
Ad-=13;
M Abid 48
Soustraction et comparaison
La soustraction de 2 pointeurs de même type
permet :
de savoir combien de variables les séparent et non pas
combien d’octets
Comparer deux pointeurs permet de savoir s’ils
désignent la même variable
Remarque : Additionner 2 pointeurs est interdit :
cela renverrait l’adresse d’une case mémoire qui
n’a aucun lien avec les 2 pointeurs de départ
M Abid 49
Intérêts et utilisation des pointeurs
Les pointeurs jouent un rôle primordial dans les
cas suivants:
1. Modification d’arguments de fonction (passage
par adresse)
2. Renvoi de valeur
Lorsqu’une fonction doit retourner plusieurs valeurs
3. Gain de taille
Passer un argument via son pointeur permet de gagner
de la place et du temps d’exécution
4. Gestion dynamique de la mémoire
Allocation et libération de la mémoire à l’aide des
pointeurs
M Abid 50
Types personnalisés
En C, on peut créer de nouveaux types à partir des
types prédéfinis (ou types par défaut).
Ces types appelés "types personnalisés"
permettent de représenter des ensembles de
données organisées.
Il existe trois sortes de types personnalisés :
Les unions : types complexes hétérogènes
Les énumérations : types simples homogènes
Les structures : types complexes hétérogènes
M Abid 51
Déclaration d’un type personnalisée
Un type personnalisé doit absolument précéder la
déclaration de variables utilisant ce type.
Si le programme ne contient qu’un seul fichier la
déclaration des types personnalisés se place au
tout début juste après les directives de
préprocesseur.
Si le programme contient des bibliothèques : les
types personnalisés doivent être déclarés au
début du fichier en-tête (.h)
Ce type pourra être utilisé dans tous les fichiers qui
incluent ce (.h)
M Abid 52
Les structures
Une structure en C définit un type de donnée
complexe et hétérogène.
Un type complexe et hétérogène décrit une
information formée de plusieurs valeurs qui
peuvent être de types différents qui peuvent être
eux-mêmes simples ou complexes.
struct NOM {
type1 nom1;
type2 nom2;
…
typen nomn;
}
M Abid 53
Champ d’une structure
Une structure permet de regrouper sous un même
identificateur plusieurs données qui peuvent être
complètement différentes. Ces données sont appelées
les champs de la structure.
Chaque champs est caractérisé par un identificateur
et un type.
L'identificateur d'un champ est important et doit être
unique au sein d'une structure.
Le champ d'une structure peut être de n'importe quel
type simple ou complexe
En mémoire les champs qui composent une structure
sont placés de façon contigüe en mémoire, exactement
comme les éléments formant un tableau.
M Abid 54
Déclaration de variables (1)
Les variables de type structure sont déclarées
comme n’importe quel autre variable le mot clé
struct fait partie du nom du nouveau type
Exemple:
struct article {
int numero;
float prix;
int quantite;
};
…
struct article art1;
M Abid 55
Déclaration de variables (2)
Les variables de type structure peuvent
également être déclarées simultanément à la
définition de la structure.
Exemple:
struct article {
int numero;
float prix;
int quantite;
} art1;
M Abid 56
Nom d’une structure
Le nouveau type déclaré à l’aide d’une structure
doit toujours être précédé du mot clé « struct »
Une structure peut également ne pas avoir de nom
on parle alors de « Structure anonyme ».
Exemple :
struct {
int numero;
float prix;
int quantite;
};
M Abid 57
Opérateur typedef
L’opérateur typedef permet de définir des
équivalences entre types (des synonymes).
Exemples:
typedef int entier
int x, y ; entier x, y;
typedef int* ptr;
int *p; ptr p;
Attention typedef ne crée pas de nouveaux types
mais simplement de nouveaux noms synonymes.
M Abid 58
Utilisation de typedef avec les structures
L’utilisation de typedef permet d’alléger l’écriture du type
structure:
Exemple:
struct article {
int numero;
float prix;
int quantite;
};
typedef struct article article;
« struct article » est renommée simplement « article »
Autres syntaxes:
typedef struct article{ typedef struct {
int numero; int numero;
float prix; float prix;
int quantite; int quantite;
} article; } article;
M Abid 59
Accès aux champs d’une variable structurée
A l’aide de l’opérateur « . »
Exemple:
struct article {
int numero;
float prix;
int quantite;
} art1;
[Link] donne accès au champs quantité de
la variable art1
[Link] donne accès au champs prix de la
variable art1
M Abid 60
Exemple
[Link]=15; /* affecte la valeur 15 au
champs quantite de la variable art1*/
printf(‘’ %f’’, [Link]); /* permet d’afficher la
valeur du champs prix */
scanf(‘’%d’’, &[Link]); /* initialise la valeur
du champs numero de la variable art1*/
[Link]++; /* incrémente la valeur du
champs quantité de la variable art1*/
M Abid 61
Initialisation
L’initialisation peut se faire :
1. Soit globalement au moment de la définition de
la variable
Il est alors inutile de remplir tous les champs : les
champs manquants sont initialisés à une valeur nulle par
défaut
Exemple:
struct article art1={123, 145.6, 67}
2. Soit individuellement après la définition du type
structure
M Abid 62
Copie de variables
On peut copier une variable de type structuré
dans une autre variable de même type.
struct article {
int numero;
float prix;
int quantite;
} art1, art2;
art1 = art2; est équivalent à :
[Link] = [Link];
[Link] = [Link];
[Link] = [Link];
M Abid 63
Structures comportant d’autres structures
Une structure peut intégrer d’autres structures dans sa
définition
Exemple:
Écrire une structure salarié qui comprend son nom, son
salaire et en plus les dates de naissance et d’embauche
struct Date { struct Salarie {
int jour; char nom[25];
int mois; float salaire[12];
int annee; int age;
}; struct Date naissance;
struct Date embauche;
} s1;
Quelle est le mois d’embauche de s1 ?
[Link]
M Abid 64
Transmission de structures en argument de
fonctions
Les variables structures sont des variables comme
les autres : le passage d’arguments ne change pas
M Abid 65
Exemple
struct point {
int x;
int y;
};
void fct(struct point m){
m.x=13;
m.y=18;
}
main() {
struct point p;
p.x=3;
p.y=7;
fct(p);
printf("x= %d y=%d ", p.x, p.y);
}
M Abid 66
Transmission de l’adresse d’une structure
Déclaration
void fct( struct point *m)
Accès aux champs de la variable structurée
Utilisation de l’opérateur * (attention aux priorités
des opérations). Exemple: (*m).x=13
Utilisation d’un nouvel opérateur -> (composé du
symbole «-» suivi du symble « > »)
m -> x=13
Les deux écritures sont strictement identiques
M Abid 67
Exemple
struct point {
int x;
int y;
};
void fct(struct point * m){
m -> x=13;
m -> y=18;
}
main() {
struct point p;
p.x=3;
p.y=7;
fct(&p);
printf("x= %d y=%d ", p.x, p.y);
}
M Abid 68
Transmission d’une structure en retour d’une
fonction
On peut utiliser la valeur d’une structure comme
valeur de retour d’une fonction
Exemple:
struct point fct (struct point m)
M Abid 69
Exemple
struct point {
int x;
int y;
};
struct point fct(struct point m){
m.x=13;
m.y=18;
return m;
}
main() {
struct point p;
p.x=3;
p.y=7;
p = fct(p);
printf("x= %d y=%d ", p.x, p.y);
}
M Abid 70
Les unions
Une union est une autre forme de type complexe
hétérogène.
Les unions permettent d’attribuer plusieurs types
à une même zone mémoire
Les unions permettent d’accéder au cours de
l’exécution à un des types à la fois
Déclaration d’une union: union NOM {
type1 nom1;
Mot-clé : union
type2 nom2;
…
typen nomn;
}
M Abid 71
Représentation en mémoire
Un seul espace mémoire est attribué à une union.
Sa taille doit être suffisamment grande pour
stocker l’élément le plus long de l’union
La représentation en mémoire des champs d'une
union n'est donc pas contigüe.
Les champs ne se suivent pas mais sont plutôt
superposés.
les champs sont les uns sur les autres
M Abid 72
Accès aux champs d’une union
Soit l’union suivante : union type_nombre {
On accède aux 4 octets soit short entier;
comme un réel (float) soit float reel;
comme un entier (short)
};
Si une valeur a été stockée
dans un certain champ, il faut
y accéder avec ce même
champ
Si on stocke une valeur réelle
et qu’on tente d’afficher un
entier l’affichage sera faux
(erreur d’exécution)
M Abid 73
Exemple
#include<stdio.h>
union type_nombre {
short entier;
float reel;
};
int main () {
union type_nombre n;
[Link] =3.14f;
printf(‘’%f %hd \n’’,[Link], [Link]);
}
La valeur [Link] qui sera affichée n’aura pas de sens
Cette variable pourra posséder soit une valeur entière,
soit une valeur flottante mais pas les deux à la fois
M Abid 74
Différence entre union et structure en C
Une définition d'union a la même syntaxe qu'une
définition de structure introduite par le mot clé
struct.
La différence sémantique entre les unions et les
structures est qu'une variable de type union ne
peut avoir à un instant donné qu'un seul membre
ayant une valeur.
Pour une variable de type struct, tous les
membres peuvent avoir en même temps une valeur.
M Abid 75
Utilisation des unions
L’utilisation des unions peut se résumer à deux
cas:
1. Limiter l’occupation mémoire en ne réservant
qu’un seul espace mémoire
2. Simuler du polymorphisme avec une fonction
unique recevant une union en argument et ayant
un comportement différent suivant le type qui y
est stocké
M Abid 76
Les types énumérés ou énumérations
Permettent de définir un type simple dont on énumère
les éléments: on donne la liste effective de ces
éléments
Quelques exemples:
les jours de semaine/ mois de l'année
les notes de musique
les indications d'état civil
...
Déclaration:
Utilise le mot-clé enum
enum nom { liste d’éléments };
Liste d’éléments représente une suite de noms de
constantes
Une valeur entière est associée à chaque nom
M Abid 77
Exemple 1
#include <stdio.h>
enum jour {SAMEDI, DIMANCHE, LUNDI, MARDI,
MERCREDI, JEUDI, VENDREDI};
/* SAMEDI correspond à 0, DIMANCHE à 1,
LUNDI à 2, …*/
int main()
{
enum jour j;
j= SAMEDI; /* j aura pour valeur 0*/
…
}
M Abid 78
Exemple 2
#include<stdio.h>
enum mois {JAN=1, FEV, MAR, AVR, MAI, JUIN, JUIL,
AOUT, SEPT, OCT, NOV, DEC};
int main(){
enum mois m;
m=JAN;
printf(‘’%d \n", m);
m=JUIL;
printf(‘’%d \n’’,m);
…
}
M Abid 79
Intérêt des énumérations
L'un des avantages des types enum est de
permettre de définir des ensembles de
constantes entières en les regroupant par thème.
Ceci a pour effet de rendre le code plus facile à
lire.
M Abid 80