Chapitre 1

Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 30

Langage C avancé

Tronc commun

Pr. Nabila ZRIRA & Pr. Hamza TOULNI


Département Informatique

Année universitaire: 2023-2024


Chapitre I
Rappel
Structures
Déclaration d'une structure

Une structure possède un nom et se compose de plusieurs champs


• Chaque champ à son propre type et son propre nom
• Pour déclarer une structure on utilise le mot-clé struct

Le nom de la
Mot-clé struct structure

struct nomStructure {
type1 champ1 ;
Champs de la structure
...
typeN champN ;
};

3
Structures
Déclaration d'une structure

Exemple : la structure imbriquée

struct Etudiant {
int Code;
char Genre;
char Nom[12];
struct DateDeNaissance {
float Moyenne;
int Jour;
struct DateDeNaissance Date; char Mois[8];
int Annee;
};
};

4
Structures
Déclaration d'une structure

Attention : la structure suivante est incorrecte


struct Etudiant {
struct DateDeNaissance {
int Code; int Jour;
char Nom; char Mois[8];
int Annee;
char Nom[12]; };
float Moyenne;
struct Etudiant Date;
};

Il y a deux raisons :
• Le nom de variable Nom n'est pas unique
• Le type de donnée struct Etudiant n'est pas autorisé

5
Structures
Définition d'une variable structurée

Soit la structure Personne :


struct Etudiant {
int Code;
char Genre;
char Nom[12];
float Moyenne;
struct DateDeNaissance Date;
};

On peut définir plusieurs variables structurées :


struct Etudiant E1,E2,E3;

6
Structures
Accès aux champs d'une variable structurée
Chaque variable de type structure possède des champs repérés avec des noms uniques

• le nom des champs ne suffit pas pour y accéder étant donné qu'ils n'ont de contexte qu'au sein de la variable structurée

• Pour accéder aux champs d'une structure, on utilise l'opérateur de champ (un simple point . ) placé entre le nom de la
variable structurée que l'on a défini et le nom du champ :

Nom_Variable.Nom_Champ;

• Soit E1 une variable de type struct Etudiant définie précédemment, on pourra écrire :
E1.Code = 90822;
E1.Genre = 'M’;
E1.Nom="Benssouda";
E1.Moyenne=12.50;
E1.Date.Jour=24;
E1.Date.Mois="Mars";
E1.Date.Annee=2000;

7
Structures
Utilisation de typedef
Le mot-clé typedef permet d'associer un nom à un type donné.

On l'utilise suivi de la déclaration d'un type puis du nom qui remplacera ce type.

Ceci permet, par exemple, de s'affranchir de l'emploi de struct à chaque utilisation d'un complexe : il n'est
pas alors nécessaire de donner un nom à la structure

typedef struct {
int Code;
char Genre;
char Nom[12];
float Moyenne;
struct DateDeNaissance Date;
}Etudiant;

8
Structures
Tableaux de structures

Il est possible de créer un tableau ne contenant que des éléments du type d'une structure donnée.

Créer un tableau dont le type est celui de la structure et de le repérer par un nom de variable :

struct Nom_Structure Nom_Tableau[Nb_Elements];

Le nom de la Le nom du Nombre d’élément


mot clé struct
structure tableau dans le tableau

Chaque élément du tableau représente alors une structure du type que l'on a défini.

9
Structures
Tableaux de structures

Le tableau suivant T pourra par exemple contenir 6 variables structurées de type struct Etudiant

T[0]
struct Etudiant{
int code;
float moyenne;
};
struct Etudiant T[6];

T[5]

10
Structures
Tableaux de structures

Le tableau suivant list pourra par exemple contenir 1000 variables structurées de type struct entry

struct entry{
char fnom[10];
char lnom[12];
char phone[8];
};
struct entry list[1000];

11
Pointeurs
Exemple :

int var=100;

var

Une variable appelée var est déclarée et initialisée à 100. Le compilateur a réservé un emplacement mémoire à
l’adresse 1004, qu’il associe donc au nom de la variable.

12
Pointeurs
Déclaration d’un pointeur

Syntaxe
Type *nom_ptr;

