“Rappels” de C
ECP – Option SAHenri Fallon <[email protected]>
Objectifs
Théorie + pratique Compréhension générale du langage Repartant « du début » Pour ceux qui savent déjà coder : retournez
dormir :-)
Syntaxe basique
Les instructions se terminent par un ' ; ' Les instructions peuvent se regroupper avec
des accollades : { .... } Les commentaires entre /* et */
Premier programme
Source ExécutableCompilation
Compréhensible par un humain (un peu entrainé)
Non utilisable par la machine
Incompréhensible par un humain (ou alors vraiment très entrainé !)
Utilisable par la machine
Premier programme (2)
int main(void) {
fputs(“hello world\n”);
}
implémentation
Premier programme (3)
int main(void) {puts("hello world\n");
}compilation
implémentation
$ gcc -out hello hello.c
Premier programme (4)
int main(void) {puts("hello world\n");
}compilation
implémentation
$ gcc -out hello hello.cexécution
$ ./hellohello world$
Les variables
Se déclarent avant les instructions
Ont un type Entier (int, short, ...) éventuellement “unsigned” Caractère (char) décimaux (float, double, ...)
Se convertissent
int i;float f;char c;
Utilisation de variablesint main( void ) {
int i;i = 0;if( i == 0 ) {
puts("i est nul\n"); }i=5;if( i == 0 ) {
puts("i est encore nul\n"); }
}
$ ./programme2i est nul$
Instructions conditionnelles
utilisation de « if »
pas de point-virgule après if ou else bonne habitude : toujours grouper les
instructions avec ' {' et '}' comparaisons
(a==b) (a!=b) (a<b) (a>b) (a) ...
if( condition ) {instructions;
} else {autres_instructions;
}
Boucles utilisation de « for »
exemple
for( initialisation; condition; iteration ) {instructions;
}
int main( void ) {int i;for( i=0; i<3; i++ ) {
printf("i vaut %d\n", i);}
}
$ ./programme_boucle_fori vaut 0i vaut 1i vaut 2$
Boucles (2)
while( condition ) {instructions;
}
int main( void ) {int i = 3;while( i < 6 ) {
puts("proj\n");i++;
}}
utilisation de « while »
exemple
$ ./programme_boucle_whileprojprojproj$
Boucles (3)
do {instructions;
} while( condition ) ;
autre utilisation de « while »
différence : le bloc « instructions » est toujours exécuté au moins une fois
A l'utilisation d'une boucle, toujours penser aux conditions d'entrée et de sortie.
Boucles : pratique
Pour un nombre de fois determiné :for( i=0; i<nb; i++ ) { instructions; }
Tant qu'une condition est vraiewhile( condition ) { instructions; }
Au moins une fois, et tant qu'une condition est vraie do { instructions } while ( condition );
En utilisant while, il faut que condition ait une chance de changer !!
Tests et conditions
sur les nombres : == != < > <= >= implicitement : '!=0'
opérateurs logiques (!cond) (cond1)&&(cond2) (cond1)||(cond2) importance des parenthèses
if( i ) {puts("i non nul");
}
int i=12;if( ((i%2)&&(i<6))|| (i>10) ) { ... } /*vrai*/if( (i%2) && ((i<6))||(i>10)) ) { ... } /*faux*/
Trucs et astuces
dans le doute, mettre des parenthèses et des accollades
les opérateurs unitaires ++ et - - pratiques à utiliser de préférence seuls
i++if( i ) { ... }/* plus lisible que */
if( ++i ) { ... }
Les fonctions Don't repeat yourself : factoriser le code
gain de place et de lisibilité code maintenable travail distribuable dans une équipe
int main(void) {int i=0;
i++;
i++;
i++;
}
printf("i vaut %d, et i-1 vaut %d",i,i-1);
printf("i vaut %d, et i-1 vaut %d",i,i-1);
printf("i vaut %d, et i-1 vaut %d",i,i-1);
int main(void) {int i=0;
affiche( i );i++;
affiche( i );i++;
affiche( i );i++;
}
void affiche( int v ) {printf("v vaut %d et v-1 vaut %d\n",v,
v-1);}
Les fonctions
ont un type de retour, ou void ne s'utilisent qu'après
avoir été implémentées avoir été déclarées .... et notre premier programme ?
$ gcc -Wall -out hello hello.chello.c: In function `main´:hello.c: warning: implicit declaration of function `puts´hello.c: warning: control reaches end of non-void function
Retour à hello.c
directive #include valeur de retour
#include <stdio.h>
int main(void) {fputs(“hello world\n”);return 0;
}
Pointeurs
c'est une variable qui contient une adresse memoire
il est typé : « pointeur vers un int », « pointeur vers un unsigned short », ...
« double sens » de la déclaration
a est un « int * » *a est un « int »
int *a;
Pointeurs accès à l'adresse d'une variable : par
l'opérateur & accès à la variable depuis le pointeur : par
l'opérateur *#include <stdio.h>int main( void ) {
int i = 0;int *p;p = &i;printf( "i=%d p=%p\n",i,p);i=5;printf( "i=%d p=%p\n",i,p);*p = 12;printf( "i=%d p=%p\n",i,p);
}
Tableaux
tableaux et pointeurs sont très proches déclaration:
p pointe vers le premier entier du tableau (p+1) pointe vers le second entier du tableau accès direct : p[0], p[1], ... plus rapide que (*(p+1))...
affectation à la déclaration :
int p[12];
int p[3] = { 2, 12, 42 };
Tableaux#include <stdio.h>
int main() { int foo [ ] = { 2, 12, 42 } ; int *p = foo; /* p vaut foo, donc &(foo[0]) */
printf("%d %d %d\n", foo[0], foo[1], foo[2]); printf("%d %d %d\n", p[0], p[1], p[2]); printf("%d %d %d\n", *foo, *(foo+1), *(foo+2));}
$ ./programme_tableau2 12 422 12 422 12 42$
Chaines de caractères
En C, pas de type spécifique On utilise des tableaux de char Qui se termine par un caractère nul : '\0'
char string1[] = { 'c','o','m','p','l','i','q','u','é',0};char string2[] = "plus simple";/* et même, pour les char* uniquement */char * string3 = "à la déclaration";
dernier caractère p[5] = 0 p[5] = '\0'
« Hands on » !
Et n'oubliez pas ! Identez Faites des fonctions Privilégiez la lisibilité
Et en pratique Compilez avec « -Wall » Lisez les messages d'erreur !
Exercice 1
déclarer un tableau et le remplir d'entiers de 1 à 30 à l'aide d'une boucle
afficher son contenu afficher son contenu en ordre inverse
printf("la case %d vaut %d\n", indice, valeur );
Exercice 2
Lire une ligne tapée au clavier L'afficher Recommencer jusqu'à ce qu'on tape une ligne
vide (juste <entrée>)
fgets( ) ..... stdin
scanf(« %s » ......
Exercice 3
Même chose en affichant la ligne à l'envers.
Exercice 4
Lire plusieurs lignes au clavier jusqu'à l'entrée d'une ligne vide
Les afficher dans l'ordre inverse de saisie
Pour les rapides
Ecrire une fonction qui inverse deux variables