Programmation C
Types élémentaires - Variables - Constantes - Pointeurs - Opérateurs |
|
|
|
|
Types élémentaires
- Types entiers
- short : stockage sur au moins 2 octets
- Sur 2 octets valeurs possibles de -32768 à 32767 (de -215 à 215-1)
- int : stockage sur au moins 2 octets suivant le compilateur, généralement 4 octets
- Sur 2 octets, valeurs possibles de -32768 à 32767 (de -215 à 215-1)
- Sur 4 octets : valeurs possibles de -2147483648 à 2147483647 (de -231 à 231-1)
- long : stockage sur au moins 4 octets suivant le compilateur
- Sur 4 octets valeurs possibles de -2147483648 à 2147483647 (de -231 à 231-1)
- Sur 8 octets de -9223372036854775808 à 9223372036854775807 (de -263 à 263-1)
- long long : stockage sur au moins 8 octets suivant le compilateur
- Sur 8 octets de -9223372036854775808 à 9223372036854775807 (de -263 à 263-1)
- Types entiers non signés (valeurs positives seules possibles)
- unsigned short : stockage sur au moins 2 octets
- Sur 2 octets valeurs possibles de 0 à 65535 (de 0 à 216-1)
- unsigned int : stockage sur au moins 2 octets suivant le compilateur, généralement 4 octets
- Sur 2 octets, valeurs possibles de 0 à 65535 (de 0 à 216-1)
- Sur 4 octets : valeurs possibles de 0 à 4294967295 (de 0 à 232-1)
- unsigned long : stockage sur au moins 4 octets suivant le compilateur
- Sur 4 octets valeurs possibles de 0 à 4294967295 (de 0 à 232-1)
- Sur 8 octets valeurs possibles de 0 à 18446744073709551615 (de 0 à 264-1)
- unsigned long long : stockage sur au moins 8 octets suivant le compilateur
- Sur 8 octets valeurs possibles de 0 à 18446744073709551615 (de 0 à 264-1)
- size_t : stockage sur 4 octets si compilation en 32 bits, sur 8 octets si compilation en 64 bits
Utilisé pour représenter des "tailles" (nombre d'enregistrements d'un tableau, nombre d'octets...)
- Types réels
- float : stockage sur 4 octets
- 7 chiffres de précision sur la mantisse, exposant de -38 à +38, valeurs positives ou négatives
- double : stockage sur 8 octets
- 16 chiffres de précision sur la mantisse, exposant de -308 à +308, valeurs positives ou négatives
- long double : stockage sur au moins 8 octets (non nomalisé)
- Type booléen
- Pas de type booléen en C89
- Assimilation de toute variable à un booléen
- Vrai si différente de zéro
- Faux si égale à zéro
- Utilisation fréquente du type int pour les variables booléennes
- Introduction du type bool et des constantes littérales true et false avec le C99 et son API stdbool
- Type caractère
- char : stockage sur au moins 1 octet, généralement 1 octet
- Sur 1 octet valeurs décimales de -128 à 127 (de -27 à 27-1)
- Stockage de la valeur ASCII du caractère
- Type caractère non signé
- unsigned char : stockage sur au moins 1 octet, généralement 1 octet
- Sur 1 octet valeurs décimales de 0 à 255 (de 0 à 28-1)
- Souvent utilisé pour coder les octets de mémoire
- Type chaîne de caractères
- "Type" void
- Type spécial utilisé pour indiquer "vide"
- Non utilisable pour définir une variable car elle ne pourrait rien contenir
- Possibilité de définir un pointeur qui ne pointe spécifiquement sur aucun type (voir plus loin)
- Type retour pour les fonctions qui ne retournent rien (voir chapitre sur les fonctions)
- Type de la liste de paramètres pour les fonctions qui ne prennent pas de paramètre (voir chapitre sur les fonctions)
- ...
|
Variable
- Support du stockage de l'information quand celle-ci est susceptible de varier au cours de l'exécution du programme
- Caractérisée par le nom qui la désigne (respect des conventions du langage C pour le choix des noms de variable), le type de la valeur qu'elle contient et la valeur qu'elle contient
- Typage immuable et obligatoire
- Syntaxe de définition
nonType nomVariable;
- Exemples
- int i;
- double d;
- long l = 1000;
- char c = 'A';
|
Constante
|
- Exemple
#include <stdbool.h>
void main(void) {
// Valeur définie en utilisant une constante int donnée en notation binaire
const unsigned char CUC = 0b0100110;
bool b = true;
char c;
short s;
int i;
long l;
long long ll;
float f;
double d;
unsigned char uc;
unsigned int ui;
// Valeur affectée en utilisant une constante littérale caractère
c = 'a';
// Valeur affectée en utilisant la constante littérale false
b = false;
// Valeur affectée en utilisant une constante littérale int
s = -10;
// Valeur affectée en utilisant une constante littérale int
i = 1;
// Valeur affectée en utilisant une constante littérale long
l = -1000000000L;
// Valeur affectée en utilisant une constante littérale entière sur 64 bits
ll = 4000000000000000000LL;
// Valeur affectée en utilisant une constante littérale float
f = -0.98e-10F;
// Valeur affectée en utilisant une constante littérale double
d = 0.56e284;
// Valeur affectée en utilisant une constante littérale int
uc = 150;
// Valeur affectée en utilisant une constante int donnée en notation hexadécimale
ui = 0xE5A845DC;
}
|
TypesElementaires.c - TypesElementaires.exe |
|
Transtypage
|
- Exemple
#include <stdio.h>
void main(void) {
printf("%d\n", (int)3.82);
printf("%d\n", (int)-3.98);
printf("%d\n", (int)3.72 * 10);
printf("%d\n", (int)(3.72 * 10));
printf("%c\n", (char)110);
}
|
Transtypage.c - Transtypage.exe |
|
|
Pointeurs
- Possibilité d'utiliser explicitement des variables de type adresse mémoire
- Pas de type pointeur générique mais plutôt existence d'un type pointeur pour chacun des types élémentaires : pointeur sur int, pointeur sur unsigned char, pointeur sur void...
- Quel que soit le type pointeur d'une variable, stockage de l'adresse sur 4 octets en 32 bits, sur 8 octets en 64 bits
- Pointeurs généralement notés en hexadécimal.
Exemples : 0xFEA456C3 en 32 bits, 0x78FF4376CD6290AB en 64 bits
- Transtypage possible de n'importe quel type pointeur vers n'importe quel type pointeur
- Syntaxe de définition d'une variable nommée nomVariable de type pointeur sur le type nomType
nomType* nomVariable;
ou
nomType * nomVariable;
ou
nomType *nomVariable;
- Existence de l'opérateur & permettant d'obtenir l'adresse mémoire de n'importe quelle variable (ou constante) sous la forme d'un pointeur sur le type de la variable
- Variable nomVariable du type nomType -> &nomVariable du type pointeur sur nomType
- Existence de l'opérateur * permettant de désigner la valeur de la variable pointée par n'importe quel type de variable pointeur : un int pour pointeur de type int *, un unsigned char pour pointeur
de type unsigned char *...
- Variable nomVariable du type pointeur sur nomType -> *nomVariable du type nomType
- ATTENTION : Sauf à vouloir planter l'exécution, impossibilité de stocker de l'information dans la zone mémoire pointée par une variable de type pointeur si cette zone mémoire
- ne correspond pas à une "vraie" variable
- n'a pas été correctement allouée dynamiquement à cette fin
- Existence de la constante NULL généralement égale à l'adresse mémoire 0x00000000 en 32 bits, 0x0000000000000000 en 64 bits
- Fréquemment utilisée pour affectation aux variables de type pointeur lorsqu'elles ne contiennent pas d'adresse valide (pas l'adresse mémoire d'une zone mémoire valide)
- Pointeurs pour faire quoi ?
- Gérer finement la mémoire
- Gérer les tableaux et en particulier l'allocation dynamique de mémoire pour les tableaux
- Passer des paramètres à des fonctions
- ...
|
- Exemples
#include <stdio.h>
void main(void) {
int val = 10;
int* pVal = NULL;
printf("%p\n%p\n\n", &val, pVal);
pVal = &val;
printf("%p\n%p\n\n", &val, pVal);
}
|
Pointeurs1.c - Pointeurs1.exe |
000000394610F9C0
0000000000000000
000000394610F9C0
000000394610F9C0
|
|
#include <stdio.h>
void main(void) {
int val = 10;
int* pVal = &val;
printf("%d %d\n", val, *pVal);
*pVal = 100;
printf("%d %d\n", val, *pVal);
val = 200;
printf("%d %d\n", val, *pVal);
}
|
Pointeurs2.c - Pointeurs2.exe |
|
|
Opérateurs
- Existence d'opérateurs associés aux différents types
- = : opérateur d'affectation, résultat du type de la variable affectée et égal à la valeur affectée
- Types entiers
- Résultat booléen
- == : test d'égalité
- != : test de différence
- > : test de supériorité
- < : test d'infériorité
- >= : test de supériorité ou égalité
- <= : test d'infériorité ou égalité
- Résultat entier
- + : addition entière
- - : soustraction entière
- * : multiplication entière
- / : division entière
- % : reste de la division entière (modulo)
- << : décalage de bit(s) vers la gauche (souvent utilisé pour multiplier par deux, quatre, huit... les entiers positifs)
- >> : décalage de bit(s) vers la droite (souvent utilisé pour diviser par deux, quatre, huit... les entiers positifs)
- & : et binaire (et bit à bit)
- | : ou binaire (ou bit à bit)
- ^ : ou exclusif (ou exclusif bit à bit)
- ++ : incrément de 1
- Si ++ placé avant la variable, incrément de 1 et obtention de la valeur incrémentée
- Si ++ placé après la variable, obtention de la valeur initiale puis incrément de 1
- -- : décrément de 1
- Si -- placé avant la variable, décrément de 1 et obtention de la valeur décrémentée
- Si -- placé après la variable, obtention de la valeur initiale puis décrément de 1
- ...
- ...
- Types réels
- Résultat booléen
- == : test d'égalité
- != : test de différence
- > : test de supériorité
- < : test d'infériorité
- >= : test de supériorité ou égalité
- <= : test d'infériorité ou égalité
- Résultat réel
- + : addition réelle
- - : soustraction réelle
- * : multiplication réelle
- / : division réelle
- ...
- ...
- Type "booléen"
- == : test d'égalité
- != : test de différence
- && : et logique
- || : ou logique
- ! : non
- Types caractères
- Assimilables aux types entier
- Types pointeurs
- Traités dans le chapitre "Tableaux"
- Opérateur sizeof
- Appliqué à une constante ou une variable : nombre d'octets occupés par la constante ou la variable
- Appliqué à un type : nombre d'octets occupés par une constante ou une variable définie de ce type
- Obtention d'une valeur de type size_t (type entier non signé dont la précision varie selon l'architecture cible de compilation, 4 ou 8 octets)
- Syntaxe
sizeof(...)
-> taille en octets de l'item donné entre parenthèses
- Opérateurs opérateur=
- Avec tous les opérateurs portant sur deux items, possibilité d'implanter la syntaxe var = var opérateur item en utilisant la syntaxe var opérateur= item
- Exemples
- Existence de règles définissant la possibilité de marier des variables ou des constantes de types différents au sein d'une même opération, et, si ce mariage est possible, ce qu'est le type du résultat
et comment il est calculé
- Existence de priorités entre opérateurs
- A priorités égales, évaluation de gauche à droite
Conseil : mettre des parenthèses pour éviter les risques d'écriture érronée
|
- Exemples
#include <stdio.h>
#include <stdbool.h>
void main(void) {
int a1 = 10;
int a2;
int a3;
a3 = (a2 = a1 - 1) - 1;
printf("%d %d %d\n", a1, a2, a3);
printf("%d %d %d\n", a1 + a2, a1 * a2, a1 / a2);
printf("%d %d\n", a1 << 2, a2 >> 2);
printf("%d %d\n", a1 == a2, a1 != a2);
printf("\n");
double d1 = 1.1;
double d2 = 2.1;
printf("%lf %lf\n", d1, d2);
printf("%lf %lf %lf %lf\n", d1 + d2, d1 - d2, d1 * d2, d1 / d2);
printf("%d %d\n", d1 == d2, d1 < d2);
printf("\n");
char c = 'a';
c += 10;
printf("%c\n", c);
printf("\n");
bool b1 = true;
bool b2 = false;
printf("%d %d\n", b1, b2);
printf("%d %d %d %d\n", true && true, true && false, false && true, false && false);
printf("%d %d %d %d\n", true || true, true || false, false || true, false || false);
printf("%d %d\n", !b1, !b2);
}
|
Operateurs1.c - Operateurs1.exe |
10 9 8
19 90 1
40 2
0 1
1.100000 2.100000
3.200000 -1.000000 2.310000 0.523810
0 1
k
1 0
1 0 0 0
1 1 1 0
0 1
|
|
#include <stdio.h>
#include <stdbool.h>
void main(void) {
int a1 = 55;
int a2 = 10;
double d1 = 1.1;
double d2 = 2.1;
char c = 'a';
printf("%d %lf %lf\n", a1 / a2, a1 / a2, (double)a1 / a2);
printf("%d %lf\n", d1 / d2, d1 / d2);
printf("%c %d %lf\n", c + 1, c + 1, c + 1);
}
|
Operateurs2.c - Operateurs2.exe |
5 0.000000 5.500000
818089009 0.523810
b 98 0.000000
|
|
#include <stdio.h>
#include <stdbool.h>
void main(void) {
int i;
long l;
long long ll;
float f;
double d;
char c;
bool b;
void* p;
printf("Variable int : %zu\n", sizeof(i));
printf("Variable long : %zu\n", sizeof(l));
printf("Variable long long : %zu\n", sizeof(ll));
printf("Variable float : %zu\n", sizeof(f));
printf("Variable double : %zu\n", sizeof(d));
printf("Variable char : %zu\n", sizeof(c));
printf("Variable bool : %zu\n", sizeof(b));
printf("Variable void* : %zu\n", sizeof(p));
printf("\n");
printf("Type int : %zu\n", sizeof(int));
printf("Type long : %zu\n", sizeof(long));
printf("Type long long : %zu\n", sizeof(long long));
printf("Type float : %zu\n", sizeof(float));
printf("Type double : %zu\n", sizeof(double));
printf("Type char : %zu\n", sizeof(char));
printf("Type bool : %zu\n", sizeof(bool));
printf("Type void* : %zu\n", sizeof(void *));
}
|
OperateurSizeof.c - OperateurSizeof.exe |
Variable int : 4
Variable long : 4
Variable long long : 8
Variable float : 4
Variable double : 8
Variable char : 1
Variable bool : 1
Variable void* : 8
Type int : 4
Type long : 4
Type long long : 8
Type float : 4
Type double : 8
Type char : 1
Type bool : 1
Type void* : 8
|
|
|