Langage C : Résumé I

Langage C : Résumé IChapitre 2 - Types et variables2.1 Codage en binaire2.2 Mémoire2.3 Variable2.4 Types de base2.5 Déclaration et affectation des variables/constChapitre 3 - Opérateurs3.1 Opérateurs arithmétiques3.1.1 priorités3.1.2 types et domaines de définition3.1.3 Règles de conversion implicites3.1.4 Conversions explicites3.2 Opérateur d'affectation et d'assignation3.3 Opérateurs d'incrémentation3.4 Opérateur virgule3.5 Opérations de comparaison3.6 Opérateurs logiques3.6 Opérateurs bit-à-bit3.7 Opérateurs de décalage de bitChapitre 4 - Entrées / Sorties4.1. Syntaxe de printf()4.1.1 Affichage / saisie4.1.2 printf : syntaxe4.2 spécifications de format4.2.1 Caractères4.2.2 Nombre entiers4.2.3 Nombre à virgule flottante4.2.4 Formats d'affichage4.3 caractères d'échappement4.4 Syntaxe de scanf()Chapitre 5 - Structures de contrôle5.1 Branchement conditionnel5.1.1 ifsyntaxe :5.1.2 if elsesyntaxe :5.1.3 Remarques5.1.4 Styles de codageStyle Kernighan & RichtieStyle Whitesmiths5.1.5 Opérateur ternaire5.1.6 Branchement multiple switchswitch seul Syntaxe : Organigramme :switch + breakSyntaxe :Organigramme:5.1.7 Comparaison switch vs if..else5.2 Boucles5.2.1 Boucle whileSyntaxeStructogrammeRemarques5.2.2 Boucle do..whileSyntaxeStructogrammeRemarques5.2.3 Boucle forSyntaxeStructogrammeRemarquesPrécisionsinitialisation ConditionincrémentFonctionnementEquivalent en boucle while5.2.4 Quelle boucle choisir ?5.3 Instructions de branchement inconditionnels5.3.1 Instruction return5.3.2 Fonction exit(<int>)Autres instructions inconditionnellesFonctionnementChapitre 6 - Fonctions (partie 1)6.1 Notion de fonction6.1.1 Avantages de l'utilisation de fonctions6.1.2 Appel de fonction6.1.3 Définition de fonction6.1.4 Prototype de fonction6.1.5 Valeur retournéeTypes de retoursParamètres formelsParamètre effectifs6.2 Variables locales et globales6.2.1 Visibilité des variablesVariables globalesVariables locales6.2.2 Danger des variables globales6.2.3 Mot-clé static6.3 Organisation de la mémoire

Chapitre 2 - Types et variables

les variables : informations que l'on stocke pour les réutiliser plus tard.

la mémoire : divisée en octets, ce qui est 8 bits qui eux mm 8x 0 ou 1.

on va diviser les infos sur plusieurs octets car on ne peut pas les entrer en entier dedans .

2.1 Codage en binaire

les nombres valent la mm chose peut importe la base. Cela représente le mm nombre de choses

c'est seulement la "traduction" pour notre "langage".

dans un ordinateur, au final, tous les nombres sont en binaire, pcq en hw on a un état électrique "haut" ou "bas".

2.2 Mémoire

chaque case mémoire a 8bits d'espace, ainsi qu'une adresse.

mais un variable peut avoir une taille plus grande que 1 octet, elle prendra juste plusieurs bytes dans la mémoire

2.3 Variable

une variable est un endroit de la mémoire ou on va mémoriser une valeur d'un certain type

d'abord on doit déclarer la variable et on peut optionnellement l'initialiser avec une certaine valeur.

pour la déclaration, on doit indiquer au compilateur le type de nos donnée. Cela permet de définir les opérations autorisées ainsi que la place que prendra les données dans la mémoire, pour pouvoir réserver la bonne taille.

la taille (en byte) est généralement une puissance de 2 : 8, 16, 32, 64 bits

p.ex si on déclare un 'int', c'est une variable de 4byte. Il y aura alors 4 byte dans la RAM qui seront "réservés" à cette variable. quand on modifie la var. on va modifier les 4 bytes alloués à celle-ci dans la ram.

Caractéristiques d'une variable :

