Langage C :
Tableaux et Fonctions
[email protected]
Tableaux (1)
Définition:
Un tableau est une structure de donnée permettant de rassembler les
variables de même type désignés par un identificateur unique.
Un tableau est composé d’un ensemble des cases :
Chaque case est représentée par son indice
Dans chaque case on peut garder une valeur
Remarque:
Quand on peut utiliser un tableau lorsqu’on a un ensemble de
variables de mêmes types.
Tableaux (2)
Un tableau a une taille fixe correspondant au nombre des valeurs
pouvant être stockées dans le tableau
L'accès à un élément du tableau se fait au moyen de l'indice. Par
exemple, Tab[i] donne la valeur de l'élément i du tableau Tab
printf("%f", Tab[1]); // affiche 7
Pour changer la valeur d’une case, on utilise : Tab[3] = 11,1;
Déclaration d’un tableau
La déclaration d'un tableau s'effectue en précisant le type de ses
éléments et sa taille.
Type identificateur [Taille]
int Tab[50]; /* Tableau des entiers de taille 50*/
float T[10]; /* Tableau de réels de taille 10*/
On peut définir des tableaux de tous types : tableaux d'entiers, de
réels, de caractères, de chaînes de caractères, …
Lorsqu’on déclare un tableau, il n’est pas initialiser, c’est-à-dire, les
valeurs des cases ne sont pas définies
Initialisation d’un tableau
Liste des constantes du type adéquat, entre accolades
float Tab[6] ={7.5, 7, 11.3, 11.2, 14.3, 14,2};
Nombre d’éléments comptés par le compilateur
float Tab[] ={7.5, 7, 11.3, 11.2, 14.3, 14,2};
La liste peut être partielle
float Tab[6] ={7.5, 7, 11.3, 11.2};
Tableau à deux dimensions
De manière similaire, on peut déclarer un tableau à plusieurs
dimensions. Par exemple, pour un tableau à deux dimensions :
type nom-du-tableau[nombre-lignes][nombre-colonnes]
En fait, un tableau à deux dimensions est un tableau unidimensionnel
dont chaque élément est lui-même un tableau. On accède à un
élément du tableau par l’expression “tableau[i][j]”.
Pour initialiser un tableau à plusieurs dimensions à la compilation, on
utilise une liste dont chaque élément est une liste de constantes
Exemple :
int tab[2][3] = {{1, 2, 3}, {4, 5, 6}};
Pourquoi un sous-programme?
Certains problèmes conduits à des programmes longs, difficiles à
écrire et à comprendre.
Le sous-programme servent à fractionner le code et à améliorer sa
visibilité.
Lorsque le même fragment du code doit être exécuté plusieurs fois,
il est naturel d’isoler ce fragment et de lui donner un nom, pour y
faire une référence lorsqu'on veut l’exécuter.
Lorsqu'à un endroit du programme, on veut exécuter les instructions
d’un sous-programmes, on spécifie le nom du sous-programme
considéré : «on appelle » le sous-programme.
Fonctions et procédures
La plupart des sous-programmes servent à calculer des résultats à
partir des valeurs de certaines variables du programme appelant
Ils se comportent comme des fonctions mathématiques
On doit donc spécifier
La liste et le type des paramètres que l’on peut passer à la fonction
Le type de la valeur qu’elle renvoie
En C, il n’y a pas de différences entre les fonctions et les procédures:
Il y a que des fonctions censées renvoyée une valeur d’un type spécifié
Une procédure est une fonction qui ne renvoie rien (type void)
Fonctions (1)
Une fonction est un bloc d’instructions ayant:
Un type pour les valeurs qu’elle retourne (type de résultat)
Un nom (nom de la fonction)
Une liste de paramètres typés, entre parenthèses (paramètres )
Elle retourne un résultat à partir des valeurs des paramètres
Fonctions (2)
En général, le nom d’une fonctions apparaît à trois endroit dans un
programme
Lors de la déclaration (juste après la partie de la bibliographie)
Lors de la définition (en dehors du programme principale)
Lors de l’appel (dans le programme principal ou dans une autre
fonction)
Fonctions (3)
L’instruction return
On spécifie la valeur que renvoie une fonction au moyen de
l’instruction return (valeur de même type le type de retour déclaré
de la fonction)
Pour les fonctions ne retournant rien, on utilise l’instruction return
sans argument ou bien on peut rien écrire.
Exemple : Max de deux entiers
Exercice
Ecrire une fonction Fact du type long qui reçoit la valeur N (type int)
comme paramètre et qui fournit le factorielle de N comme résultat.
Ecrire un petit programme qui teste la fonction Fact
Exercice : solution
Paramètres formels et effectifs
Les paramètres servent à échanger les données entre le programme
principal (ou la fonction appelante) et la fonction appelée
Les paramètres placés dans la déclaration de la fonction sont des
paramètres formels
Les paramètres placés dans l’appel d’une fonction sont des
paramètres effectifs. Ils contiennent les valeurs pour effectuer le
traitement.
Le nombre, l’ordre et les types des paramètres (formels/effectifs)
doivent correspondre.
Exemple
Les pointeurs : introduction
La déclaration d’une variable c’est une réservation d’un espace
mémoire
L’emplacement de cet espace dans la mémoire est identifié par un
numéro unique : adresse mémoire
L’adresse correspond au numéro de l’emplacement mémoire
Un pointeur est une variable qui permet de stocker une adresse
Exemple : int i = 20;
int *p = &i; //pointeur sur i
Les pointeurs : déclaration & initialisation
Déclaration d’un pointeur
Le_type_de_la_variable_pointée * identificateur;
int i;
int * p; //pointeur vers un entier
char * s; //pointeur vers un caractère
Comme toute variable, il faut l’initialiser
int i;
int *p1, *p2;
p1 = &i;
Un pointeur ne pointe sur rien en lui affectant une valeur NULL
p2 = NULL;
Les pointeurs : opérations
il existe deux opérations permettant d’utiliser les pointeurs:
& : permet à un pointeur de pointer vers une variable
p = &i; // p pointe vers i
* : permet d’accéder à la valeur de la variable pointée
*p = *p + 40; //ajouter 40 à i
Les pointeurs : exemple
Les pointeurs : exemple
Le premier programme affiche :
*p = 50
*p = 10
i = 10
Le deuxième programme affiche:
x = 10, y = 10
x = 11, y = 10
*p_y = 11
Le troisième programme affiche:
x = 7, y = 6
*p = 7, *r = 7
Transmission des paramètres
Il existe deux modes de transmission de paramètres en C
La transmission par valeur
Dans ce mode les paramètres, lors de l’appel de la fonction, ne
subissent aucune modification
Utilisé lorsque le type de paramètre est un type simple
La transmission par adresse (par référence)
Dans ce mode les paramètres, lors de l’appel de la fonction, ne
subissent les mêmes modification que les paramètres de la fonction
appelante
Utilisé lorsque le type de paramètre est un tableau ou un pointeur
Transmission des paramètres
Exemple : permutation par valeur
Nous appelons la fonction PERMUTER pour les deux variables x = 5 et
y=7
Résultat : x et y restent inchangés !!
Transmission des paramètres
Exemple : permutation par adresse
Pour pouvoir modifier le contenu de x et y, la fonction PERMUTER a
besoin des adresses de x et y
En utilisant des pointeurs, on écrits une deuxième fonction:
Nous appelons la fonction par :
Transmission des paramètres
Exemple : permutation par adresse
Pointeurs et tableaux
Un tableau est une référence (pointeur) sur une zone mémoire de
variables contiguës de même type
On peut utiliser un nom de tableau comme référence
Pointeurs et tableaux : exercices
Ecrire une fonction permettant de remplir un tableau d’entiers (en
utilisant un pointeur)
Ecrire une fonction permettant d’afficher le contenu d’un tableau
passé en paramètre comme pointeur
Ecrire une fonction qui retourne le maximum d’un tableau passé en
paramètre comme pointeur
Ecrire un petit programme qui test toutes les fonctions
Tableaux multidimensionnels
Il est possible de déclarer des tableaux multidimensionnels en
spécifiant plusieurs paires de []
int Tab[3][3] /* Tableau de 3 lignes et de 3 colonnes */
/* int Tab[][]; est équivalant à int **Tab; */
Les données sont stockées par ligne majeure, c'est-à-dire que dans
Tab[n][m] la case Tab[i+1][0] est stockée juste après la case Tab[i][m-1]
Tab[3][3] = { { 1, 2, 3 }, { 4, 5, 6} , { 7, 8, 9} };
Tableaux multidimensionnels
Lors de sa déclaration
int Tab[3][3] = { { 1, 2, 3 }, { 4, 5, 6} , { 7, 8, 9} };
Initialisation d’un tableau multidimensionnelles à l’aide d’une une
fonction
Pointeurs et Tableaux multidimensionnels
Le compilateur effectue les calculs d'adresses de façon à accéder à la
bonne case du (sous-)tableau stocké de façon linéaire
int Tab[3][3] = { { 1, 2, 3 }, { 4, 5, 6} , { 7, 8, 9} };
/* Équivalant à Tab[9] « lourd au niveau traitement » */
int * li0; /* Pointeur sur la première ligne */
int * li1; /* Pointeur sur la deuxième ligne */
li1 = Tab[1]; /* Tab de type (int **), Tab[1] de type (int *) */
li0 = Tab[0]; /* Même valeur d'adresse, pas même type ! */
li1[1] = 7; /* Écriture tout à fait correcte */
Pointeurs et Tableaux multidimensionnels
On peut émuler des tableaux multidimensionnels au moyen de
pointeurs de pointeurs
Exercice
Écrire un programme qui lit les dimensions L et C d'un tableau Tab à deux
dimensions du type réel (dimensions maximales: 50 lignes et 50
colonnes)
Proposer une fonction permettant de remplir ce tableau
Proposer une autre fonction permettant d’afficher les valeurs de ce
tableau ainsi que la somme de tous ses éléments
Exercice : solution
Variables locales et globales
Une variable locale n'est connue qu'à l'intérieur de la fonction où
elle a été définie
Une variable globale est connue par l'ensemble des fonctions
La portée des variables
Le mot clé static, utilisé pour qualifier une variable locale, étend sa
portée à la durée du programme
La portée des variables
Pour une variable statique, l'initialisation à la déclaration a un sens
particulier
Récursivité
Est une méthode de description d’algorithme qui permet à une
fonction de s’appeler elle-même
Dans une procédure récursive il y a deux notions à retenir:
La fonction s’appelle elle-même : on recommence avec des nouvelles
données
Il y a un test de fin : dans ce cas il n y a pas d’appel récursive
Récursivité : exemple
Écrire une fonction qui prend comme paramètres deux entiers (x, n) et
calcule x à la puissance de n.
Solution :
int puissance(int x, int n) {
if (n == 0)
return 1;
else
return (x * puissance(x , n - 1));
}