Exemple

int * p_var;

Un emplacement a été alloué à la variable p_var

p_var var 13
Pointeurs
Initialisation d’un pointeur

Syntaxe:
Pointeur = & variable;

Exemple:
p_var = & var;
p_var var

La variable p_var contient l’adresse de la variable var, elle est également un pointeur vers var.

14
Pointeurs
Modes d’accès

printf("%d", var); équivalent à printf("%d", *p_var);

Accès direct Accès indirect

var *p_var
p_var

15
Pointeurs
Modes d’accès
Les pointeurs sont très importants en langage C, il est essentiel de bien comprendre leur fonctionnement.
Si votre pointeur s’appelle p_var et qu’il a été initialisé pour pointer sur la variable var alors :

Par exemple :
int var;
int *p_var;

*p_var var Contenu de var


p_var &var Adresse de var

Pointeur NULL :
int *P; NULL est utilisée pour indiquer qu'un pointeur ne pointe 'nulle part'.
P=NULL; 16
Pointeurs
Pointeurs et tableaux

int x[6];
x == 1000
&x[0] == 1000
&x[1] == 1004

double expenses[3];
expenses == 1250
&expenses[0] == 1250
&expenses[1] == 1258

17
Pointeurs
Pointeurs et tableaux

Nous pouvons accéder aux éléments par pointeurs en faisant des calculs d’adresses.

long v[6] = { 1,2,3,4,5,6 };


long *p;
1
p = v; 2
printf("%d\n", *p); 6
p++;
printf("%d\n", *p);
p += 4;
p += 4
printf("%d\n", *p);
p++

p
1000 1 2 3 4 5 6
v
1000 1004 1008 1012 1016 1020

18
Pointeurs
Operateurs * et ++

*p++ signifie :
*p++ trouver la valeur pointée
*p++ passer à l’adresse suivante
(*p)++ signifie :
(*p)++ trouver la valeur pointée
(*p)++ incrémenter cette valeur (sans changer le pointeur)
*++p signifie :
*++p incrémenter d’abord le pointeur
*++p trouver la valeur pointée
++*p signifie:
++*p incrémenter d’abord la valeur pointée (sans changer le pointeur)
++*p trouver la valeur pointée 19
Pointeurs
Operateurs * et ++

#include<stdio.h>
int main(){ E N N I
char nom[30]="ENIM";
char* p = nom;
printf ("%c ", *p);
printf ("%c ", *++p);
printf ("%c ", *p++);
printf ("%c ", *p);
return 0;
}

20
Pointeurs
Fonctions : Passage des paramètres

Passage par valeur


• Les arguments (paramètres) peuvent être considérés comme des variables locales à la fonction;
• Lors de l'appel de la fonction, la valeur de chaque paramètre est recopiée dans un nouvel espace mémoire
réservé pour ce paramètre;
• Une fonction peut donc localement modifier le contenu de ses paramètres;
• Les valeurs utilisées lors de l'appel ne seront absolument pas modifiées.
Passage par adresse
• Le passage des paramètres par valeur ne permet donc pas de modifier une variable de la fonction appelante
• Grâce aux pointeurs, il est possible d'agir à distance sur les variables
• Il suffit pour cela d'envoyer non pas la valeur d'une variable mais son adresse en mémoire (c'est à dire un
pointeur sur cette variable)
• La fonction appelée peut alors modifier le contenu de cet emplacement mémoire (et donc le contenu de la
variable elle-même)
21
Pointeurs
Exemple Case mémoire Adresse
1004
#include <stdio.h>
1008
void somme(int , int , int *);
1012
int modif(int , int *, int *);
1016
int main(){
1020
int a, b, c;
1024
a = 2; b = 8;
1028
somme(a, b, &c);
1032
printf("Somme de a=%d et b=%d : %d\n",a, b, c);
1036
a = modif(a, &b, &c);
1040
printf(" Modif : a=%d , b=%d et c= %d\n",a, b, c);
1044
return 0;
1048
}
1052
void somme(int x, int y, int *z){
1056
*z = x + y;
1060
}
1064
int modif(int x, int *y, int *z){
1068
x *= 2; *y= x+ *y; *z= 5;
1072
return x;
1076
}
22
Allocation dynamique de la mémoire