Cycle de vie d'une variable:

  1. déclaration : on dit on compil. le type de notre variable.
  2. affectation : on dit au compil ce que l'on veut mettre dans notre variable
  3. lecture : on demande quelle est la donnée qui est stockée dans notre variable
  4. destruction : on libère la mémoire précédemment utilisée

noms de variable :

  1. caractères maj/min
  2. chiffres 0-9
  3. underscore

ne pas commencer par un chiffre

et on ne peut pas utiliser les mots réservés

utiliser uniquement lowerCamelCase pour les variables

C est un langage à type faible, explicite et statique :

2.4 Types de base

Types de base :

Types dérivés :

Types des entiers:

Types des nombres à virgules

float (32 bits) : signe : 1bit , exposant : bit 8 bits, mantisse : 23 bits (≈ 7 chiffres significatifs) double (64 bits) signe : 1 bit, exposant : 11 bits, mantisse : 52 bits (≈ 16 chiffres significatifs)

2.5 Déclaration et affectation des variables/const

  1. Utiliser des noms de variables explicites

    • plus la portée est importante, plus cela doit être explicite
  2. initialiser de préférence les variables à leur déclaration

  3. NE PAS UTILISER #DEFINE !!!!!

  4. éviter aux maximum les constantes littérales

Chapitre 3 - Opérateurs

on utilise les opérateurs pour "mélanger" différentes données selon un schéma particulier.

3.1 Opérateurs arithmétiques

3.1.1 priorités

  1. parenthèses
  2. multiplications, divisions, modulo
  3. addition, soustractions
  4. affectation

3.1.2 types et domaines de définition

il ne faut pas dépasser les valeurs max et min possible d'une variable

il existe une librairie qui fournit des macros qui donne les valeurs max et min des différents type : <limits.h>

Ces valeurs dépendent de l'implémentation de la machine ou de l'archi du CPU

avec les float ou double, on a les nombres spéciaux suivants :

pour les entier, il n'existe pas de valeurs spéciale, mais certains bits ne sont simplement pas pris en compte.

3.1.3 Règles de conversion implicites

  1. dans une affectation, type le plus précis prioritaire
  2. dans une opération, on converti les type les plus faible vers les plus forts

3.1.4 Conversions explicites

modification de type réalisée par le programmeur

(<type>) <valeur>

on peut aussi utiliser des suffixes :

3.2 Opérateur d'affectation et d'assignation

i = i + 1 équivalent à i += 1

i = i & j équivalent à i &= j

3.3 Opérateurs d'incrémentation

il y a à chaque fois, deux possibilités :

  1. préfixés, on incrémente puis on affecte ++a
  2. postfixé, on affecte puis on incrémente a++

il faudrait toujours utiliser les opérateurs préfixés

3.4 Opérateur virgule

<opération1>, ..., <opérationN>

on évalue l'expression1, puis 2 jusqu'à N

la valeur de l'opération virgule est celle de la dernière valeur, la plus à droite

par exemple pour une boucle for :

for(int i=0, j=0; i<15; ++i, j+=2)

3.5 Opérations de comparaison

les opération de comparaison renvoient toujours soit true (1) soit false (0)!

exemple :

int a = 10 < 20; --> a vaut 1

int a = 10 > 20; --> a vaut 0

3.6 Opérateurs logiques

exemple :

bool a = true || false--> a vaut true

bool a = true && false--> a vaut false

Le membre de droite n'est évalué que si nécessaire. par exemple :

bool a = false && true, on n'évalue QUE false parce que dans un AND, les deux opérandes doivent être à true, donc comme le 1er vaut false, peu importe la valeur de la 2e opérande, la condition est fausse.

3.6 Opérateurs bit-à-bit

on compare chaque bit de la 1re opérande avec chaque bit de la 2e opérande, un par un.

par exemple :

int a = 0101 & 1100; a vaut 0100

3.7 Opérateurs de décalage de bit

Chapitre 4 - Entrées / Sorties

4.1. Syntaxe de printf()

4.1.1 Affichage / saisie

pour utiliser ces fonctions, il faut inclure la bibliothèque stdio.h : #include <stdio.h>

4.1.2 printf : syntaxe

