Le langage C pour la programmation système

Language C, Dennis Ritchie
Le premier manuel à contribué à la popularité de C

C a connu le succès grâce à la liberté nouvelle qu'il offrait aux programmeurs. Son inconvénient est la difficulté à déboguer les programmes. Il produit des programmes rapides et une large collection d'APIs est disponible. Il reste le meilleur outil pour la programmation proche du hardware et s'utilise même pour des applications. Voir Why SQLite is coded in C, par exemple. Autres logiciels codés en C: Linux, les jeux Doom, Quake et SimCity, Apache, NGINX, PHP, JVM, Git...

Le langage C été conçu de 1969 à 1972 par Dennis Ritchie pour programmer le système d'exploitation Unix. Il avait pour objectif d'être portable. Voir Le développement du langage C pour un historique.
Le tutoriel du langage par Dennis Ritchie et Brian Kernighan est considéré comme un des meilleurs jamais écrit.

C parait plutôt rustique par rapport aux langages modernes, mais dans les années 70, comme alternative à Basic, il était extrêmement évolué. Appeler une fonction par son numéro de ligne, ou avoir des noms de variable limités à deux caractères dans le basic AppleSoft de Microsoft, rendait la programmation très laborieuse. Même Pascal avec sa lourdeur et ses contraintes semblait moins intéressant que C.

C est peut être toujours une meilleure solution que C++ pour la programmation système, c'est en tout cas l'opinion de Linux Torvald qui a choisi d'utiliser ce langage pour le logiciel Git, très largement répandu.
Mais ce jugement (en 2007) peut dater car depuis C++ a connu plusieurs évolutions et améliorations, notamment avec la version 11. Il demeure néanmoins que pour des applications système critiques, C++ reste trop complexe et indéterminé.
Pour pallier à l'insécurité du langage C, Microsoft a créé Checked C, une extension qui teste les problèmes de mémoire dans un programme.

Ce qu'on doit savoir sur l'histoire de C

Dennis Ritchie et son collègue Ken Thompson ont mis on point le language sur un terminal de type Teletype 33, tel que représenté sur la photo ci-dessous.

Terminal teletype 33

Dennis Ritchie (debout) et Ken Thomson au Bell Labs sur le terminal Teletype 33

Pour imaginer à quoi ressemblait la programmation dans ces conditions, on regardera cette vidéo du terminal en action... On comprend mieux alors la syntaxe du langage, faite pour économiser la frappe, et où le signe = est choisi pour l'assignement et == pour la comparaison, parce que l'assignement est plus fréquent que la comparaison! Voici le clavier vu de plus près...

Clavier de Teletype 33

 

Ritchie a du faire preuve d'ingéniosité dans la définition du langage pour réduire le nombre de frappes, avec par exemple l'opérateur d'incrément ++. D'autres constructions sont beaucoup plus douteuses comme l'assignement imbriqué dans un test de comparaison.
En outre l'influence du clavier concerne autant le code source du compilateur que celui des programmes qu'il reconnait. Par contre un langage moderne peut être simplifié au prix d'un compilateur plus complexe. Les claviers ont bien changé, pourtant les constructions alambiquées de C demeurent dans de nombreux autres langages dont C++, Java, C# de Microsoft et de très récents tels Go et Dart de Google et Swift.

Un langage ou tout est une expression

Un programme C est composé d'un ensemble de fonctions qui retournent ou non une valeur, et de variables globales. Toute chose peut être évaluée comme une expression, et ce n'est pas forcément un avantage pour la sécurité.
Fonctions et variables ont un prototype dans un fichier en-tête pour une utilisation partagée du fichier source.
Le programmeur doit gérer lui-même la mémoire, utilisant des pointeurs et des fonctions pour allouer ou libérer des blocs de mémoire.
Il est portable avec quelque restrictions: par exemple, les types de variables additionnels dépendent du compilateur.

Le standard ISO C11 de 2011 ajoute de nouvelles fonctions au langage C: le multi-thread, Unicode, les fonctions lambda, structures et unions imbriquées anonymes.

Les structures de données:

Scalaires: int, long, char, char *.
struct permet de créer un type d'objet formé de plusieurs variables et était le précurseur des objets.
union permet de donner plusieurs identifieur à une variable et s'utilise surtout avec les structs.
typedef pour définir de nouveaux types de données.

Les structures de contrôle:

Les symboles:

// and /* */ commentaires.
& | && || opérateurs logiques.
# directive pour le pré-processeur.

Les symboles composés effectuent deux opérations sur une même variable. Par exemple, a += b ajoute b à a puis assigne le résultat à a.

La boucle while:

while(x < y)
{
   ... instructions ...
}

La définition d'une fonction:

int nom(char *x, int y)
{
   ... instructions ...

   return(z);
}

Exemple de code

Afficher les caractères d'une chaîne en C.

char *s = "demo";
int l = strlen(s);
for(int i = 0; i < l; i++)
{
   char c = s[i];
   printf("%c\n", c);
} 

Voir aussi

Sites et outils pour C