Loading lang_c_02_basics...
int // cette fonction doit renvoyer un entier main(void) // elle s'appelle main et n'attend aucun paramètre {
// cette paire d'accolades matérialise le corps de la fonction, // c'est ici que figureront les variables et les instructions
return 0; // voici l'entier que cette fonction doit renvoyer }
{ }(accolades) qui suit matérialise le corps de la fonction, c'est-à-dire l'algorithme que doit exécuter cette fonction lorsqu'elle est appelée ; il ne s'agit dans cet exemple simpliste que de fournir une valeur entière (0) que cette fonction doit renvoyer. Nous n'avons pas le choix quant au fait que la fonction main() n'attend pas de paramètre (à une variante près qui sera vue dans cette section).
int // cette fonction doit renvoyer un entier axpy(int a, // elle s'appelle axpy int x, // et attend int y) // trois paramètres entiers { return a*x+y; // elle combine ses paramètres pour produire son résultat }
int main(void) // la fonction axpy() est invoquée { // avec les trois entiers attendus, return 10*axpy(2, 5, 7); // son résultat est exploité pour produire } // le résultat du programme
int // cette fonction doit renvoyer un entier axpy(int a, // elle s'appelle axpy int x, // et attend int y); // trois paramètres entiers
int main(void) // la fonction axpy() est invoquée { // avec les trois entiers attendus, return 10*axpy(2, 5, 7); // son résultat est exploité pour produire } // le résultat du programme
int // la définition axpy(int a, // de la fonction axpy() int x, // a bien le même prototype int y) // que sa déclaration préalable { return a*x+y; // elle combine ses paramètres pour produire son résultat }
#include <stdio.h>
int main(void) { printf("hello, world\n"); return 0; }
#include <ctype.h>— character types
#include <float.h>— floating types
#include <limits.h>— implementation-defined constants
#include <math.h>— mathematical declarations
#include <stdbool.h>— boolean type and values
#include <stddef.h>— standard type definitions
#include <stdint.h>— integer types
#include <stdio.h>— standard buffered input/output
#include <stdlib.h>— standard library definitions
#include <string.h>— string operations
<stdio.h>.
<stdio.h>expose, entre autres choses, la déclaration de la fonction printf() qui est ici invoquée dans la fonction main().
int axpy(int a, int x, int y) { int myVar; // déclaration d'une variable nommée myVar pouvant contenir une valeur entière myVar=a*x; // le produit de deux entiers peut être stocké dans une variable de type entier myVar=myVar+y; // consultation et modification de cette variable return myVar; // la valeur de cette variable est du même type que le résultat }
... { int v1; // une seule variable de type entier de valeur indéterminée int v2, v3; // deux variables de type entier de valeurs indéterminées int v4=8; // une seule variable de type entier valant initialement 8 int v5=10, v6, v7=v4+20, v8=2*v7, v9; // cinq variables de type entier, trois sont initialisées, ... // deux autres ont une valeur indéterminée }
... { int v1=1234, v2=-5678; // entiers relatifs, constantes décimales int v3=0xBadC0de, v4=-0644; // entiers relatifs, constante hexadécimale puis octale unsigned int v5=16384; // entier naturel, constante décimale unsigned int v6=0xDeadBeef; // entier naturel, constante hexadécimale ... }
... { int v1=0xBadC0de, v2=-5678; printf("v1 is %d and 10*v2 is %d\n", v1, 10*v2); // v1 is 195936478 and 10*v2 is -56780 ... }
... { double v1=0.0, v2=12.34, v3=-56.78; // utilisation du séparateur décimal double v4=-1e-6, v5=6.02e23; // élévation à une puissance de dix ... }
... { double v1=0.5e-4, v2=9.81; printf("v1 is %g and v1*v2 is %g\n", v1, v1*v2); // v1 is 5e-05 and v1*v2 is 0.0004905 ... }
... { char v1='E', v2='N', v3='I', v4='B'; // saisie des caractères littéraux char v5=69, v6=78, v7=73, v8=66; // saisie des codes ASCII (entiers) ... }
... { char v1='E', v2='N', v3=73, v4=66; printf("as text: %c %c %c %c\n", v1, v2, v3, v4); // as text: E N I B printf("as int: %d %d %d %d\n", v1, v2, v3, v4); // as int: 69 78 73 66 printf("as text: %c %c %c %c\n", v1-4, v2-12, v3-6, v4+2); // as text: A B C D ... }
<stdbool.h>.
#include <stdbool.h> // en dehors de toute fonction ... { bool v1=true, v2=false; // deux variables booléennes et les deux valeurs possibles printf("v1 is %d and v2 is %d\n", v1, v2); // v1 is 1 and v2 is 0 ... }
typedef unsigned char Byte; // Byte est le nom d'un nouveau type identique à unsigned char typedef double Mass; // Mass est le nom d'un nouveau type identique à double ... { Byte v1=7, v2=130; // ces deux variables ne sont rien d'autre que des unsigned char Mass v3=26.4; // celle ci n'est rien d'autre qu'un double ... }
... { double v1=12.34; int v2=v1, v3=(int)v1; // avertissement pour v2, pas pour v3 unsigned int v4=v2, v5=(unsigned int)(v2+v3); // avertissement pour v4, pas pour v5 double v6=v5; // aucun avertissement printf("v1=%g v6=%g \n", v1, v6); // v1=12.34 v6=24 printf("v2=%d v3=%d v4=%d v5=%d \n", v2, v3, v4, v5); // v2=12 v3=12 v4=12 v5=24 ... }
int my_var=12;
extern int my_var;
#include <stdio.h>
void testStatic(int i) { static int s=100; // variable initialisée au démarrage du programme s=s+i; // variable modifiée à chaque nouvelle invocation printf("s=%d\n", s); }
int main(void) { testStatic(1); // s=101 testStatic(10); // s=111 return 0; }
#include <stdio.h> // inclusion d'un fichier standard, pré-installé dans le système #include "myheader.h" // inclusion d'un fichier propre à notre projet
#define COUNT 1000 // le mot COUNT sera substitué par la constante 1000 #define WEIRD_SUM a + b // le mot WEIRD_SUM sera substitué par l'expression a + b ... { int a=COUNT, b=2*COUNT; printf("WEIRD_SUM is %d\n", WEIRD_SUM); // WEIRD_SUM is 3000 ... }
#define BAD_SUM(x, y) x+y // aucune protection --> interaction possible #define BETTER_SUM(x, y) ((x)+(y)) // protection de toute l'expression et de ses paramètres #define BAD_PRODUCT(x, y) x*y // aucune protection --> interaction possible #define BETTER_PRODUCT(x, y) ((x)*(y)) // protection de toute l'expression et de ses paramètres ... { int v1=10, v2=100; printf("2*BAD_SUM(%d, %d) is %d\n", // 2*BAD_SUM(10, 100) is 120 v1, v2, 2*BAD_SUM(v1, v2)); // calcule 2*v1+v2 --> incorrect printf("2*BETTER_SUM(%d, %d) is %d\n", // 2*BETTER_SUM(10, 100) is 220 v1, v2, 2*BETTER_SUM(v1, v2)); // calcule 2*((v1)+(v2)) --> correct printf("BAD_PRODUCT(%d, %d) is %d\n", // BAD_PRODUCT(12, 100) is 210 v1+2, v2, BAD_PRODUCT(v1+2, v2)); // calcule v1+2*v2 --> incorrect printf("BETTER_PRODUCT(%d, %d) is %d\n", // BETTER_PRODUCT(12, 100) is 1200 v1+2, v2, BETTER_PRODUCT(v1+2, v2)); // calcule ((v1+2)*(v2)) --> correct ... }
#if defined _WIN32 // la macro _WIN32 n'existe que si nous compilons pour Windows ... ces lignes contiennent du code spécifique à Windows ... elles ne seront compilées que pour cette plateforme #else ... celles-ci contiennent du code pour les autres systèmes #endif
// ce commentaire doit nécessairement tenir sur une seule ligne
/* cette autre forme de commentaire fonctionne aussi sur une seule ligne */ /* mais elle a l'intérêt de s'étendre facilement sur plusieurs lignes. Attention toutefois : en saisissant à nouveau le symbole /* nous pouvons penser à une imbrication de commentaires mais il n'en est rien. Ce long commentaire se termine bien ici. */ ... { #if 0 // cette directive émule un commentaire sur plusieurs lignes printf("I don't want this code to be compiled!\n"); # if 0 // et elle offre l'avantage de permettre l'imbrication. printf("Not even this one...\n"); # endif #else printf("But this code will be considered.\n"); #endif ... }
... { typedef double value; // le nom value désigne ici un type value x=2.3; // x est une variable de type value (c'est-à-dire double) int value=8; // erreur de compilation ! (le nom value existe déjà) int printf=12; // la variable locale printf masque la fonction de même nom printf("really?\n"); // erreur de compilation ! (printf n'est pas une fonction dans ce contexte) ... }
{ }(accolades), peuvent apparaître partout où une instruction est attendue ; il est donc possible de les imbriquer, ce qui sera particulièrement utile pour les instructions de contrôle (voir plus loin)✍
... { int v1=6, v2=8; printf("v1 is %d and v2 is %d\n", v1, v2); // v1 is 6 and v2 is 8 { // ouverture d'un nouveau bloc (inutile ici, juste pour l'exemple) int v1=12; // cette nouvelle variable v1 masque celle du bloc englobant printf("v1 is %d and v2 is %d\n", v1, v2); // v1 is 12 and v2 is 8 v1=v1+2; // modification de la variable locale à ce bloc v2=v2-5; // modification de la variable locale au bloc englobant } printf("v1 is %d and v2 is %d\n", v1, v2); // v1 is 6 and v2 is 3 ... }
printf("as an instruction\n"); // le résultat de l'appel à printf() est ignoré int v1=10+printf("as an expression\n"); // ici il participe à une expression arithmétique int v2=100; v1=v1*2+8; // cette instruction affecte le résultat d'une expression à une variable v2=v2*3+(v1=v1*2+8); // une affectation est aussi une expression qui vaut la valeur affectée printf("5=%d v1=%d v1+v2/2=%d\n", 5, v1, v1+v2/2);
... { int v1=10, v2=20; v1+=2; // équivalent à v1=v1+2; v2*=v1+8; // équivalent à v2=v2*(v1+8); printf("v1=%d v2=%d\n", v1, v2); // v1=12 v2=400 ... }
... { int value, v1=10, v2=20, v3=30, v4=40; value=++v1; // pré-incrémentation, équivalent à v1+=1; puis value=v1; printf("v1=%d value=%d\n", v1, value); // v1=11 value=11 value=--v2; // pré-décrémentation, équivalent à v2-=1; puis value=v2; printf("v2=%d value=%d\n", v2, value); // v2=19 value=19 value=v3++; // post-incrémentation, équivalent à value=v3; puis v3+=1; printf("v3=%d value=%d\n", v3, value); // v3=31 value=30 value=v4--; // post-décrémentation, équivalent à value=v4; puis v4-=1; printf("v4=%d value=%d\n", v4, value); // v4=39 value=40 ... }
... { int v1=10, v2=20, v3=30, v4=40; bool b1=v1>v2; printf("b1=%d\n", b1); // b1=0 bool b2=(v1+v2==v3)&&(v3<=v4); printf("b2=%d\n", b2); // b2=1 bool b3=!b2||(!b1&&(v4-v3!=v2)); printf("b3=%d\n", b3); // b3=1 ... }
bool callMe(void) { printf("Hi there!\n"); return true; }
... dans une autre fonction ... { int v1=10, v2=20; bool b1=(v1>v2)&&callMe(); bool b2=(v1>v2)||callMe(); // Hi there! bool b3=(v1<v2)&&callMe(); // Hi there! bool b4=(v1<v2)||callMe(); printf("b1=%d b2=%d b3=%d b4=%d\n", // b1=0 b2=1 b3=1 b4=1 b1, b2, b3, b4); ... }
... { int v1=10, v2=20; bool b1=v1&&!v2; // faux puisque v1!=0 est vrai et v2==0 est faux bool b2=v1<v2; // vrai int v3=b1+80*b2+500*(2*v1==v2); // b1 vaut 0, b2 vaut 1, 2*v1==v2 est vrai et vaut 1 printf("b1=%d b2=%d v3=%d\n", b1, b2, v3); // b1=0 b2=1 v3=580 ... }
... { if(v1<v2) { printf("v1 is less than v2\n"); } ... } // if(v1<v2) printf("v1 is less than v2\n");
... { if(v1<v2) printf("v1 is less than v2\n"); ... }
... { if(v1<v2) { printf("v1 is less than v2\n"); } else { printf("v1 is greater than or equals to v2\n"); } ... }
... { if(v1<v2) { printf("v1 is less than v2\n"); } else if(v1>v2) { printf("v1 is greater than v2\n"); } else { printf("v1 equals to v2\n"); } ... }
... { if(v1<v2) { printf("v1 is less than v2\n"); } else { if(v1>v2) { printf("v1 is greater than v2\n"); } else { printf("v1 equals to v2\n"); } } ... }
... { int v1=10, v2=20; int v3=v1<v2 ? v1*500 : v2+500; printf("v3=%d\n", v3); // v3=5000 int v4=2*(v1>v2 ? v1 : v2)+5; printf("v4=%d\n", v4); // v4=45 ... }
... { int v1=10, v2=20; int v3; if(v1<v2) { v3=v1*500; } else { v3=v2+500; } printf("v3=%d\n", v3); // v3=5000 int tmp; if(v1>v2) { tmp=v1; } else { tmp=v2; } int v4=2*tmp+5; printf("v4=%d\n", v4); // v4=45 ... }
... { int value=obtainAnyData(); switch(value*2+3) { case 3: { printf("this case was expected\n"); break; } case 5: { printf("so was this one\n"); break; } case 7: { printf("and this one too\n"); break; } default: { printf("unexpected case!\n"); break; } } ...
... { int v1=10, v2=20; while(v1>0) { --v1; v2+=5; } printf("v1=%d v2=%d", v1, v2); // v1=0 v2=70 ... }
... { int v1=10, v2=20; do { --v1; v2+=5; } while(v1>0); printf("v1=%d v2=%d", v1, v2); // v1=0 v2=70 ... }
int doSomething(int n) { printf("doing something with %d\n", n); return 100-12*n; }
... dans une autre fonction ... { int i=0, result; do { result=doSomething(i); ++i; } while(result>0); ... }
int doSomething(int n) { printf("doing something with %d\n", n); return 100-12*n; }
... dans une autre fonction ... { int i=0, result=doSomething(i); // code duplication! while(result>0) { ++i; result=doSomething(i); } ... }
... { for( instruction_initiale ; condition ; instruction_itérative ) { /* corps de la boucle */ } ... }
... { instruction_initiale; while( condition ) { /* corps de la boucle */
instruction_itérative; } ... }
... { for(int i=0; i<10; ++i) { printf("%d ", i); // 0 1 2 3 4 5 6 7 8 9 } printf("\n"); ... }
... { int i; for(i=0; i<4; ++i) { printf("< "); // < < < < } printf("\n"); for( ; i<8; i+=2) { printf(">> "); // >> >> } printf("\n"); printf("i=%d\n", i); // i=8 ... }
... { for(double d=0.5; d>1e-3; d*=d) { printf("%g ", d); // 0.5 0.25 0.0625 0.00390625 } printf("\n"); ... }
... { for( ; ; ) { printf("stuck here, forever!\n"); // L'éternité, c'est long... surtout vers la fin. } ... }
... { for(int i=0; i<chooseIterationCount(); ++i) { doSomething(i); } ... }
... { for(int i=0, count=chooseIterationCount(); i<count; ++i) { doSomething(i); } ... }
double compute(int i, double x) { printf("i is %d and x is %g\n", i, x); // i is 8 and x is 12.5 return x-i; // terminer la fonction ici en renvoyant un résultat de type double printf("not displayed\n"); }
void testCompute(void) { printf("compute(8, 12.5) gave %g\n", compute(8, 12.5)); // compute(8, 12.5) gave 4.5 return; // terminer la fonction ici sans renvoyer de résultat (type de retour void) printf("not displayed\n"); }
int obtainAnyData(void) { return 17; }
... dans une autre fonction ... { int value=obtainAnyData(), found=0; for(int i=0; i<100; ++i) // pour au pire cent valeurs successives { if(i%value==0) // à chaque fois qu'elle est multiple de value { printf("%d\n", i); // nous l'affichons if(++found==5) { break; // nous quittons la boucle après cinq multiples } } } printf("found %d multiples of %d\n", found, value); ... }
... { for( ... ; ... ; ... ) { // ... obtenir des informations ...
// ... préparer la condition 1 ... if( ... condition 1 ...) { // ... traiter la condition 1 ... continue; // pas la peine d'aller plus loin dans le corps de la boucle }
// ... préparer la condition 2 ... if( ... condition 2 ...) { // ... traiter la condition 2 ... continue; // pas la peine d'aller plus loin dans le corps de la boucle }
// ... ainsi de suite ... } ... }
... { for( ... ; ... ; ... ) // boucle 1 { ... for( ... ; ... ; ... ) // boucle 2 { ... if(somethingWentWrong()) { goto emergencyExit; // sortie directe } ... } ... } emergencyExit: // étiquette pour la sortie printf("done\n"); ... }
... { for( ... ; ... ; ... ) // boucle 1 { ... bool breakout=false; for( ... ; ... ; ... ) // boucle 2 { ... if(somethingWentWrong()) { breakout=true; break; // sortie boucle 2 } ... } if(breakout) { break; // sortie boucle 1 } ... } printf("done\n"); ... }