printf("<chaine de commande>", <Liste d'expressions>);

<chaine de commandes>

Liste d'expressions

La liste d'expressions doit posséder (au moins) autant de valeurs qu'il y a de spécifications de format

Exemple :

renvoie : nb 20 x 7

4.2 spécifications de format

4.2.1 Caractères

4.2.2 Nombre entiers

4.2.3 Nombre à virgule flottante

il existe encore d'autres types mais qui ne sont que rarement utilisés.

4.2.4 Formats d'affichage

Avec le type char :

Avec les types réels, il est possible de donner des indications sur la largeur et la précision de la valeur.

La Largeur L fixe le nombre de caractère minimum que devra prendre notre nombre. Si la largeur est plus grande que la place que prend le nombre, des espaces sont affichés avant le nombre. La largeur comprend tous les caractères que devra afficher le nombre au minimum (valeurs décimales et point compris!)

La précision P fixe la précision, càd le nombre de décimales de notre nombre. La précision commence toujours par un point. La spécification .P indique que P décimales seront affichées.

%<L>.<P>f ou %<L>d par exemple.

exemple :

4.3 caractères d'échappement

aussi appelés caractères de contrôle, ils commencent toujours par le caractère backslash : \

il permettent de faire des actions spécifiques, comme un retour à ligne, une tabulation, ... :

4.4 Syntaxe de scanf()

exemple :

<chaine de commandes>

<Liste de variables>

Si on ajoute des caractères alphanumériques comme dans l'exemple précédent (/) il faut le taper pendant la saisie !

il faudrait donc taper par exemple 0 1 / 0 1 / 2 0 0 0 <enter>

scanf renvoie le nombre de champs remplis par l'utilisateur.

fflush(stdin) vide le buffer d'entrée

Chapitre 5 - Structures de contrôle

5.1 Branchement conditionnel

5.1.1 if

syntaxe :

ou éventuellement (mais à éviter)

La deuxième syntaxe ne fonctionne que pour une seule instruction, sinon, il faut mettre les accolades.

Attention, il n'y a pas de ; après le if, sinon les instructions à l'intérieur du bloc ne s'exécuteront pas!

image-20211027082059746

5.1.2 if else

syntaxe :

ou éventuellement (mais à éviter)

image-20211027082126248

5.1.3 Remarques

5.1.4 Styles de codage

Il existe plusieurs manière de placer les accolades dans le code. Cela n'influencera pas l'exécution du code mais uniquement sa lisibilité. Il n'y a pas vraiment de meilleure façon de faire, l'important est que le code soit lisible, compréhensible et d'être cohérent dans tout le programme (i.e. ne pas changer et/ou alterner de façon d'écrire)

Style Kernighan & Richtie
Style Whitesmiths

5.1.5 Opérateur ternaire

L'opérateur renvoie un résultat en fonction du résultat d'une opération logique.

Syntaxe :

5.1.6 Branchement multiple switch

switch seul

Syntaxe :

On va évaluer la valeur de value.

Si value == <val_A> alors on exécute toutes les instructions à partir de <instruction_A1> jusqu'à la fin.

Dès qu'on rencontre une condition vérifiée, on exécute les instructions à partir de cet endroit.

Organigramme :

image-20211027082557917

switch + break

Avec le mot clé break on indique que l'on veut quitter le branchement switch. On peut alors uniquement exécuter les instructions qui correspondent à la condition testée et pas les suivantes.

Syntaxe :
Organigramme:

image-20211027083303585

5.1.7 Comparaison switch vs if..else

switch ne permet que de tester des égalités entre valeurs entière ou de type char

switch ne peut pas tester des valeurs réelles, des chaînes de caractères, des structures, des tableaux ou des intervalles de valeurs.

 

Un if..else peut toujours remplacer un switch mais l'inverse n'est souvent pas possible.

5.2 Boucles

5.2.1 Boucle while

Tant que la condition est vérifiée, répéter [...]

Syntaxe

Structogramme

image-20211027084016501

Remarques

Avec la boucle while, tant que la condition est vraie, on exécute les instructions du bloc, mais le corps n'est pas forcément exécuté (si la condition est fausse dès le départ)

Il faut faire attention à ce que le corps de la boucle puisse modifier la condition afin de la rendre fausse, sinon on aura affaire à une boucle infinie.

5.2.2 Boucle do..while

Répéter [...] tant que la condition est vraie

Syntaxe

Structogramme

image-20211027084547871

Remarques

Les instructions du blocs sont exécutées puis répétées tant que la condition est vraie.