L’allocation dynamique se fait en C par la fonction malloc()de la librairie standard <stdlib.h>.

Syntaxe :
malloc(sizeof(type))

Exemple :
#include <stdlib.h>
int *p;
p = (int*)malloc(sizeof(int));

23
Allocation dynamique de la mémoire
Exemple

valeur de p = 5368711424
#include <stdio.h> valeur de *p = 3
#include <stdlib.h>
int main(){
int i = 3;
int *p;
p = (int*)malloc(sizeof(int));
printf("valeur de p = %ld\n",p);
*p = i;
printf("valeur de *p = %d\n",*p);
return 0;
}

24
Allocation dynamique de la mémoire
calloc()

La fonction calloc() de la librairie <stdlib.h> a le même rôle que la fonction malloc() mais elle
initialise en plus l’objet pointé *p à zéro.
Syntaxe :
calloc ( nb-objets , taille-objets )
Exemple :
Si p est de type int*, l’instruction
p = (int*)calloc(N,sizeof(int));
Ce code est équivalent à:
p = (int*)malloc(N * sizeof(int));
for (i = 0; i < N; i++)
*(p + i) = 0;
L’emploi de calloc()est simplement plus rapide.
25
Allocation dynamique de la mémoire
free()

Enfin, lorsque l’on n’a plus besoin de l’espace-mémoire alloué dynamiquement (c’est-`a-dire quand on n’utilise plus le pointeur
p), il faut libérer cette place en mémoire. Ceci se fait à l’aide de l’instruction free qui a pour syntaxe
free ( nom-du-pointeur );
A toute instruction de type malloc()ou calloc() doit être associée une instruction de type free.

Exemple:

#include <stdlib.h>
int main() {
int n;
int *tab;
...
tab = (int*)malloc(n * sizeof(int));
...
free(tab);
return 0;
} 26
Pointeurs de structure
Définition

Les structures en C possèdent une adresse, correspondant à l’adresse du premier élément du premier
champ de la structure . On peut donc manipuler des pointeurs sur des structures.

Exemple :

struct Etudiant{
char nom[20];
int age;
};

struct Etudiant *E;

E est un pointeur de type struct Etudiant qui pointe sur une variable structurée de type struct
Etudiant.

27
Pointeurs de structure
Accès aux champs
Si p est un pointeur sur une structure, on peut accéder à un membre de la structure pointé par l’expression :

(*p).champ

L’usage de parenthèses est ici indispensable car l’opérateur d’indirection * à une priorité moins élevée que
l’opérateur de champ de structure. Cette notation peut être simplifiée grâce à l’opérateur pointeur de champ de
structure, noté -> . L’expression précédente est strictement équivalente à p->champ

Exemple :
(*E).nom; Ou E->nom;
struct Etudiant{ (*E).age; Ou E->age;
char nom[20];
int age;
};
(*E).nom; Ou E->nom;
struct Etudiant *E;
&(*E).age; Ou &E->age;

28
Pointeurs de structure
Allocation dynamique

Exemple :

struct Etudiant{ typedef struct {


char nom[20]; char nom[20];
int age; int age;
}; } Etudiant;
struct Etudiant *E; Etudiant *E;

E=(struct Etudiant *)malloc(sizeof(struct Etudiant)); E=(Etudiant *)malloc(sizeof(Etudiant));

29
Pointeurs de structure
Allocation dynamique

Exemple :

struct Etudiant{ typedef struct {


char nom[20]; char nom[20];
int age; int age;
}; } Etudiant;
struct Etudiant *T; Etudiant *T;

T=(struct Etudiant *)malloc(n*sizeof(struct Etudiant)); T=(Etudiant *)malloc(n*sizeof(Etudiant));

(*(T+i)).nom Ou (T+i)->nom Ou T[i].nom T[i].nom Ou (T+i)->nom


(*(T+i)).age Ou (T+i)->age Ou T[i].age &T[i].age Ou &(T+i)->age

30

Vous aimerez peut-être aussi