cours
78
Home.md
78
Home.md
@@ -1 +1,77 @@
|
||||
Bienvenue sur le Wiki.
|
||||
---
|
||||
title: Informatique Industrielle
|
||||
---
|
||||
|
||||
> Le langage C reste aujourd'hui très utilisé, notamment pour le développement du noyau des systèmes d'exploitation, des logiciels embarqués et des applications nécessitant des performances élevées. Sa simplicité, sa proximité avec le matériel et sa portabilité sont les principales raisons de son succès durable.
|
||||
{class=definition}
|
||||
|
||||
- [Histoire du langage C](histoire)
|
||||
|
||||
## Caractéristiques
|
||||
|
||||
- Langage de programmation procédural ;
|
||||
- Langage de bas niveau : conçu pour être compilé en un nombre d’instructions machine prévisible en termes d’occupation mémoire et de charges de calcul ;
|
||||
- Langage extrêmement utilisé dans :
|
||||
- La programmation embarquée sur micro-contrôleurs ;
|
||||
- Les calculs intensifs ;
|
||||
- L’écriture du noyau de systèmes d’exploitation ;
|
||||
- Les modules où la rapidité de traitement est importante.
|
||||
|
||||
Sa syntaxe de base a inspiré de nombreux langages plus récents dont C++, Java et PHP, C#, JavaScript, ...
|
||||
|
||||
### Avantages
|
||||
|
||||
- Nombre restreint de concepts, ce qui facilite sa maîtrise ;
|
||||
- Nombre restreint de mots clés, ce qui facilite l’apprentissage ;
|
||||
- Proche de la machine : opérateurs proches du langage machines et fonctions permettant un accès direct au système ;
|
||||
- Programmation modulaire : permet de gérer plusieurs fichiers sources ⇒ structuration, compréhensibilité et réutilisation du code ;
|
||||
- Grand nombre de bibliothèques tierces existantes.
|
||||
|
||||
### Inconvénients
|
||||
|
||||
- Pas universel car la génération des exécutables dépend du compilateur et donc de la cible ;
|
||||
- Langage bas niveau offrant peu de fonctionnalités notamment pour la gestion de la mémoire et les chaînes de caractères ;
|
||||
- Pas de gestion efficace des erreurs et beaucoup de libertés laissées au programmeur ⇒ rigueur et discipline de programmation ;
|
||||
- Bibliothèque standard assez pauvre.
|
||||
|
||||
|
||||
## Concepts
|
||||
|
||||
- [Anatomie d'un programme](anatomie)
|
||||
- [La compilation](compilation)
|
||||
- [Les variables](variables)
|
||||
|
||||
### Opérateurs
|
||||
|
||||
- [Opérateurs d'affectation](affectation)
|
||||
- [Opérateurs arithmétiques](arithmétiques)
|
||||
- [Opérateurs logiques](logique)
|
||||
- [Opérateurs bit à bit](bit)
|
||||
|
||||
### Les instructions
|
||||
|
||||
- [Instructions conditionnelles](instructions/conditions)
|
||||
- [Instructions de boucles](instructions/boucles)
|
||||
- [Instructions de débranchement](instructions/debranchement)
|
||||
|
||||
### Les programmation avancée
|
||||
|
||||
- [Les pointeurs](pointeurs)
|
||||
- [Les chaines de caractères](string)
|
||||
- [Les structures](structure)
|
||||
- [Les fichiers](fichiers)
|
||||
- [Lecture et écriture en bloc](fichiers/bloc)
|
||||
- [Les fonctions mathématiques](math)
|
||||
|
||||
## Travaux dirigés
|
||||
|
||||
- [Installation de l'environnement de développement](TD/td0)
|
||||
- [Afficher des informations à l'écran](TD/td0/affichage)
|
||||
- [Les types numériques](TD/td0/types)
|
||||
- [La fonction main](TD/td0/main)
|
||||
- [Travaux dirigés 1](TD/td1)
|
||||
- [Travaux dirigés 2](TD/td2)
|
||||
- [Travaux dirigés 3](TD/td3) : lecture d'un fichier texte
|
||||
- [Travaux dirigés 4](TD/td4) : structure
|
||||
- [Travaux dirigés 5](TD/td5) : Lecture d'un fichier tsv, écriture binaire
|
||||
- [Travaux dirigés 6](TD/td6) : Lecture mixte
|
||||
|
||||
25
affectation.md
Normal file
25
affectation.md
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: Opérateurs d'affectation
|
||||
---
|
||||
|
||||
Les opérateurs d'affectation en C sont utilisés pour assigner des valeurs à des variables. Le plus basique est l'opérateur =, mais il existe plusieurs autres opérateurs d'affectation combinés qui effectuent des opérations mathématiques tout en affectant une valeur à la variable.
|
||||
|
||||
Opérateur | Description | Opérateur | Équivalence
|
||||
---|---|---|---
|
||||
= | Opérateur d'affectation simple. Attribue les valeurs des opérandes de droite à l'opérande de gauche c = a + b attribuera la valeur de a + b à c
|
||||
+= | Addition et affectation | a += 5 | a = a + 5
|
||||
-= | Soustraction et affectation | a -= 5 | a = a - 5
|
||||
*= | Miltiplication et affectation | a *= 5 | a = a * 5
|
||||
/= | Division et affectation | a /= 5 | a = a / 5
|
||||
%= | Modulo et affectation | a %= 5 | a = a % 5
|
||||
<<= | Décallage à gauche et affectation | a <<= 2 | a = a << 2
|
||||
\>>= | Décallage à droite et affectation | a >>= 2 | a = a >> 2
|
||||
&= | Et binaire et affectation | a &= 2 | a = a & 2
|
||||
^= | Ou exclusif et affectation | a ^= 2 | a = a ^ 2
|
||||
\|= | Ou binaire et affectation | a \|= 2 | a = a | 2
|
||||
|
||||
|
||||
> Les opérateurs d'affection combinent l'affectation simple aux autre opérateurs pour simplifier l'écriture d'une formule.
|
||||
{class=definition}
|
||||
|
||||
Chapitre suivant : les [Opérateurs arithmétiques](arithmétiques)
|
||||
99
anatomie.md
Normal file
99
anatomie.md
Normal file
@@ -0,0 +1,99 @@
|
||||
---
|
||||
title: Anatomie d'un programme en C
|
||||
---
|
||||
|
||||
Un programme en langage C est constitué des éléments suivants :
|
||||
|
||||
- Directives de préprocesseur
|
||||
- Fonctions
|
||||
- Déclarations de variables
|
||||
- Instructions
|
||||
- Structures de contrôle
|
||||
- Commentaires
|
||||
|
||||
### Exemple minimaliste
|
||||
|
||||
```c
|
||||
#include <stdio.h> // Directive de préprocesseur
|
||||
|
||||
int main() { // Début de la fonction principale
|
||||
puts("Bonjour."); // Instruction
|
||||
return 0; // Retourne le code 0 pour indiquer la fin du programme
|
||||
}
|
||||
```
|
||||
|
||||
### Directives de préprocesseur
|
||||
|
||||
Les directives de préprocesseur commencent par le symbole # et sont traitées avant la compilation. Elles servent principalement à inclure des bibliothèques ou définir des constantes.
|
||||
|
||||
Inclure la bibliothèque d'entrées/sorties standard (stdio : standard input output)
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
```
|
||||
|
||||
Déclarer une constante
|
||||
|
||||
```c
|
||||
#define PI 3.1415
|
||||
```
|
||||
|
||||
### Fonctions
|
||||
|
||||
La fonction main est le point d’entrée de tout programme C. Elle retourne un code numérique pour spécifier si le traitement (quelqu'il soit) s'est bien déroulé.
|
||||
|
||||
### Variables
|
||||
|
||||
Une variable doit être déclarée avant utilisation, en précisant son type.
|
||||
|
||||
```c
|
||||
int age = 25; // variable de type nombre entier (integer)
|
||||
float taille = 1.75; // variable de type nombre réel à virgule flottante
|
||||
char initiale = 'A'; // variable de type caractère (character)
|
||||
```
|
||||
|
||||
### Instructions
|
||||
|
||||
Les instructions sont des opérationsqui sont exécutées par le programme elle peuvent iclure des tests, des opérations mathématiques ou des appels de fonctions.
|
||||
|
||||
Chaque instruction en C se termine par un point-virgule ;.
|
||||
|
||||
### Commentaires
|
||||
|
||||
Il existe deux manières d'écrire des commentaires : en-ligne ou en bloc.
|
||||
|
||||
Les commentaires en-ligne Doivent obligatoirement tenir sur une ligne. Ils Peuvent se trouver à la suite d'une instruction.
|
||||
|
||||
```c
|
||||
// Calcul du discriminant
|
||||
delta = b * b - 4 * a * c; // Δ = b² - 4ac
|
||||
```
|
||||
|
||||
Les commentaires en bloc peuvent s’étendre sur plusieurs lignes. Ils sont délimités par /* et */
|
||||
|
||||
```c
|
||||
/* Résolution d'une équation du 2nd degré
|
||||
Auteur: Emmanuel Medina */
|
||||
```
|
||||
|
||||
## Bibliothèques
|
||||
|
||||
### stdio
|
||||
|
||||
La bibliothèque standard d'entrée/sortie ***stdio.h***, est essentielle pour interagir avec les flux d'entrée et de sortie. Elle fournit des fonctions pour lire et écrire des données, ainsi que pour manipuler les fichiers.
|
||||
|
||||
### stdlib
|
||||
|
||||
La bibliothèque standard ***stdlib.h*** (standard library) fournit des fonctions essentielles pour la gestion de la mémoire, le contrôle des processus, le tri des données, les fonctions mathématiques simples et les conversions de texte en nombre.
|
||||
|
||||
### string
|
||||
|
||||
La bibliothèque ***string.h*** fournit des fonctions pour manipuler les chaînes de caractères et les blocs mémoire.
|
||||
|
||||
### ctype
|
||||
|
||||
La bibliothèque ***ctype.h*** fournit des fonctions pour tester et manipuler des caractères.
|
||||
|
||||
### math
|
||||
|
||||
La bibliothèque ***math.h*** , permet de définir les principales fonctions usuelles mathématiques.
|
||||
95
arithmétiques.md
Normal file
95
arithmétiques.md
Normal file
@@ -0,0 +1,95 @@
|
||||
---
|
||||
title: Opérateurs arithmétiques
|
||||
---
|
||||
|
||||
Les opérateurs arithmétiques en C sont utilisés pour effectuer des opérations mathématiques de base telles que l'addition, la soustraction, la multiplication.
|
||||
|
||||
### Addition (+)
|
||||
|
||||
```c
|
||||
int a = 5, b = 3;
|
||||
int result = a + b; // result vaut 8
|
||||
```
|
||||
|
||||
### Soustraction (-)
|
||||
|
||||
```c
|
||||
int a = 5, b = 3;
|
||||
int result = a - b; // result vaut 2
|
||||
```
|
||||
|
||||
### Multiplication (*)
|
||||
|
||||
```c
|
||||
int a = 5, b = 3;
|
||||
int result = a * b; // result vaut 15
|
||||
```
|
||||
|
||||
### Division (/)
|
||||
|
||||
```c
|
||||
int a = 10, b = 2;
|
||||
int result = a / b; // result vaut 5
|
||||
```
|
||||
|
||||
#### Remarque
|
||||
|
||||
Lorsque les deux opérandes sont des entiers, la division entière est effectuée, ce qui signifie que toute fraction est ignorée (tronquée).
|
||||
|
||||
```c
|
||||
int a = 10, b = 3;
|
||||
int result = a / b; // result vaut 3 (10 / 3 = 3.333, mais la partie décimale est ignorée)
|
||||
```
|
||||
|
||||
Si l'une des valeurs est de type flottant (comme float ou double), la division produira un résultat décimal.
|
||||
|
||||
### Modulo (%)
|
||||
|
||||
L'opérateur de modulo renvoie le reste de la division entière entre deux valeurs. Cet opérateur ne peut être utilisé qu'avec des entiers.
|
||||
|
||||
```c
|
||||
int a = 10, b = 3;
|
||||
int result = a % b; // result vaut 1 (car 10 % 3 = 1)
|
||||
```
|
||||
|
||||
Opérateurs d'incrémentation et de décrémentation
|
||||
|
||||
Ces opérateurs sont des variantes des opérateurs arithmétiques, utilisés pour ajouter ou soustraire 1 à une variable.
|
||||
|
||||
### Incrémentation
|
||||
|
||||
L'opérateur d'incrémentation ajoute 1 à la valeur de la variable.
|
||||
|
||||
Post-incrémentation (var++) : L'opérateur incrémente la variable après que sa valeur actuelle soit utilisée dans l'expression.
|
||||
|
||||
```c
|
||||
int a = 5;
|
||||
int result = a++; // result vaut 5, puis a devient 6
|
||||
```
|
||||
|
||||
Pré-incrémentation (++var) : L'opérateur incrémente la variable avant que sa valeur soit utilisée dans l'expression.
|
||||
|
||||
```c
|
||||
int a = 5;
|
||||
int result = ++a; // a devient 6, puis result vaut 6
|
||||
```
|
||||
|
||||
### Décrémentation (--)
|
||||
|
||||
L'opérateur de décrémentation soustrait 1 à la valeur de la variable.
|
||||
|
||||
Post-décrémentation (var--) : La décrémentation est effectuée après que la valeur de la variable soit utilisée dans l'expression.
|
||||
|
||||
```c
|
||||
int a = 5;
|
||||
int result = a--; // result vaut 5, puis a devient 4
|
||||
```
|
||||
|
||||
Pré-décrémentation (--var) : La décrémentation est effectuée avant que la valeur soit utilisée dans l'expression.
|
||||
|
||||
```c
|
||||
int a = 5;
|
||||
int result = --a; // a devient 4, puis result vaut 4
|
||||
```
|
||||
|
||||
Chapitre suivant : les [Opérateurs logique](logique)
|
||||
67
bit.md
Normal file
67
bit.md
Normal file
@@ -0,0 +1,67 @@
|
||||
---
|
||||
title: Opérateurs bit-à-bit
|
||||
---
|
||||
|
||||
Les opérateurs bit-à-bit travaillent sur chacun des bits des opérandes.
|
||||
|
||||
## Inversion bit-à-bit
|
||||
|
||||
L'opérateur `~` retourne 0 pour un bit à 1 et 1 pour un bit à 0. C'est un opérateur unaire
|
||||
|
||||
v | r | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
|
||||
-----|----:|--:|--:|--:|--:|--:|--:|--:|--:
|
||||
a | 73 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 1
|
||||
~a | 182 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 0
|
||||
|
||||
|
||||
## ET bit-à-bit
|
||||
|
||||
L'opérateur `&` retourne 1 si les deux bits de même poids sont à 1
|
||||
|
||||
v | r | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
|
||||
------|--:|--:|--:|--:|--:|--:|--:|--:|--:
|
||||
a | 73 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 1
|
||||
b | 15 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1
|
||||
a & b | 9 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1
|
||||
|
||||
|
||||
## OU bit-à-bit
|
||||
|
||||
L'opérateur `|` retourne 1 si l'un ou l'autre des deux bits de même poids est à 1 (ou les deux).
|
||||
|
||||
v | r | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
|
||||
---|--:|--:|--:|--:|--:|--:|--:|--:|--:
|
||||
a | 73 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 1
|
||||
b | 15 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1
|
||||
a \| b | 79 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1
|
||||
|
||||
|
||||
## OU exclusif bit-à-bit
|
||||
|
||||
L'opérateur `^` retourne 1 si un seul des deux bits de même poids est à 1.
|
||||
|
||||
v | r | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
|
||||
---|--:|--:|--:|--:|--:|--:|--:|--:|--:
|
||||
a | 73 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 1
|
||||
b | 15 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1
|
||||
a ^ b | 70 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 0
|
||||
|
||||
|
||||
## Décalage à droite
|
||||
|
||||
Un décalage à droite revient à efectuer un division entière par 2.
|
||||
|
||||
v | r | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
|
||||
---|--:|--:|--:|--:|--:|--:|--:|--:|--:
|
||||
a | 73 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 1
|
||||
a >> 2 | 18 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0
|
||||
|
||||
|
||||
## Décalage à gauche
|
||||
|
||||
Un décalage à gauche revient à efectuer une multiplication par 2.
|
||||
|
||||
v | r | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
|
||||
-------|--:|--:|--:|--:|--:|--:|--:|--:|--:
|
||||
a | 9 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1
|
||||
a << 2 | 36 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0
|
||||
51
chainescaracteres.md
Normal file
51
chainescaracteres.md
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
title: Chaines de caracteres
|
||||
---
|
||||
|
||||
En langage C le tableau se comporte comme un pointeur aux différences suivantes :
|
||||
|
||||
La réservation de la zone mémoire est dimensionnée par sa déclaration
|
||||
(ex : int tab[100]) ;
|
||||
|
||||
Cette zone mémoire ne peut pas être redimensionnée. On dit alors que la taille du tableau est statique.
|
||||
|
||||
Si je déclare int tab[100], alors tab (le nom du tableau) est un pointeur contenant l’adresse du premier élément du tableau.
|
||||
tab = &tab[0];
|
||||
*tab = *(&tab[0]) = tab[0];
|
||||
|
||||
En langage C, le codage utilisé pour les caractères est le codage ASCII (étendu
|
||||
pour les accents). Une table de code ASCII est disponible ici.
|
||||
Les différents codes courants (en décimal) sont les suivants :
|
||||
I ’ ’ (espace) ⇒ 32 ;
|
||||
I ’0’ à ’9’ : ⇒ 48 à 57 ;
|
||||
I ’A’ à ’Z’ : ⇒ 65 à 90 ;
|
||||
I ’a’ à ’z’ : ⇒ 97 à 122.
|
||||
|
||||
En se basant sur la relation de précédence alphabétique des caractères, nous
|
||||
pouvons définir une précédence lexicographique pour les chaînes de caractères.
|
||||
Cette relation de précédence qui suit l’ordre du dictionnaire est définie de la
|
||||
manière suivante :
|
||||
- La chaîne vide "" précède lexicographiquement toutes les autres chaînes ;
|
||||
- La chaîne A = a1a2...ap (p caractères) précède lexicographiquement la
|
||||
chaîne B = b1b2...bm (m caractères) si l’une des deux conditions suivantes est remplie :
|
||||
X a1 < b1 ;
|
||||
X a1 = b1 et a2a3...ap précède lexicographiquement b2b3...bm
|
||||
|
||||
• "ABC" précède "BCD" car ’A’<’B’ ;
|
||||
• "ABC" précède "B" car ’A’<’B’ ;
|
||||
• "Abc" précède "abc" car ’A’<’a’ ;
|
||||
• "ab" précède "abcd" car "" précède "cd" ;
|
||||
• " ab" précède "ab" car ’ ’<’a’ (le code ASCII de ’ ’ est 32, et le code ASCII de ’a’ est 97).
|
||||
Il ne faut pas oublier que l’ordinateur travaille avec les codes ASCII ! ! !
|
||||
|
||||
Contrairement aux langage plus évolués (Java, C++, PHP, ...), il n’existe
|
||||
pas en C de type prédéfini chaîne de caractères.
|
||||
Or, dans tout programme informatique qui se respecte, les chaînes de
|
||||
caractères sont très utilisées afin de stocker des informations non numériques
|
||||
comme par exemple une liste de noms, d’adresses, de références, ....
|
||||
Par conséquent, il existe quand même des notations particulières et une bonne
|
||||
quantité de fonctions spéciales pour le traitement des chaînes de caractères
|
||||
que nous allons étudier ici.
|
||||
|
||||
En langage C, les chaînes de caractères sont des tableaux de caractères.
|
||||
Leur déclaration est donc analogue à celle d’un tableau à une dimension :
|
||||
29
comparaison.md
Normal file
29
comparaison.md
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
title: Opérateurs de comparaison
|
||||
---
|
||||
|
||||
### Égalité
|
||||
|
||||
== Vérifie si les valeurs de deux opérandes sont égales ou non. Si oui, alors la condition devient vraie.
|
||||
|
||||
### Différent
|
||||
|
||||
!= Vérifie si les valeurs de deux opérandes sont égales ou non. Si les valeurs ne sont pas égales, la condition devient vraie.
|
||||
|
||||
### Supérieur
|
||||
|
||||
\> Vérifie si la valeur de l'opérande gauche est supérieure à la valeur de l'opérande droit. Si oui, alors la condition devient vraie.
|
||||
|
||||
### Inférieur
|
||||
|
||||
< Vérifie si la valeur de l'opérande gauche est inférieure à la valeur de l'opérande droit. Si oui, alors la condition devient vraie.
|
||||
|
||||
### Supérieur ou égal
|
||||
|
||||
\>= Vérifie si la valeur de l'opérande gauche est supérieure ou égale à la valeur de l'opérande droit. Si oui, alors la condition devient vraie.
|
||||
|
||||
### Inférieur ou égal
|
||||
|
||||
<= Vérifie si la valeur de l'opérande gauche est inférieure ou égale à la valeur de l'opérande droit. Si oui, alors la condition devient vraie.
|
||||
|
||||
Le résultat des opérateurs conditionnels sont 1 pour la condition vraie et 0 pour la condition fausse;
|
||||
41
compilation.md
Normal file
41
compilation.md
Normal file
@@ -0,0 +1,41 @@
|
||||
---
|
||||
title: Compilation
|
||||
---
|
||||
|
||||
**Prétraitement** : Le traitement par le préprocesseur : le fichier source est analysé par le préprocesseur qui effectue des transformations textuelles dans le fichier source. Substitution de chaine de caractère, des constantes, prise en compte des directives de compilation, inclusion des autres fichiers sources...
|
||||
|
||||
```c
|
||||
#define PI 3.1415
|
||||
|
||||
double aire = PI * pow(rayon, 2);
|
||||
```
|
||||
|
||||
remplacé par
|
||||
|
||||
```c
|
||||
double aire = 3.1415 * pow(rayon, 2);
|
||||
```
|
||||
|
||||
**La compilation** : C’est la traduction du fichier généré par le préprocesseur en assembleur, c’est-à-dire en une suite d’instruction correspondant au microprocesseur cible. (en mnémonique rendant la lecture encore possible).
|
||||
|
||||
**L’assemblage** : L'assembleur traduit le code assembleur en code objet binaire directement compréhensible par le processeur. (fichiers objets).
|
||||
|
||||
**L’édition de liens** : Le linker combine le code objet avec les bibliothèques nécessaires (comme la bibliothèque standard C) pour produire un exécutable. (fichiers exe ou out).
|
||||
|
||||
```mermaid
|
||||
graph LR;
|
||||
A((Source C .c)) --> B[Prétraitement]
|
||||
B --> C[Compilation]
|
||||
C --> D[Assemblage]
|
||||
D --> E((Code Objet .o))
|
||||
E --> F[Édition des liens]
|
||||
F --> G((Exécutable .exe))
|
||||
```
|
||||
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
||||
mermaid.initialize({ startOnLoad: true });
|
||||
await mermaid.run({
|
||||
querySelector: '.language-mermaid',
|
||||
});
|
||||
</script>
|
||||
117
logique.md
Normal file
117
logique.md
Normal file
@@ -0,0 +1,117 @@
|
||||
---
|
||||
title: Les opérateurs logiques
|
||||
---
|
||||
|
||||
Ces opérateurs permetent de vérifier si plusieurs conditions sont vraies. Les valeurs renvoyés sont 0 pour faux et 1 pour vrai.
|
||||
|
||||
A noter : Par économie de moyens, le langage C travaille avec des entiers en utilisant la convention suivante : la valeur 0 représente la valeur booléenne faux ou false, et toute autre valeur sera assimilée à la valeur vrai ou true.
|
||||
|
||||
### NON logique
|
||||
|
||||
L'opérateur `!` inverse l'état d'une variable booléenne. Retourne la valeur 1 si la variable vaut 0 et 0 si elle vaut 1 (ou tout nombre différent de 0).
|
||||
|
||||
```c
|
||||
a = !b;
|
||||
```
|
||||
|
||||
a | !a
|
||||
--:|--:
|
||||
0 | 1
|
||||
1 | 0
|
||||
|
||||
### OU logique
|
||||
|
||||
> L'opérateur **OU logique** vérifie qu'au moins **une** des conditions est réalisée.
|
||||
{class=definition}
|
||||
|
||||
L'opérateur `||` retourne 1 si une des deux conditions a la valeur 1 (ou tout nombre différent de 0).
|
||||
|
||||
L'opérateur `||` retourne 0 seulement si les deux conditions ont la valeur 0.
|
||||
|
||||
```c
|
||||
condition1 || condition2;
|
||||
```
|
||||
|
||||
a | b | a \|\| b
|
||||
--:|--:|--:
|
||||
0 | 0 | 0
|
||||
1 | 0 | 1
|
||||
0 | 1 | 1
|
||||
1 | 1 | 1
|
||||
|
||||
|
||||
### ET logique
|
||||
|
||||
> L'opérateur **ET logique** vérifie que **toutes** les conditions sont vraies.
|
||||
{class=definition}
|
||||
|
||||
L'opérateur `&&` retourne 1 seulement si les deux conditions ont la valeur 1 (ou tout nombre différent de 0).
|
||||
|
||||
L'opérateur `&&` retourne 0 si **une seule** des deux conditions possède la valeur 0 et quelque soit la valeur de l'autre condition.
|
||||
|
||||
```c
|
||||
resultat = condition1 && condition2;
|
||||
```
|
||||
|
||||
a | b | a && b
|
||||
--:|--:|--:
|
||||
0 | 0 | 0
|
||||
1 | 0 | 0
|
||||
0 | 1 | 0
|
||||
1 | 1 | 1
|
||||
|
||||
|
||||
### Short-circuit evaluation
|
||||
|
||||
Short-circuit evaluation (court-circuit d'évaluation) ou lazy evaluation (évaluation paresseuse) ou appel par nécessité ou évaluation retardée est un mécanisme d'optimisation de l'éxecution du programme. Les expressions ne sont évaluées que si c'est nécessaire au résultat final.
|
||||
|
||||
Si le résultat est irrémédiablement connu à une étape alors la suite n'est pas évaluée car cela ne pourra faire changer le résultat.
|
||||
|
||||
Soit les 3 fonctions suivantes
|
||||
|
||||
```c
|
||||
int FonctionV()
|
||||
{
|
||||
puts("Execution de V");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int FonctionF()
|
||||
{
|
||||
puts("Execution de F");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FonctionA()
|
||||
{
|
||||
puts("Execution de A");
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
```c
|
||||
FonctionV() && FonctionA();
|
||||
```
|
||||
|
||||
`FonctionA` est appelée car la seule évaluation de `FonctionV` qui retourne vrai ne permet pas de conclure au résultat.
|
||||
|
||||
```c
|
||||
FonctionF() && FonctionA();
|
||||
```
|
||||
|
||||
Il n'est pas nécessaire d'appeler `FonctionA` car de toute façon avec `FonctionF` qui retourne faux le résultat final sera faux quelque soit le résultat de `FonctionA`.
|
||||
|
||||
Le court-circuit d'évaluation peut remplacer une syntaxe utilisant `if`
|
||||
|
||||
```c
|
||||
if (FonctionB())
|
||||
{
|
||||
FonctionA();
|
||||
}
|
||||
```
|
||||
|
||||
```c
|
||||
FonctionB() && FonctionA();
|
||||
```
|
||||
|
||||
Chapitre suivant : les [Opérateurs bit-à-bit](bit)
|
||||
98
opérateurs.md
Normal file
98
opérateurs.md
Normal file
@@ -0,0 +1,98 @@
|
||||
---
|
||||
title: Operateurs
|
||||
---
|
||||
|
||||
>Un **opérateur** est un symbole qui indique au programme qu'il faut effectuer des opérations mathématiques ou logiques spécifiques.
|
||||
{class=definition}
|
||||
|
||||
## Opérateurs de signe
|
||||
|
||||
Supposons que la variable **a** a pour valeur 7
|
||||
|
||||
Opérateur | Description | Exemple
|
||||
---|---|---
|
||||
\+ | positif | a + -5 = 2
|
||||
\− | inversion de signe | a − +5 = 2
|
||||
|
||||
## Opérateurs arithmétiques
|
||||
|
||||
Supposons que la variable **a** a pour valeur 7 et que la variable **b** la valeur 19 alors :
|
||||
|
||||
Opérateur | Description | Exemple
|
||||
---|---|---
|
||||
\+ | Addition | a + b = 26
|
||||
− | Soustraction | a − b = -12
|
||||
\* | Multiplication | a * b = 133
|
||||
/ | Division | b / a = 2
|
||||
% | Modulo, reste de la division entière | b % a = 5
|
||||
++ | Opérateur d'incrémentation<br>augmente la valeur entière de 1. | a++ = 8
|
||||
-- | Opérateur de décrémentation<br>diminue la valeur entière de 1. | a\-\- = 6
|
||||
|
||||
## Opérateurs relationnels
|
||||
|
||||
Supposons que la variable **a** a pour valeur 7 et que la variable **b** la valeur 19 alors :
|
||||
|
||||
Opérateur | Description | Exemple
|
||||
---|---|---
|
||||
== | Vérifie si les valeurs de deux opérandes sont égales ou non. Si oui, alors la condition devient vraie. | a == b n'est pas vrai.
|
||||
!= | Vérifie si les valeurs de deux opérandes sont égales ou non. Si les valeurs ne sont pas égales, la condition devient vraie. | a != b est vrai.
|
||||
\> | Vérifie si la valeur de l'opérande gauche est supérieure à la valeur de l'opérande droit. Si oui, alors la condition devient vraie. | a > b n'est pas vrai.
|
||||
< | Vérifie si la valeur de l'opérande gauche est inférieure à la valeur de l'opérande droit. Si oui, alors la condition devient vraie. | a < b est vrai.
|
||||
\>= | Vérifie si la valeur de l'opérande gauche est supérieure ou égale à la valeur de l'opérande droit. Si oui, alors la condition devient vraie. | a >= b n'est pas vrai.
|
||||
<= | Vérifie si la valeur de l'opérande gauche est inférieure ou égale à la valeur de l'opérande droit. Si oui, alors la condition devient vraie. | a <= b est vrai.
|
||||
|
||||
Le résultat des opérateurs conditionnels sont 1 pour la condition vraie et 0 pour la condition fausse;
|
||||
|
||||
## Opérateurs logiques
|
||||
|
||||
Supposons que la variable **a** a pour valeur 1 et que la variable **b** la valeur 0 alors :
|
||||
|
||||
Opérateur | Description | Exemple
|
||||
---|---|---
|
||||
&& | **ET logique**. Si les deux opérandes sont différents de zéro, la condition devient vraie. | a && b est faux.
|
||||
\|\| | **OU logique**. Si l'un des deux opérandes est différent de zéro, la condition devient vraie. | a \|\| b est vrai.
|
||||
! | **NON logique**. Il est utilisé pour inverser l'état logique de son opérande. Si une condition est vraie, alors l'opérateur logique NON la rendra fausse. | !(a && b) est vrai.
|
||||
|
||||
En savoir plus sur les [opérateurs logiques](logique)
|
||||
|
||||
Supposons que la variable **a** a pour valeur 60 et que la variable **b** la valeur 13 alors :
|
||||
|
||||
En savoir plus sur les [opérateurs bit-à-bit](bit)
|
||||
|
||||
|
||||
## Autres
|
||||
|
||||
Outre les opérateurs évoqués ci-dessus, il existe quelques autres opérateurs importants.
|
||||
|
||||
Opérateur | Description | Exemple
|
||||
---|---|---
|
||||
sizeof() | Renvoie la taille d'une variable. sizeof(a), où a est un entier, renverra 4.
|
||||
& | Renvoie l'adresse d'une variable. &a renvoie l'adresse réelle de la variable.
|
||||
\* | Pointeur de la variable *a;
|
||||
? : | Expression conditionnelle.
|
||||
|
||||
## Priorité et ordre d’évaluation
|
||||
|
||||
La priorité des opérateurs détermine le groupement des termes dans une expression et décide comment une expression est évaluée. Certains opérateurs ont une priorité plus élevée que d'autres ; par exemple, l'opérateur de multiplication a une priorité plus élevée que l'opérateur d'addition.
|
||||
|
||||
Par exemple, x = 7 + 3 * 2; ici, x est assigné à 13, pas 20 parce que * a une priorité plus élevée que +. On effecture d'abord la multiplication 3 * 2, puis on ajoute 7.
|
||||
|
||||
Les opérateurs avec la plus haute priorité apparaissent en haut du tableau, ceux avec la plus basse apparaissent en bas. Dans une expression, les opérateurs de priorité supérieure seront évalués en premier.
|
||||
|
||||
Categorie | Opérateurs | Associativité
|
||||
--- |---|---
|
||||
Préfixe | () [] -> . ++ \-\- | de gauche à droite
|
||||
Unaire | + - ! ~ ++ \-\- (type)* & sizeof | de droite à gauche
|
||||
Multiplicative | * / % | de gauche à droite
|
||||
Additive | + - | de gauche à droite
|
||||
Décallage | << >> | de gauche à droite
|
||||
Relationnelle | < <= > >= | de gauche à droite
|
||||
Égalité | == != | de gauche à droite
|
||||
Et binaire | & | de gauche à droite
|
||||
Ou exclusif | ^ | de gauche à droite
|
||||
Ou binaire | \| | de gauche à droite
|
||||
Et logique | && | de gauche à droite
|
||||
Ou logique | \|\| | de gauche à droite
|
||||
Ternaire | ?: | de droite à gauche
|
||||
Assignation | = += -= *= /= %=>>= <<= &= ^= \|= |de droite à gauche
|
||||
Séquence | , | de gauche à droite
|
||||
427
pointeurs.md
Normal file
427
pointeurs.md
Normal file
@@ -0,0 +1,427 @@
|
||||
---
|
||||
title: Pointeurs
|
||||
---
|
||||
|
||||
> Un pointeur est une variable de type **référence**, dont la valeur est l'**adresse** d'une autre variable appelée cible.
|
||||
|
||||
Sur un sytème 32 bits la taille d'un pointeur est de 4 octets (32 bits), sur un système 64 bits la taille d'un pointeur de de 8 octets (64 bits).
|
||||
|
||||
|
||||
```c
|
||||
int score = 65040073;
|
||||
int *pointeur = &score;
|
||||
```
|
||||
|
||||
<svg viewbox="0 0 300 330" width="300">
|
||||
<defs
|
||||
id="defs84">
|
||||
<marker
|
||||
style="overflow:visible;"
|
||||
id="Arrow1Send"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto">
|
||||
<path
|
||||
transform="scale(0.2) rotate(180) translate(6,0)"
|
||||
style="fill-rule:evenodd;fill:context-stroke;stroke:context-stroke;stroke-width:1.0pt;"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
id="path4681" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="Arrow1Sstart"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto">
|
||||
<path
|
||||
transform="scale(0.2) translate(6,0)"
|
||||
style="fill-rule:evenodd;fill:context-stroke;stroke:context-stroke;stroke-width:1.0pt"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
id="path4678" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible;"
|
||||
id="Arrow1Lend"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto">
|
||||
<path
|
||||
transform="scale(0.8) rotate(180) translate(12.5,0)"
|
||||
style="fill-rule:evenodd;fill:context-stroke;stroke:context-stroke;stroke-width:1.0pt;"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
id="path4669" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible;"
|
||||
id="Arrow2Lend"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto">
|
||||
<path
|
||||
transform="scale(1.1) rotate(180) translate(1,0)"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
style="fill-rule:evenodd;fill:context-stroke;stroke-width:0.62500000;stroke-linejoin:round;"
|
||||
id="path4687" />
|
||||
</marker>
|
||||
<style>
|
||||
.rect {
|
||||
fill: none;
|
||||
stroke: black;
|
||||
stroke-width: 1px;
|
||||
}
|
||||
.ligne {
|
||||
stroke: black;
|
||||
stroke-width: 0.5px;
|
||||
}
|
||||
text.address { font-size:11px; }
|
||||
.variable { fill: #ffcc44; }
|
||||
</style>
|
||||
</defs>
|
||||
<text x="0" y="0" class="address">
|
||||
<tspan x="0" y="14">10000</tspan>
|
||||
<tspan x="0" y="34">10001</tspan>
|
||||
<tspan x="0" y="54">10002</tspan>
|
||||
<tspan x="0" y="74">10003</tspan>
|
||||
<tspan x="0" y="94">10004</tspan>
|
||||
<tspan x="0" y="114">10005</tspan>
|
||||
<tspan x="0" y="134">10006</tspan>
|
||||
<tspan x="0" y="154">10007</tspan>
|
||||
<tspan x="0" y="174">10008</tspan>
|
||||
<tspan x="0" y="194">10009</tspan>
|
||||
<tspan x="0" y="214">10010</tspan>
|
||||
<tspan x="0" y="234">10011</tspan>
|
||||
<tspan x="0" y="254">10012</tspan>
|
||||
<tspan x="0" y="274">10013</tspan>
|
||||
<tspan x="0" y="294">10014</tspan>
|
||||
<tspan x="0" y="314">10015</tspan>
|
||||
</text>
|
||||
<rect x="40" y="60" width="90" height="80" class="variable"/>
|
||||
<text x="0" y="0">
|
||||
<tspan x="45" y="15">0000 1100</tspan>
|
||||
<tspan x="45" y="35">0100 0000</tspan>
|
||||
<tspan x="45" y="55">0000 0100</tspan>
|
||||
<tspan x="45" y="75">1100 1001</tspan>
|
||||
<tspan x="45" y="95">0110 1110</tspan>
|
||||
<tspan x="45" y="115">1110 0000</tspan>
|
||||
<tspan x="45" y="135">0000 0011</tspan>
|
||||
<tspan x="45" y="155">1100 0000</tspan>
|
||||
<tspan x="45" y="175">0010 0000</tspan>
|
||||
<tspan x="45" y="195">0000 0000</tspan>
|
||||
<tspan x="45" y="215">0000 1111</tspan>
|
||||
<tspan x="45" y="235">1001 0000</tspan>
|
||||
<tspan x="45" y="255">0000 0000</tspan>
|
||||
<tspan x="45" y="275">0000 0000</tspan>
|
||||
<tspan x="45" y="295">0110 0000</tspan>
|
||||
<tspan x="45" y="315">0000 0000</tspan>
|
||||
</text>
|
||||
<rect x="40" y="1" width="90" height="320" class="rect"/>
|
||||
<path d="M40,20h75 M40,40h75 M40,60h75 M40,80h75 M40,100h75 M40,120h75 M40,140h75 M40,160h75 M40,180h75 M40,200h75 M40,220h75 M40,240h75 M40,260h75 M40,280h75 M40,300h75" class="ligne"/>
|
||||
<path
|
||||
style="fill:none;stroke:#000;stroke-width:1.5px;stroke-opacity:1"
|
||||
d="M 118,60 c 8,0 8,4 8,20
|
||||
0,8 0,20 8,20
|
||||
-8,0 -8,10 -8,20
|
||||
0,16 0,20 -8,20" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
|
||||
d="M 134.3373,22.772575 35.934705,64.97496"
|
||||
/>
|
||||
<text x="140" y="105">score</text>
|
||||
<text x="140" y="25">*pointeur</text>
|
||||
</svg>
|
||||
|
||||
La déclaration d'un pointeur s'effectue en utilisant le symbole `*` appelé indirection.
|
||||
|
||||
Pour déclarer un pointeur il convient de spécifier aussi le type de la variable cible. Comme cela le système connait le nombre d'octets visés par le pointeur.
|
||||
|
||||
Dans cette déclaration le pointeur `*pointeur` vise une variable de type `int`.
|
||||
|
||||
L'adresses d'une variable correspond à l'adresse de début de la variable dans la mémoire.
|
||||
|
||||
```c
|
||||
int *pi; // pi est un pointeur pointant sur un entier
|
||||
char *pc; // pc est un pointeur pointant sur un char
|
||||
float *pf; // pf est un pointeur pointant sur un float
|
||||
```
|
||||
|
||||
### Opérateur Adresse de ...
|
||||
|
||||
L'opérateur `&` sur une variable existante permet de d'assigner au pointeur l'adresse de la variable cible.
|
||||
|
||||
Le format %p de `printf` permet d'afficher l'adresse mémoire en hexadécimal d'un pointeur.
|
||||
|
||||
```c
|
||||
printf("%p\n", pointeur);
|
||||
```
|
||||
|
||||
### Opérateur contenu de ...
|
||||
|
||||
Pour modifier la valeur d'une variable données en passant par le pointeur s'effectue en utilisant l'opérateur d"indirection `*`;
|
||||
|
||||
```c
|
||||
*pointeur = 66000000;
|
||||
printf("%d\n", score);
|
||||
```
|
||||
|
||||
l'opérateur d'indirection `*` modifie la valeur ciblée par le pointeur, et non le pointeur lui-même.
|
||||
|
||||
|
||||
|
||||
|
||||
## Allocation dynamique
|
||||
|
||||
> La déclaration d'un pointeur n'engendre pas de réservation en mémoire.
|
||||
|
||||
Les allocations de mémoires pour les pointeurs sont réalisées dans une zone mémoire bien spécifique qui s’appelle le tas (heap) (cours INFO2).
|
||||
|
||||
- L’allocation correspond à la réservation d’un bloc mémoire spécifique à votre programme par le gestionnaire de mémoire du système d’exploitation.
|
||||
- Cette opération est qualifiée d’allocation dynamique car la taille du bloc est modifiable à tout instant dans votre programme.
|
||||
- La gestion de l’allocation mémoire se fait grˆace aux 3 fonctions suivantes :
|
||||
|
||||
- malloc et calloc : demande de mémoire du programme au système d’exploitation ;
|
||||
- realloc : changement de la taille du bloc mémoire alloué (en + ou en -) ;
|
||||
- free : libération du bloc mémoire lorsqu’il n’est plus utilisé.
|
||||
|
||||
Afin de pouvoir gérer la mémoire dynamiquement en utilisant ces fonctions, il faut inclure stdlib.h.
|
||||
|
||||
La déclaration d’un pointeur n’engendre pas de réservation mémoire. Si on ne réserve pas d’emplacement mémoire, il y a risque de débordement d’un pointeur dans les données voisines, donc de plantage du programme.
|
||||
|
||||
|
||||
### malloc
|
||||
|
||||
```c
|
||||
void *malloc(size t taille);
|
||||
```
|
||||
|
||||
Elle permet d’allouer un bloc de mémoire de taille octets dans la zone de mémoire appelée tas (heap), réservée aux données ;
|
||||
|
||||
Le bloc de données n’est pas initialisé lors de l’allocation ;
|
||||
|
||||
Elle renvoie un pointeur de type void (permettant de gérer les adresses de données de tous types). Il convient donc de le convertir en un type de données déterminé (cast) ;
|
||||
|
||||
Si l’allocation réussit, la fonction renvoie un pointeur sur le bloc nouvellement alloué. Si la place disponible est insuffisante ou si taille vaut 0, elle renvoie un pointeur nul : NULL.
|
||||
|
||||
```c
|
||||
int *p;
|
||||
|
||||
p = (int *) malloc(10 * sizeof(int));
|
||||
// réservation pour 10 entiers
|
||||
|
||||
if ( p== NULL) // test création du pointeur
|
||||
{
|
||||
printf("erreur d'allocation mémoire !!!");
|
||||
// ici traitement de l'erreur ...
|
||||
}
|
||||
```
|
||||
|
||||
### calloc
|
||||
|
||||
```c
|
||||
void *calloc(size t nombre, size t tailleType);
|
||||
```
|
||||
|
||||
Elle permet d’allouer un bloc de mémoire de nombre ∗ tailleType octets dans la zone de mémoire appelée tas (heap), réservée aux données ;
|
||||
|
||||
Le bloc de données est initialisé avec des 0 lors de l’allocation ;
|
||||
|
||||
Elle renvoie un pointeur de type void (permettant de gérer les adresses de données de tous types). Il convient donc de le convertir en un type de données déterminé (cast) ;
|
||||
|
||||
Si l’allocation réussit, la fonction renvoie un pointeur sur le bloc nouvellement alloué. Si la place disponible est insuffisante ou si taille vaut 0, elle renvoie un pointeur nul : NULL.
|
||||
|
||||
```c
|
||||
int *p;
|
||||
p = (int *) calloc(10 , sizeof(int) );
|
||||
// réservation pour 10 entiers
|
||||
if ( p== NULL) // test création du pointeur
|
||||
{
|
||||
printf("erreur d'allocation mémoire !!!");
|
||||
// ici traitement de l'erreur ...
|
||||
}
|
||||
```
|
||||
|
||||
### realloc
|
||||
|
||||
```c
|
||||
void *realloc(void *pointeurBase, size t newTaille);
|
||||
```
|
||||
|
||||
Elle permet de changer la taille d’un bloc de mémoire déjà alloué. Elle est le reflet de l’aspect dynamique des pointeurs ;
|
||||
|
||||
Le paramètre newTaille correspond à l’addition de la taille de l’ancien bloc et de la taille du bloc supplémentaire à ajouter ;
|
||||
|
||||
Le contenu du bloc précédant est gardé ⇒ pas besoin de gérer le copie ;
|
||||
|
||||
Elle renvoie un pointeur de type void (permettant de gérer les adresses de données de tous types). Il convient donc de le convertir en un type de données déterminé (cast) ;
|
||||
|
||||
Si l’allocation réussit, la fonction renvoie un pointeur sur le bloc nouvellement alloué. Si la place disponible est insuffisante ou si newTaille vaut 0, elle renvoie un pointeur nul : NULL.
|
||||
|
||||
```c
|
||||
int *p;
|
||||
|
||||
p = (int *) realloc( p , 20 * sizeof(int) );
|
||||
// réservation pour 10 entiers supplémentaires
|
||||
|
||||
if ( p== NULL) // test création du pointeur
|
||||
{
|
||||
printf("erreur d'allocation mémoire !!!");
|
||||
// ici traitement de l'erreur ...
|
||||
}
|
||||
```
|
||||
|
||||
!!! ATTENTION, les données peuvent être déplacées si l'espace n'est pas suffisant !!!
|
||||
|
||||
### Libération
|
||||
|
||||
La fonction free
|
||||
|
||||
```c
|
||||
void *free(void *pointeur);
|
||||
```
|
||||
|
||||
Cette fonction permet de libérer l’espace mémoire alloué par les 3 fonctions précédentes.
|
||||
|
||||
Il est important de libérer l’espace après utilisation, sinon celui-ci devient inutilisable pour la suite du programme ! !
|
||||
|
||||
|
||||
```c
|
||||
# include < stdio .h >
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
int *p;
|
||||
...
|
||||
free(p); // libération de la mémoire occupée
|
||||
}
|
||||
```
|
||||
|
||||
## L'arithmétique des pointeurs
|
||||
|
||||
On peut déplacer un pointeur dans la mémoire à l'aide des opérateurs d'addition, de soustraction, d'incrémentation, de décrémentation.
|
||||
|
||||
On ne peut le déplacer que d'un nombre de cases mémoire multiple de la taille définit lors de la déclaration.
|
||||
|
||||
```c
|
||||
int *pi = malloc(100 * sizeof(int));
|
||||
char *pc = malloc(100 * sizeof(char));
|
||||
*pi = 5;
|
||||
*pc = 'A';
|
||||
|
||||
*(pi+1) = 200; // 200 est de contenu de la case mémoire 4 octets après pi
|
||||
*(pi+2) = 500; // 500 est le contenu de la case mémoire 8 octets après pi
|
||||
|
||||
|
||||
*pc = 'A'; // la case mémoire pc contient le code ASCII de A = 65
|
||||
pc--; // on décrémente la valeur du pointeur pc de 1
|
||||
*pf = 1.5; // 1,5 est stocké dans la case mémoire pf et les 4
|
||||
// suivantes
|
||||
pf++; // on incrémente la valeur du pointeur pf de 4 cases
|
||||
//mémoires qui correspond à la taille d'un float
|
||||
int *pi,*qi,i;
|
||||
pi = qi; // autorisé
|
||||
|
||||
i = pi + qi; // interdit : on ne peut pas additionner deux pointeurs
|
||||
// ça n'a pas de sens
|
||||
|
||||
i = pi-qi; // autorisé : donne le nombre d'objets entre les deux
|
||||
// pointeurs
|
||||
|
||||
I = pi*qi; // interdit : on ne peut pas multiplier deux pointeurs
|
||||
// ça n'a pas de sens
|
||||
```
|
||||
## Utilisation des pointeurs
|
||||
|
||||
## Les pointeurs et les tableaux.
|
||||
|
||||
Le langage C gère un tableau comme un pointeur à la différence près qu'il réserve un emplacement dimensionné
|
||||
par la déclaration.
|
||||
Exemple : int T[50];
|
||||
int i, *pi, T[10];
|
||||
pi = &i; // *pi représente i car pi pointe sur i
|
||||
*pi = 0; // c'est équivalent à i = 0
|
||||
pi = &T[0]; // pi pointe maintenant sur le premier élément du tableau T
|
||||
// *pi représente T[0]
|
||||
*pi = 0; // équivalent à T[0] = 0;
|
||||
|
||||
## Tableaux.
|
||||
|
||||
La déclaration de T[50] réserve en mémoire 50 entiers, mais nous avons en même temps un nouveau pointeur
|
||||
initialisé sur le début du tableau.
|
||||
|
||||
```c
|
||||
int *pi, T[10], X;
|
||||
pi = T; // pi pointe sur le début du tableau soit le premier élément
|
||||
*T = 0; // c'est équivalent à T[0] = 0
|
||||
*(T+2) = 5; // c'est équivalent à T[2] = 5
|
||||
*(pi+5) = 0; // équivalent à T[5] = 0;
|
||||
```
|
||||
|
||||
Les tableaux en mémoire = Tableaux de pointeurs
|
||||
|
||||
Exemple : tableau 1 dimension
|
||||
|
||||
```c
|
||||
char Tab1D[5];
|
||||
```
|
||||
|
||||
Exemple : tableau 2 dimensions avec des chaines de caractères
|
||||
|
||||
```c
|
||||
char Tab2D [5][7] = {"UN", "DEUX", "TROIS", "QUATRE", "CINQ"};
|
||||
```
|
||||
|
||||
On alloue le maximum pour ne pas avoir de problèmes de débordement.
|
||||
Zones Mémoire Perdues
|
||||
|
||||
|
||||
On déclare un tableau de pointeurs dans lequel chaque pointeur désigne l'adresse d'un autre tableau
|
||||
Exemple : tableau 2 dimensions avec des chaines de caractères
|
||||
char *Tab2D [5] ;
|
||||
|
||||
```c
|
||||
char *Tab[] = { "UN" , "DEUX", "TROIS", "QUATRE", "CINQ"} ;
|
||||
Tab[0] pointe sur "UN"
|
||||
Tab[1] pointe sur "DEUX"
|
||||
*Tab[0] retourne sur 'U' de "UN"
|
||||
*( Tab[0] + 1) retourne sur 'N' de "UN"
|
||||
*( Tab[1] + 2) retourne sur 'U' de "DEUX"
|
||||
```
|
||||
|
||||
Attention:
|
||||
|
||||
*Tab[4] + 1 retourne 'D' car *Tab[4] = 'C' et 'C' + 1 = 'D'
|
||||
|
||||
### Passage de paramètres aux fonctions
|
||||
|
||||
Exemple : Fonction qui prend un pointeur en paramètre d'entrée
|
||||
int carre(int *A)
|
||||
{
|
||||
int Res;
|
||||
Res = (*A) * (*A); // équivalent à : *A**A ou * A * * A
|
||||
return (Res);
|
||||
}
|
||||
Void main(void)
|
||||
{
|
||||
int *X,Y;
|
||||
X = (int*)malloc(1*sizeof(int)); // initialisation du pointeur sur le tas
|
||||
// (heap) zone mémoire réservée aux
|
||||
// données
|
||||
*X = 2;
|
||||
Y = carre(X);
|
||||
}
|
||||
|
||||
Les pointeurs avec une fonction.
|
||||
Exemple : Fonction qui prend un pointeur en paramètre d'entrée et retourne un pointeur.
|
||||
|
||||
```c
|
||||
void carre(int *A)
|
||||
{
|
||||
(*A) = (*A) * (*A); // équivalent à : *A**A ou * A * * A
|
||||
}
|
||||
|
||||
Void main(void)
|
||||
{
|
||||
int *X;
|
||||
X = 2;
|
||||
carre(&X);
|
||||
}
|
||||
```
|
||||
83
structure.md
Normal file
83
structure.md
Normal file
@@ -0,0 +1,83 @@
|
||||
---
|
||||
title: Structure
|
||||
---
|
||||
|
||||
>Un structure permet de regrouper plusieurs types de données dans un seul bloc logique pour les associer à une super variable.
|
||||
{class=definition}
|
||||
|
||||
Exemple de variables indépendantes representant des conditions météorologiques.
|
||||
|
||||
```c
|
||||
float temperature;
|
||||
float humidite;
|
||||
int pression;
|
||||
char vent_direction[2];
|
||||
int vent_vitesse;
|
||||
```
|
||||
|
||||
La structure rassemble les données dans un bloc logique
|
||||
|
||||
```c
|
||||
struct blocmeteo
|
||||
{
|
||||
float temperature;
|
||||
float humidite;
|
||||
int pression;
|
||||
char vent_direction[2];
|
||||
int vent_vitesse;
|
||||
};
|
||||
```
|
||||
|
||||
Les variables à l'intérieur de la structure sont appelées des **champs**.
|
||||
|
||||
La déclaration de variables de type structure s'effectue comme les autes types (int, float, etc...) en utilisant la déclaration le nom de la structure y compris l'instruction struct.
|
||||
|
||||
```c
|
||||
struct blocmeteo paris;
|
||||
struct blocmeteo strasbourg;
|
||||
struct blocmeteo marseille;
|
||||
```
|
||||
|
||||
On accède aux propriétés avec l'opérateur `.`
|
||||
|
||||
```c
|
||||
paris.temperature = 15.2;
|
||||
strabourg.humidite = 0.88;
|
||||
marseille.pression = 1040;
|
||||
```
|
||||
|
||||
### Nouveau type de données
|
||||
|
||||
Pour éviter d'écrire à chaque fois le mot clé struct lors de la déclaration d'une variable ou d'un paramètre de type structure, il est possible de définir un nouveau type à l'aide de la commande `typedef`. Veuillez noter que le nom du type vient tout à la fin de la définition, après la structure
|
||||
|
||||
```c
|
||||
typedef blocmeteo struct
|
||||
{
|
||||
float temperature;
|
||||
float humidite;
|
||||
int pression;
|
||||
char vent_direction[2];
|
||||
int vent_vitesse;
|
||||
} meteo;
|
||||
```
|
||||
|
||||
Le nom de la structure en elle même n'est plus utile, on peut l'ignorer.
|
||||
|
||||
```c
|
||||
typedef struct
|
||||
{
|
||||
float temperature;
|
||||
float humidite;
|
||||
int pression;
|
||||
char vent_direction[2];
|
||||
int vent_vitesse;
|
||||
} meteo;
|
||||
```
|
||||
|
||||
La déclaration des variables se fait directement avec le type;
|
||||
|
||||
```c
|
||||
meteo paris;
|
||||
meteo strasbourg;
|
||||
meteo marseille;
|
||||
```
|
||||
3
tableaux.md
Normal file
3
tableaux.md
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
title: Tableaux
|
||||
---
|
||||
89
variables.md
Normal file
89
variables.md
Normal file
@@ -0,0 +1,89 @@
|
||||
---
|
||||
title: Variables
|
||||
---
|
||||
|
||||
>Une variable est un élément qui associe un **identifiant** à une **valeur**.
|
||||
{class=definition}
|
||||
|
||||
### Caractéristiques
|
||||
|
||||
Une variable possède plusieurs caractéristiques ou propriétés.
|
||||
|
||||
La **déclaration**, c'est l'endroit dans le code qui défini l'existence de la variable.
|
||||
|
||||
```c
|
||||
int age = 19;
|
||||
```
|
||||
|
||||
Un **nom** sous lequel la variable est déclarée. Dans cette déclaration le nom de la variable est `age`.
|
||||
|
||||
Un **type**. Dans la mémoire d'un ordinateur, toute information est stockée sous forme d'éléments binaires appelés `bit` (en: binary digit, nombre binaire). Un même ensemble de bits peut être représenté sous différentes aspects : nombre entier, nombre réel, texte, photo, vidéo, audio, ... C'est la convention d'interprétation du type qui défini la valeur de la variable.
|
||||
|
||||
Dans cette déclaration le type de la variable `age` est un entier `int`.
|
||||
|
||||
La **taille** associée au type. Dans le cas des types fixe, le type de la variable spécifie aussi le nombre de bits ou le nombre de mots (en: bytes, octets) utilisés.
|
||||
|
||||
Dans cette déclaration la taille de la variable `age` est de 4 octets ou 32 bits, qui est la taille associée à un type `int`.
|
||||
|
||||
La **valeur**, c'est la valeur intrasèque des bits suivant la représentation associée au type;
|
||||
|
||||
Dans cet exemple la valeur de la variable `age` est `10`.
|
||||
|
||||
L'**adresse**, c'est l'endroit dans la mémoire de l'ordinateur où est stockée physiquement la variable.
|
||||
|
||||
La **portée**, c'est la portion de code où la variable est utilisable. Une variable est accessible depuis sa définition jusqu'à la fin du bloc où elle est déclarée.
|
||||
|
||||
Sa **durée de vie**, c'est le temps d'exécution pendant laquelle la variable existe. Il est possible de masquer une variable par une autre en utilisant un même identifiant. La première variable est hors de portée mais existe toujours. Une variable `static` est utilisable que dans la fonction dans laquelle elle a été déclarée, cependant sa durée de vie s'étend sur l'intégralité de l'éxécution du programme.
|
||||
|
||||
Sa **visibilité**, dans un langage évolué comme le C++, le C# ou Java, c'est un ensemble de règles qui fixe qui peut utiliser la variable.
|
||||
|
||||
### Règles
|
||||
|
||||
#### Déclaration
|
||||
|
||||
>Les variables doivent être déclarées **avant** d'être utilisées.
|
||||
{class=warning}
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("%d", age);
|
||||
int age = 10;
|
||||
}
|
||||
```
|
||||
|
||||
Ce code provoque une erreur : la variable est non déclarée avant sont utilisation !
|
||||
|
||||
```
|
||||
error: ‘age’ undeclared (first use in this function)
|
||||
```
|
||||
|
||||
Voici le code correct
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int age = 10;
|
||||
printf("%d", age);
|
||||
}
|
||||
```
|
||||
|
||||
## Expressions littérales
|
||||
|
||||
Dans un programme il est possible de manipuler des valeurs sans pour autant les avoir déclarées avant. Ces valeurs existent de manières littérales à l'intérieur même du code du programme.
|
||||
|
||||
>Attention, dans le cas des chaines de caractères, il ne faut pas confondre le nom de la variable avec sa valeur.
|
||||
{class=warning}
|
||||
|
||||
```c
|
||||
char joueur[10] = "Alice";
|
||||
|
||||
printf("%s\n", "joueur");
|
||||
printf("%s\n", joueur);
|
||||
```
|
||||
|
||||
`"joueur"` avec des guillemets est une valeur littérale. On peut considérer, sans que cela soit le cas, que c'est une variable sans nom, qui possède la valeur `joueur`.
|
||||
Reference in New Issue
Block a user