Accès rapide :
Les nouveaux types de données en C99
Introduction d'un pseudo type booléen <stdbool.h>
Le commentaire // sur une seule ligne
Déclaration de la variable de boucle dans le for
Plus d'obligation de déclarer les variables en tête de bloc
Définition de fonctions inline
Ajout du mot clé restrict
Nous allons, dans ce chapitre, lister l'ensemble des extensions du langage C apparues avec la version C99 du standard. Il est donc important de comprendre que pour compiler les exemples proposés
dans ce document, il faudra activer ce support au niveau du compilateur. Si vous utilisez gcc (idem pour MinGW), il faudra donc ajouter l'option de compilation -std=c99
.
Comme vous allez pouvoir vous en rendre compte, un grand nombre des nouveautés de ce standard sont en réalité des éléments rétro-intégré de C++ . Pour rappel, C++ est un langage de programmation dérivé de C et ajoutant un très grand nombre de nouveaux concepts et notamment la programmation orientée objet (POO). Pour autant, toutes les extensions de C++ n'étaient pas liées à la POO : c'est une bonne partie de ces points non liés à la POO qui sont ici considérés.
La norme C99 rajoute quelques nouveaux type de données dans le langage.
long double
long long
(ou long long int
)unsigned long long
(ou unsigned long long int
)
Le langage C ne définit pas, à proprement parlé, de type booléen. Néanmoins, le standard C99 introduit l'entête <stdbool.h>
.
Cette entête défini trois macro, bool
, true
et false
afin d'améliorer la lisibilité de vos programmes.
#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main( int argc, char * argv[] ) { bool mustExit = false; while( mustExit ) { printf( "a new loop." ); mustExit = true; } return EXIT_SUCCESS; }
Une nouvelle forme de commentaire intègre le standard : le commentaire //
déjà présent en C++. En fait, cet ajout, n'en est pas vraiment un. Effectivement, même si le précédent
standard (c90) ne définissait pas cette forme de commentaire, de très nombreux compilateurs avaient déjà, par anticipation, supporté cette syntaxe. D'ailleurs, dans GCC, l'option de compilation
-std=c99
n'est même pas requise pour que ce commentaire soit supporté.
#include <stdio.h> #include <stdlib.h> int main() { /* Classical comment syntax. Can span on multiple lines */ printf( "some lines of code\n" ); // new C99 comment, on a single line printf( "some lines of code\n" ); return EXIT_SUCCESS; }
Il vous est possible de déclarer la variable permettant de faire tourner une boucle for
directement dans la définition de cette boucle.
A l'origine, cette extension a été introduite par le langage C++ durant les années 80. Suite au succès de cette extension, il a été décidé de la retro-intégrer au
langage C. Voici un petit exemple.
#include <stdio.h> #include <stdlib.h> int main() { int array[] = { 10, 20, 30, 40, 50 }; for( unsigned int index=0; index<5; index++ ) { printf( "array[%u] == %d\n", index, array[index] ); } return EXIT_SUCCESS; }
Voici ce que produit cet exemple.
$> gcc -o Sample -Wall -std=c99 Sample.c $> ./Sample array[0] == 10 array[1] == 20 array[2] == 30 array[3] == 40 array[4] == 50 $>
En fait, l'exemple précédent, permettant de déclarer la variable d'un boucle for
dans sa définition, est un cas particulier de ce que je présente ici. Plus généralement, on ne doit plus
systématiquement déclarer une variable en tête de bloc, mais au contraire au plus proche de son utilisation. L'avantage ce principe de développement réside dans le fait que vous aurez moins à
naviguer dans vos codes pour les comprendre. Effectivement déclarer la variable de boucle une vingtaine de ligne au-dessus, n'aide pas forcément à une compréhension rapide du code.
Qui plus est le principe de localité nous amène à dire que plus d'optimisations pourront être produite par votre compilateur.
Encore une fois, cette possibilité est issue du langage C++. Qui plus est gcc à intégré cette possibilité sans nécessiter l'option -std=c99. Mais c'est, malgré tout, bien la norme C99 qui ajoute cette possibilité.
#include <stdio.h> #include <stdlib.h> int main() { int a = 33; printf( "a == %d\n", a ); int b = 44; printf( "b == %d\n", b ); return EXIT_SUCCESS; }
En C89 pur et dur, nous aurions du écrire :
#include <stdio.h> #include <stdlib.h> int main() { int a = 33; int b = 44; printf( "a == %d\n", a ); printf( "b == %d\n", b ); return EXIT_SUCCESS; }
Le mot clé inline
, repris du langage C++, permet de demander une optimisation du compilateur en injectant le code d'une fonction en lieu
et place de son appel. Consultez le chapitre dédié à ce mot clé pour de plus amples informations.
A l'instar du mot clé inline
, le mot clé restrict
permet d'obtenir des optimisations de la part du compilateur.
Ce mot clé s'utilise sur une déclaration de paramètre de type pointeur, pour indiquer qu'il est le seul moyen de manipuler la zone pointée
dans la fonction considérée. Du point de vue de l'utilisateur de la fonction, ce mot clé n'a aucune signification particulière (il ne s'adresse
qu'au compilateur).
A titre d'exemple, voici comment est déclarée (depuis C99) la fonction memcpy
.
1 2 |
#include <string.h> void * memcpy( void * restrict destination, const void * restrict source, size_t size ); |
Consultez le chapitre dédié à ce mot clé pour de plus amples informations.
Améliorations / Corrections
Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.
Emplacement :
Description des améliorations :