Cela signifie que le corps de la boucle est exécuté au moins une fois (étant donné que la condition est testée en fin de boucle)

Attention : L'instruction while du do..while doit se terminer par ;

5.2.3 Boucle for

Répéter un certain nombre de fois [...]

Syntaxe

Structogramme

image-20211027085207712

Remarques

La boucle for permet de répéter une ou plusieurs instructions un certain nombre de fois.

On utilise un indice pour compter le nombre de fois que la boucle est effectuée.

Sa valeur doit :

Précisions

initialisation

cette instruction doit initialiser la variable d'indice (exécutée qu'une seule fois, à l'entrée de la boucle)

Condition

cette condition doit être vraie pour que les conditions de la boucle s'exécutent

incrément

instruction qui incrémente (ou décrémente) la variable d'indice.

Fonctionnement

image-20211027085944518

(1) l'expression d' est exécutée (1). (2) est testée (2). (3) Si elle est remplie, alors, l' est exécutée (3), (4) puis l'<Incrémentation> est effectuée (4) (5) est à nouveau testée (5). (8) Si la n'est pas remplie (8), la boucle for prend fin. L'instruction d'<Incrémentation> est effectuée une dernière fois avant de terminer la boucle (7). La variable utilisée prend donc la prochaine valeur supérieure à la dernière autorisée par la , sauf dans le cas où la n'est d'emblée pas remplie.

Equivalent en boucle while

La boucle for

est équivalent avec une boucle while à

5.2.4 Quelle boucle choisir ?

La boucle for est à privilégier quand on connait à l'avance le nombre d'itérations à effectuer.

Si on ne connait pas à l'avance le nombre d'itérations :

5.3 Instructions de branchement inconditionnels

5.3.1 Instruction return

L'instruction return termine l'exécution de la fonction courante.

5.3.2 Fonction exit(<int>)

La fonction exit permet de terminer l'exécution où que l'on se trouve.

Elle prend un paramètre (code d'erreur entier) destiné à l'environnement d'exécution (0=OK, -1=ERR)

une directive #include <stblib.h> est nécessaire.

Cette instruction est utile pour quitter la fonction en cas d'erreur.

Autres instructions inconditionnelles

il existe également :

A l'exception de l'instruction break utilisée à l'intérieur d'un branchement switch, l'utilisation de ces instructions est à bannir!

Fonctionnement

image-20211027092145412

image-20211027092243175

image-20211027092313253

Chapitre 6 - Fonctions (partie 1)

6.1 Notion de fonction

6.1.1 Avantages de l'utilisation de fonctions

6.1.2 Appel de fonction

6.1.3 Définition de fonction

6.1.4 Prototype de fonction

L'en-tête de la fonction doit être connu par le compilateur avant son premier appel. Si la fonction est déclarée après son appel, il est alors nécessaire de définir son prototype avant son premier appel :

Si une fonction est définie dans un autre fichier, son prototype doit alors être inclus dans le fichier header (file.h) :

main.c

file.h

file.c

6.1.5 Valeur retournée

On utilise l'instruction return pour renvoyer une valeur.

L'exécution de toute fonction se termine si :

Types de retours

Types possibles :

Il faut toujours indiquer le type du retour.

Paramètres formels

→ paramètres indiqués dans la définition de la fonction

Fonction sans paramètre formel (void)

Fonction avec paramètre formels

Les paramètre peuvent être de n'importe quel type.

Paramètre effectifs

→ paramètres indiqué lors de l'appel de la fonction (arguments)

Les paramètres effectifs doivent être compatible avec les paramètres formels. Cela peut être des expressions, des constantes ou des variables.

Si la fonction retourne une valeur, elle peut ensuite être utilisée (affectée à une variable ou être utilisée dans une autre expression)

6.2 Variables locales et globales

6.2.1 Visibilité des variables

Les variables sont visibles dans le bloc où elles ont été déclarées.

Variables globales

ce sont des variables qui sont déclarées en dehors de toute fonction :

Variables locales

Elles sont déclarées dans un bloc (dans le corps d'une fonction)

6.2.2 Danger des variables globales

image-20211103090940105

6.2.3 Mot-clé static

Lorsqu'une variable locale est déclarée avec le mot-clé static:

Les variables statiques permettent de gérer la persistance tout en ayant un statut privé.

6.3 Organisation de la mémoire

image-20211103091415575