Il y a régulièrement un nouveau langage de programmation qui apparaît. Si on s'en tient aux langages "majeurs", en voici la liste certainement incomplète :

  • ShortCode en 1949.
  • AutoCode en 1952.
  • Fortran en 1957.
  • Algol en 1958.
  • Lisp en 1958.
  • Cobol en 1959.
  • Basic en 1964.
  • Pascal en 1970.
  • SmallTalk en 1972.
  • C en 1972.
  • SQL en 1972.
  • ADA en 1980.
  • C++ en 1983.
  • Objective-C en 1983.
  • Perl en 1987.
  • Haskell en 1990.
  • Python 1991.
  • Visual Basic 1991.
  • Ruby en 1993.
  • Java en 1995.
  • PHP en 1995.
  • Javascript en 1995.
  • C# en 2000.
  • Scala 2003.
  • Groovy en 2003.
  • Go 2009.
  • Swift en 2014.

Sans oublier dans le désordre: L'assembleur qui est dépendant du processeur utilisé, le bash, Lua, le Rust, Ocalm, les macrolangages des tableurs, Wolfram language (de Mathematica), le R (spécifique au maths et stats), le Forth (langage oublié), Prolog, Erlang, Vala/Genie (pour les Gobjects), Delphie, Boo, D, Eiffel, Node.js, Scratch (dédié aux enfants) et j'en passe beaucoup d'autres! (Le html et le css ne sont pas des langages de programmation, mais il n'empêche qu'il faut apprendre les balises, les mots clés, la structure du code.).

Grosso modo, on peut dire que chaque langage est apparu pour compenser les défauts du précédents.

Personnellement, j'en ai appris quelques un en autodidacte en commançant par le langage très rudimentaire de ma Ti-57, le basic du ZX80, le Pascal, le C, C++, le python, le JavaScript. En école d'ingénieur, c'était le Fortan et le Cobol, sans oublier le Basic.

Après un fort enthousiasme pour Java et Python, je suis retourné au C. Ce vieux langage de 1972 créé par Dennis Ritchie et Kenneth Thompson.

Le C a trois défauts : Il ne gère pas la mémoire, l'allocation de la mémoire et la désallocation sont laissés au bon soin de développeur. Il utilise des pointeurs pour accéder à la mémoire. Il est exclusivement procédurale.

Les pointeurs, l'allocation/désallocation de la mémoire sont une imporantes sources d'erreurs. Sa caractèristique purement procédurale ne facilite pas le réemploi de routines vers d'autres programmes et le découpage de gros programme. Le C++ a permis de résoudre une partie du problème sans pour autant simplifier le probème de la gestion de la mémoire. Le Java a résolu l'ensemble des probèmes mais...

Le Java est bien, il est orienté objet et il gère la mémoire mais il nécessite un runtime (JRE) et il ne permet pas une optimisation aussi poussée que le C/C++.

Je me suis orienté vers la programmation des microcontrôleurs. La mémoire disponible est toujours limitée de quelques Ko jusqu'à une centaine de Ko, la puissance de l'unité de calcul est ausi très limitée de 8bits @ 1Mhz jusqu'à 32bits @ 480MHz. Sachant que les microcontrôleurs les moins coûteux procurent 32Ko de Flash, 2Ko de RAM et une horloge à 20MHz, voilà pourquoi je suis revenu au C.

J'ai aussi des programmes plus conséquences qui tournent sous Linux, et qui sont écrits en C comme Ciwiki qui est un wiki perso et ArtZyn qui fournit un interface graphique entre le clavier d'Arturia MiniLab MKII et le softsynth ZynAddSubFx, plus des fonctionnalités de séquenceurs et boîte à rythme.

https://sourceforge.net/projects/ciwiki/

et https://sourceforge.net/projects/artzyn/  .

La programmation en C ne présente pas de gros inconvénients même en reprenant le codage d'un logiciel qui je n'avais plus fait évoluer après plus de 6 ans (Ciwiki 2.05 libéré en février 2016 et modifé en juillet 2022 pour donner Ciwiki 2.06). Le code était suffisamment documenté pour me permettre de me replonger dedans après plusieurs années. Et j'en arrive à la conclusion qu'il est important de bien documenter (et même à l'excés) le code source. Les routines qui peuvent sembler triviales au moment du codage ne le seront plus après plusieurs années. Il faut utiliser des noms de variables et de fonctions qui sont explicites, ne pas oublier d'indiquer le domaine de validé des variables.

Le débogage d'un programme en C :

1°) La solution classique est de monitorer le contenu des variables interessantes (contenu modifié par le programme).

J'utilise beaucoup : if( debug ) fprintf(stderr, "Line:%i, var=%s\n", __LINE__, variable_à_observer ); Si la variable est utiliser dans plusieurs fichiers c différents, j'ajoute __FILE__ : if( debug ) fprintf(stderr, "File:%s Line:%i, var=%s\n", __FILE__, __LINE__, variable_à_observer );

Ici debug est une variable globale qui vaut 0 et qui est passée à 1 en mettant un argument (comme -d) dans la ligne de commande. La fonction getopt() est fort pratique pour récuper les arguments passés en ligne de commande:

while( ( option = getopt_long ( argc, argv, "...." ) ) != -1 ) { switch( option ) { case 'd' : debug=1; break; ... } }

2°) gdb est le débugger classique en ligne de commande (pas toujours facile à utiliser),
ddd et Nemiver sontt des versions graphiques plus intruitives et plus faciles à utiliser.

3°) valgrind est super pour détecter les fuites mémoires (un free() oublié par exemple).

4°) CppCheck analyse le code source pour détecter certaines erreurs comme les variables qui n'ont pas été initialisé, le dépassement d'une table... CppCheck effectue une vérification statique du code source, il vient en complément aux options -Wall -Wextra de gcc.