Langage C cheat sheet
|
1 Types
|
|
2 Constantes
|
|
3 Opérateurs
|
|
4 Opérateurs sizeof et mémoire
|
|
5 Conversion de type
|
|
6 Tests
|
|
7 Boucles
|
|
8 Pointeur
|
|
9 Tableaux
|
|
10 Fonctions
|
|
11 Structures
|
|
12 Chaîne de caractères (Strings)
|
|
13 Fichiers
|
|
entiers
|
||
char |
1 octets
|
-128 à 127
|
short |
2 octets
|
-32 768 à 32 767
|
int |
4 octets
|
-2 147 483 648 à 2 147 483 647
|
{{lang-c}}unsigned type |
pour un type entier non signé.
Exemple: {{lang-c}} unsigned char 0 à 255 |
|
|
virgule flottante
|
||
{{lang-c}}float |
2 octets
|
-3.4e38 à 3.4e38
|
double |
4 octets
|
- 1.7e308 à 1.7e308
|
type n'est utilisé qu'à 2 occasions :{{lang-c}}int a = 2; {{lang-c}}double var2 = 31.4;int fonction ( double a, char b) {...}
|
entières
|
|
{{lang-c}}11 |
en base 10
|
{{lang-c}}0xB |
en base 16
|
{{lang-c}}0b1011 |
en base 2
|
|
réelles
|
|
{{lang-c}}31.4 |
|
{{lang-c}}3.14e1 |
en notation ingénieur (3.14 x 101= 31.4)
|
|
caractères
|
|
{{lang-c}}'A' |
le code ASCII du caractère A : 65.
{{lang-c}} char c ='A'; {{lang-c}} char c = 65; |
|
chaines de caractères
|
|
{{lang-c}}"Hello world" |
un tableau de caractères constant (lecture seule)
|
{{lang-c}}"A" |
un tableau de 2 caractères contenant 'A' et '\0' le caractère de fin de chaîne.
|
|
Arithmétiques
{{lang-c}}(a=1, b=2) |
||
|
+
|
addition
|
{{lang-c}}a+2 == 3 |
|
-
|
soustraction
|
{{lang-c}}b-a ==1 |
|
*
|
multiplication
|
{{lang-c}}a*b == 2 |
|
/
|
division réelle
|
{{lang-c}}1.0/b == 0.5 |
|
/
|
division entière ou quotient
|
{{lang-c}}1/b == 0 (1/2 == 0) |
|
%
|
reste division ou modulo
|
{{lang-c}}3%b == 1 |
|
++
|
incrémentation
|
{{lang-c}}a++ == 2 |
|
||
|
décrémentation
|
{{lang-c}}a-- == 0 |
|
Relationnel
|
||
|
==
|
égalité
|
{{lang-c}}a == b faux(0) |
|
!=
|
différent
|
{{lang-c}}a != b vrai(1) |
|
>
|
supérieur
|
{{lang-c}}a > b faux(0) |
|
<
|
inférieur
|
{{lang-c}}a < b vrai(1) |
|
>=
|
supérieur ou égal
|
{{lang-c}}a >= b faux(0) |
|
<=
|
inférieur ou égal
|
{{lang-c}}a <= b faux(0) |
|
Logique
|
||
|
&&
|
ET
|
{{lang-c}}(a==1) && (b==3) faux(0) |
|
||
|
OU
|
{{lang-c}}(a==1) || (b==3) vrai(1) |
|
!
|
négation
|
{{lang-c}}!(a==b) vrai(1) |
|
Assignation
|
||
|
=
|
assigne à gauche la valeur de droite
|
{{lang-c}} a = 1 |
|
op=
|
mettre à jour une variable avec l'opération arithmétique op
|
{{lang-c}}a+=2; {{lang-c}}a=a+2; {{lang-c}}a%=1; {{lang-c}}a=a%1; |
{{lang-c}}sizeof() |
taille du type (en octets)
|
{{lang-c}}sizeof(int) vaut 4. |
{{lang-c}}& |
adresse
|
{{lang-c}}&a est l'adresse mémoire où {{lang-c}}a est stocké. |
{{lang-c}}* |
variable pointée,
indirection |
{{lang-c}}*p est la variable à l'adresse mémoire contenue dans {{lang-c}}p. Si {{lang-c}} p=&a, alors {{lang-c}}*p est un autre nom pour la variable {{lang-c}}a. |
|
Implicite lors d'une affectation
|
|
{{lang-c}}int a = 3.9; {{lang-c}}a = 3 (troncature) {{lang-c}}double f = 2/3; {{lang-c}}double f = 0; {{lang-c}}f = 0.0 |
|
|
Implicite entre 2 opérandes de type différent
|
|
{{lang-c}}double f = 2.0/3; {{lang-c}}double f = 2.0/3.0; {{lang-c}} f = 0.666 Règle: opérande de type de plus petite capacité (entier 3) promu vers le type de l'opérande de plus grande capacité (double) |
|
|
Explicite
|
|
{{lang-c}}( type ) |
operateur de conversion de
type, de cast. {{lang-c}}(double)1/2 {{lang-c}}1.0/2 {{lang-c}}0.5 {{lang-c}}printf("%d\n", (int) 3.94); affiche {{lang-c}}3 |
|
if
|
{{lang-c}}if( condition ) { //la condition est évaluée. //si vrai, ce bloc de 2 instructions est exécuté {{lang-c}}instruction1; {{lang-c}}instruction2;{{lang-c}}} //si faux, le bloc n'est pas exécuté et l'exécution passe ici. |
|
if .. else
|
{{lang-c}}if( condition ) { //la condition est évaluée. //si vrai, ce bloc de 2 instructions est exécuté {{lang-c}}instruction1; {{lang-cpp}}instruction2; {{lang-c}}} {{lang-c}}else { //si faux, ce bloc est exécuté au lieu du précédent. {{lang-c}}instruction3; {{lang-c}}} Exemple: {{lang-c}}if ((n%2) == 1) {{{lang-c}}printf("nombre impair\n");{{lang-c}}} {{lang-c}}else {printf("nombre pair\n");{{lang-c}}} |
|
if .. else if .. else if .. else
|
{{lang-c}}if( condition1 ) { //la condition 1 est évaluée. //si vrai, ce bloc de 2 instructions est exécuté {{lang-c}}instruction1; {{lang-c}}instruction2;{{lang-cpp}}} {{lang-cpp}}else if( condition2 ){ //si condition 1 faux mais condition 2 vrai, instruction 3 est exécutée. {{lang-c}}instruction3; {{lang-c}}} {{lang-c}}else { //si condition 1 et 2 faux, instruction4 est exécutée. {{lang-cpp}}instruction4; {{lang-c}}} |
( condition ) est un test sur une variable {{lang-c}}(a), une opération {{lang-c}}(a!=1) ou le résultat d'une fonction {{lang-c}}(ftest(param)).{{lang-c}} condition est FAUX si la valeur est 0, VRAI pour toute valeur différente de 0.
|
while
|
{{lang-c}}while( condition ) { //exécuter instructions 1 et 2 de ce bloc, tant que condition vrai. {{lang-c}}instruction1; {{lang-c}}instruction2; //retour au test de condition {{lang-c}}} Exemple : Afficher la suite 0 1 ... 8 9 {{lang-c}}i=0; {{lang-c}}while(i<10) { {{lang-c}} printf("%d\n",i); {{lang-c}} i++; {{lang-c}}} |
|
do { } while;
|
{{lang-c}}do { {{lang-c}}instruction1; {{lang-c}}instruction2;//exécuter instructions 1 et 2 du bloc, {{lang-c}}} while( condition ); //tant que condition vrai. Contrairement à {{lang-c}}while, le bloc est toujours exécuté au moins une fois même si {{lang-c}}condition est faux dés le départ. {{lang-c}}do .. while(); est la seule boucle avec un {{lang-c}}; final. |
|
for
|
|
//Executer initial, puis tester la condition
{{lang-c}}for ( initial; condition ; iteration) { //exécuter instructions 1 et 2 de ce bloc, tant que condition vrai. {{lang-c}}instruction1; {{lang-c}}instruction2; //exécuter iteration avant retour au test de condition {{lang-c}}} Exemple: Afficher la suite 0 1 ... 8 9 {{lang-c}}for (i=0; i<10; i++) { {{lang-c}} printf("%d\n",i); {{lang-c}}} |
|
for while équivalence
|
{{lang-c}}for ( initial; condition ; iteration) { {{lang-c}}instructions; {{lang-c}}} {{lang-c}}initial; {{lang-c}}while( condition ) { {{lang-c}}instructions; {{lang-c}}iteration;{{lang-c}}} |
{{lang-c}}break; sortir immédiatement d'une boucle : la boucle la plus proche si dans des boucles imbriquées.{{lang-c}}continue; ignorer les instructions de la boucle situées après {{lang-c}}continue;, et retourner au test de la condition. Si dans une boucle {{lang-c}}for, exécuter l'instruction d'iteration avant le test.
|
Un pointeur est une adresse mémoire (pointeur == adresse). Un type adresse est
type*. Ex: double* est le type {adresse d'un double}. Declaration |
|
{{lang-c}}type *p; |
{{lang-c}}p est l'adresse d'une variable de type type. |
{{lang-c}}int *p = NULL; |
{{lang-c}}p est l'adresse d'un entier. Initialisé à l'adresse invalide {{lang-c}}NULL ({{lang-c}}0, une bonne pratique). |
|
RAM d'un CPU 64bits (adresses codées sur 8 octets) après l'initialisation avec NULL :
Variables: {{lang-c}} p --------------------------------------{{lang-c}} | 0x0000 (8 octs) | -------------------------------------- @mem: {{lang-c}} 0x040 0x048 |
|
|
Initialisation (2 options)
|
|
{{lang-c}}int *p = malloc( sizeof(int) ); {{lang-c}}int *p; {{lang-c}}p=malloc( sizeof(int) ); |
Initialise
{{lang-c}}p avec l'adresse d'un bloc de 4 octets réservé avec {{lang-c}}malloc(). |
{{lang-c}}int *p = &a; {{lang-c}} int *p; p=&a; |
Initialise
{{lang-c}}p avec l'adresse de {{lang-c}}a (avec {{lang-c}}int a=11;;) |
|
Variables:
{{lang-c}} p a-----------------------------------------------------{{lang-c}} | 0xC10 | | 11 |----------------------------------------------------- @mem: {{lang-c}} 0x040 0x048 0xC10 0xC14 |
|
|
Usage
|
|
|
Un pointeur ne peut pas être utilisé avant son initilialisation avec une adresse valide.
|
|
{{lang-c}}p |
une adresse
Ex: {{lang-c}}p=&a {{lang-c}}p=0xC10 |
{{lang-c}}*p |
la variable pointée :
{{lang-c}}a. Ex: {{lang-c}}*p= 12 {{lang-c}}a=12; |
|
Variables:
{{lang-c}} p ------- * -------> a-----------------------------------------------------{{lang-c}} | 0xC10 | | 12 |----------------------------------------------------- @mem: {{lang-c}} 0x040 0x048 0xC10 0xC14 |
|
{{lang-c}}p+i (avec i entier) |
adresse du ième
{{lang-c}}int en mémoire après {{lang-c}}p. Donc {{lang-c}}p+i vaut {{lang-c}}p+i*sizeof(int), quand {{lang-c}}p est de type {{lang-c}}int*. |
|
Tableau statique
La taille du tableau est déterminée à la compilation et elle est fixe pendant toute l'exécution. La taille est une constante. |
|
{{lang-c}}int t[3]; |
un tableau de 3 entiers (valeurs aléatoires)
|
{{lang-c}}double tab[4]={-1.2, 3.2}; |
un tableau de 4
{{lang-c}}double. Les 2 premiers éléments sont -1.2 et 3.2, les 2 autres nuls. |
{{lang-c}}double tab[]={-1.2, 3.2}; |
un tableau de
{{lang-c}}double, taille 2 imposé par l'initialisation |
|
Tableau dynamique
La taille du tableau est déterminée pendant l'exécution et peut être modifiée. La taille est généralement une variable. |
|
{{lang-c}}double *tab; {{lang-c}}tab = (double*) malloc ( n*sizeof (int) ); |
un tableau de
{{lang-c}}n {{lang-c}}double. Valeurs initiales aléatoires. |
|
Equivalence pointeur et nom d'un tableau
|
|
{{lang-c}} tab {{lang-c}}&tab[0] {{lang-c}}tab+i {{lang-c}}&tab[i] |
L'identifiant d'un tableau est l'adresse de son premier élément.
Par nature pour un tableau dynamique, où {{lang-c}}tab est un pointeur. Par définition pour un tableau statique, où l'identifiant est un alias pour l'adresse du 1er élément. |
|
accès aux éléments d'un tableau statique ou dynamique
|
|
{{lang-c}}tab[i] ou {{lang-c}}*(tab+i) |
i+1ième élément avec i=0,...taille-1
{{lang-c}}tab[0] est le premier élément. {{lang-c}}tab+i est l'adresse du ième élément après le premier. |
|
Copie entre deux tableaux
|
|
{{lang-c}}for (i=0; i< taille ; i++) { {{lang-c}} tab1[i]=tab2[i]; {{lang-c}}}{{lang-c}}tab1 = tab2;L'opération est incorrecte si {{lang-c}}tab1 est un tableau dynamique (un pointeur). Aucune copie d'éléments n'est effectué : le même tableau {{lang-c}}tab2 est accessible via {{lang-c}}tab1 et {{lang-c}}tab2. L'opération est illégale si {{lang-c}}tab1 est un tableau statique : {{lang-c}}tab1 est une adresse constante non modifiable. |
|
|
Comparaison du contenu de deux tableaux
|
|
{{lang-c}}equal=1; {{lang-c}}for (i=0; i< taille ; i++) { {{lang-c}}if( tab1[i]!=tab2[i] ) { {{lang-c}}equal=0; {{lang-c}}break; {{lang-c}}} {{lang-c}}}{{lang-c}}tab1 == tab2{{lang-c}}tab1 et {{lang-c}}tab2 : donc test toujours FAUX. |
|
|
Passage par valeur
|
|
Pour passer des valeurs à une fonction: la fonction utilise le type de retour (
{{lang-c}}return) pour son résultat. {{lang-c}}double add5( double value ) //la variable locale value est initialisée avec 3.14, la valeur de n {{lang-c}}{ double res= value+5; {{lang-c}}return res; {{lang-c}}} int main() {{lang-c}}{ double n=3.14; {{lang-c}}n= add5(n); //on passe la valeur n. {{lang-c}} ... //n vaut maintenant 8.14 {{lang-c}}} |
|
Passage par adresse
|
|
Pour passer des variables à une fonction: la fonction retourne ses résultats en modifiant les variables d'origines via leurs adresses.
{{lang-c}}void add5( double *var ) //le pointeur var est initialisé avec adresse de n {{lang-c}}{ *var = *var + 5; //operateur d'indirection pour accéder à la variable pointée n {{lang-c}}} {{lang-c}}{ ... {{lang-c}}double n=3.14; {{lang-c}}add5(&n); //on passe l'adresse de n. {{lang-c}}... } //n vaut maintenant 8.14. Note: l'adresse mémoire est le moyen pour la fonction {{lang-c}}add5()d'accéder à des variables qui ne lui appartiennent pas, et donc lui sont inconnues (cf portée des variables). |
|
Passage par adresse pour retourner plusieurs résultats
|
|
Car
{{lang-c}}return ne permet de retourner qu'un résultat {{lang-c}}void divisionEntiere ( int nombre, int diviseur, int *quotient, int *reste ){{lang-c}}{ {{lang-c}} *quotient = nombre/diviseur;{{lang-c}} *reste = nombre%diviseur; {{lang-c}}} {{lang-c}}{ ... {{lang-c}}int n=7, d=3; {{lang-c}}int quotient, reminder; //variable pour les résultats {{lang-c}}divisionEntiere(n, d, "ient, &reminder); //passage de leurs adresses {{lang-c}}... } |
|
Passage d'un tableau
|
|
Passer l'adresse du premier élément ( le nom du tableau) et le nombre d'éléments.
Passage par adresse, toute modification des éléments a lieu sur les éléments du tableau d'origine. |
{{lang-c}}void tab_init( double *tab, int n ) {{lang-c}}{ {{lang-c}}int i=0; {{lang-c}}for (i=0; i<n ; i++) { tab[i]=0; {{lang-c}}} {{lang-c}}} {{lang-c}}int main() {{lang-c}}{ double u[3]; {{lang-c}}tab_init(u,3); {{lang-c}}return(0); {{lang-c}}} |
|
Définition et déclaration d'une structure
|
|
{{lang-c}}struct person { char name[30];{{lang-c}}int age;{{lang-c}}}; {{lang-c}}struct person joe, diane; |
Définit le type
{{lang-c}}struct person : une structure avec 2 membres ou champs. Attention: la définition finit avec un ;. Déclare 2 structures de type {{lang-c}}struct person. |
|
Définition et déclaration avec un
{{lang-c}}typedef |
|
{{lang-c}}typedef struct { char name[30];{{lang-c}}int age;{{lang-c}}} person_t; {{lang-c}}person_t joe, diane; |
Définit le type
{{lang-c}}person_t: une structure avec 2 membres. {{lang-c}}typdef permet de définir un alias pour un type : utilisé ici pour alléger le type en 2 mots {{lang-c}}struct person en un type en un mot {{lang-c}}person_t. Déclare 2 structures de type {{lang-c}}person_t. |
|
Initialisation à la déclaration
|
|
{{lang-c}}struct person joe ={"Dupont", 13}; {{lang-c}}struct person joe ={.age= 13, .name="Dupont"}; |
Valide à la déclaration.
Après la déclaration, il faut accéder chaque membre séparément pour l'initialiser (cf ci-dessous). |
|
Accès aux membres
|
|
{{lang-c}}person_t *pdiane;pdiane= malloc ( sizeof ( person_t) ); |
Crée 1 structure, allouée via un
{{lang-c}}malloc(). |
{{lang-c}}joe.age= 27; {{lang-c}}strcpy(diane.name,"Verovski"); |
operateur
., pour accéder à partir d'une structure précède. Note: Avec un pointeur {{lang-c}}pdiane, ( *pdiane ).age = 45; est valide mais écriture déconseillée. |
{{lang-c}}pdiane->age = 27; {{lang-c}}strcpy(pdiane->name,"Verovski"); |
opérateur
{{lang-c}}->, pour accéder à partir d'un pointeur. Note: {{lang-c}}(&joe)->age=27; est valide mais écriture déconseillée. |
|
copie de structures
|
|
{{lang-fr}}joe = diane; |
Les valeurs des membres de
{{lang-c}}diane sont copiés dans les membres de {{lang-c}}joe. Note : valide entre structures de même type, donc de même taille mémoire, mais invalide pour la copie de tableaux (Voir section tableaux). |
|
Fonction et strucutre
|
|
{{lang-c}}void initPerson ( struct person *p ) {{lang-c}}{ p->page = 0; {{lang-c}}strcpy(p->name, "");{{lang-c}}} {{lang-c}}{... {{lang-c}} struct person john; {{lang-c}}initPerson(&joe); ... |
|
|
ou avec typedef :
{{lang-c}}void initPerson ( person_t *p ) {{lang-c}}{ p->page = 0; {{lang-c}}strcpy(p->name, "");{{lang-c}}} {{lang-c}}{... {{lang-c}} person_t john; {{lang-c}}initPerson(&joe); ... Le passage par adresse est privilégié pour l'efficacité : pas de copie de toutes les valeurs de la structure. |
|
|
Déclaration
|
|
{{lang-c}}char name[30]; |
un tableau de
{{lang-c}}char, pouvant servir à stocker une chaîne. |
{{lang-c}}char name[30]= " marion " ; {{lang-c}}char name[30]={'m','a','r','i','o','n','\0'}; |
un tableau, initialisé avec la chaîne de caractères
{{lang-c}}"marion". |
{{lang-c}}char name[]=" marion "; {{lang-c}}char *name=" marion "; |
un tableau de 7
{{lang-c}}char (6+caractère de fin {{lang-c}}\0, initialisé avec la chaîne de caractères {{lang-c}}"marion". une adresse/pointeur {{lang-c}}name initialisé avec l'adresse d'une chaîne constante {{lang-c}}"marion". A éviter, la chaîne n'est pas modifiable. |
|
Initialisation après déclaration
|
|
{{lang-c}}char name[30];{{lang-c}}name="marion"; |
(Voir Tableaux pour plus de détail). Copie d'adresses et non de contenu :
{{lang-c}}name est l'adresse du premier élément de name. |
{{lang-c}}strcpy(name, " marion "); |
copie la chaîne
{{lang-c}}" marion " dans {{lang-c}}name. |
{{lang-c}}sprintf(name, "%s"," marion "); |
copie la chaîne
{{lang-c}}"marion" dans {{lang-c}}name`. |
|
Lire/extraire une chaîne de caractères
|
|
{{lang-c}}scanf("%s", name); |
Lire un mot au clavier. Paramètre: adresse du tableau = son identifiant.
|
{{lang-c}}fgets(name, SIZE, stdin); |
Lire une ligne au clavier. Le
{{lang-c}}'\n' est ajouté à la fin de name. SIZE est la taille max du tableau name |
{{lang-c}}sscanf(str, "%s %d", name, &age); |
Comme
{{lang-c}}printf() mais la lecture est faite dans la chaîne {{lang-c}}printf() et non la mémoire du clavier |
|
Ecrire une chaîne de caractères
|
|
{{lang-c}}strcpy(dest, src); |
Copie la chaîne
{{lang-c}}src dans {{lang-c}}dest. Au programmeur de s'assurer que le tableau {{lang-c}}dest est assez grand |
{{lang-c}}printf("%s", name); |
Affiche une chaîne de caractère à partir de l'adresse du premier élément du tableau, d'où l'identifiant du tableau en paramètre.
Le {{lang-c}}'\0' indique à printf où arrêter l'affichage des caractères. |
{{lang-c}}sprintf(name, "%s %d"," marion ", age); |
comme
{{lang-c}}printf(), mais la chaîne est écrite dans {{lang-c}}name et non dans le terminal. |
|
Autres manipulation
|
|
{{lang-c}}char dest[10]="tic-", src[5]="toc"; {{lang-c}}strcat(dest, src); |
Concaténation : ajoute à la fin de
{{lang-c}}dest, le contenu de la chaîne {{lang-c}}src |
{{lang-c}}strcmp(dest, src); |
Comparaison : retourne 0 si le contenu de
{{lang-c}}dest est identique au contenu de {{lang-c}}src |
{{lang-c}}dest == src |
(voir Tableaux pour plus de détail) Compare les adresses mémoire des 2 chaînes (toujours Faux) et non leur contenu.
|
'\0'. |
Lecture d'un fichier
|
|
|
Un fichier texte à lire (la première ligne contient le nombre de données):
3 loic 65.3 marc 43.2 gerard 77.1 |
|
|
Code correspondant:
{{lang-c}}File *f=NULL; {{lang-c}}double poids=0; {{lang-c}}int n=0; {{lang-c}}char name[30]; {{lang-c}}f=fopen("file.txt","r"); {{lang-c}}if (f==NULL) { {{lang-c}} printf("error open\n") ; return (-1); {{lang-c}}} fscanf("%d",&n); /lecture du nombre de ligne/ while( fscanf(f, "%s %lf", name, &poids ) != EOF) { {{lang-c}} printf("%s %f", name, poids);{{lang-c}}} |
No comments yet.
Cheatography n. The art of mapping complex subjects into clear, instantly navigable reference guides.