Le langage C++ est-il plus adapté pour les débutants que le C ?
Analyse de ces langages par le Responsable C++ de Developpez

Les rubriques (actu, forums, tutos) de Développez
Réseaux sociaux


 Discussion forum

Le , par gbdivers, Inactif
Bonjour à tous

Un adage bien connu dit qu’enseigner, c’est répéter. Ceux qui fréquentent depuis quelque temps le forum C++ de Developpez le savent très bien : on revoit les mêmes discussions revenir régulièrement. Ce billet de blog va tenter d’analyser un peu les arguments concernant l’apprentissage du C++, en se focalisant plus particulièrement sur les difficultés d’utilisation. En particulier le raisonnement suivant, que l’on entend souvent : « il est préférable d’apprendre le C avec le C++ », ainsi que l’affirmation suivante, souvent pas comprise : « le C++ est un meilleur langage pour débuter que le C ».

Pourquoi le C++ est un langage plus adapté pour les débutants que le C ?

Au delà de l'aspect volontairement provocateur du titre, le but n'est pas la critique du C, mais bien la comparaison de quelques spécificités de ces langages et leurs conséquences en termes d'apprentissage. Et plus globalement, la question posée est comment doit être abordé l'enseignement du C++ moderne.

Comment pensez-vous que les différences d'approche entre le C et le C++ peuvent impacter leurs apprentissages respectifs ?
Quelles autres spécificités d'utilisation de ces langages peuvent poser des difficultés d'apprentissage ?


 Poster une réponse

Avatar de Luc Hermitte Luc Hermitte
Expert Confirmé Sénior
le 21/01/2013 18:28
Pour info, le realloc est mal utilisé et peu aussi masquer une fuite de mémoire.
Avatar de gbdivers gbdivers
Inactif
le 21/01/2013 18:48
Effectivement, même si l'utilisation de realloc n'est pas le propos, mettre du code pas très propre n'est pas pédagogique.

J'ai corrigé en :
Code :
1
2
char* str2 = realloc(str, strlen(str)*2);  
if (str) { str = str2; } else { printf("Error de réallocation"); }
C'est mieux ?

Sinon, j'utilise jamais realloc, il est sans problème possible que je l'utilise mal. Mais la question est aussi est ce que c'est pas comme ça que le débutant moyen va l'utiliser ? J'imagine qu'un développeur plus expérimenté ne fera pas l'erreur (et probablement pas les autres erreurs non plus).
Mais on constate quand même que les débutants refont souvent cette erreur (ce qui veut pas dire que les débutants C++ ne refont pas systématiquement les mêmes erreurs aussi )
Avatar de Luc Hermitte Luc Hermitte
Expert Confirmé Sénior
le 21/01/2013 19:24
Si tu corriges printf, il faut corriger realloc aussi.
Après, je préfères justement insister à montrer du code correct, cela aide à démontrer quel code est plus facile à enseigner et quel autre (OK, le même) est plus facile à maintenir.
Avatar de gbdivers gbdivers
Inactif
le 21/01/2013 19:44
Citation Envoyé par Luc Hermitte  Voir le message
Si tu corriges printf, il faut corriger realloc aussi.
Après, je préfères justement insister à montrer du code correct, cela aide à démontrer quel code est plus facile à enseigner et quel autre (OK, le même) est plus facile à maintenir.

je dois avouer que tu m'as perdu. Tu peux préciser comment tu aurais écrit le code avec realloc ?
Avatar de Iradrille Iradrille
Membre Expert
le 21/01/2013 19:51
Article sympa.

Je trouve par contre bizarre de comparer C et C++, une comparaison Java et/ou C# vs C++ m'aurait semblé plus approprié (histoire de comparer des langages objets).

Sinon j'ai dans l'ensemble un avis contraire, je pense que le C est plus simple à prendre en main, le concept objet est quand même un gros morceau à apprendre. (Même si les avantages de l'objet en valent le coup )

Le C est un langage plus bas niveau et je pense que c'est une bonne chose quand on apprend : beaucoup moins d'abstraction, on sait exactement ce que le code qu'on écrit va faire (on pourrait presque en avoir une représentation en asm dans la tête, ce qui est bien plus dur en C++).

Concernant le cast de const char* en char*, bah c'est un warning, débutant ou pas si on ignore un warning, il faut s'attendre à des répercutions (-Werror peut aider à pas les ignorer).
Et on pourrait citer un contre exemple:
Code :
1
2
3
4
5
int main() { 
	char c; 
	for(c=0; c<1000; ++c); 
	return 0; 
}
qui demande de compiler avec -Wextra pour afficher un warning, aussi bien en C qu'en C++.

Les pointeurs, ya toujours une erreur possible faut vraiment faire gaffe mais là pas vraiment de différence entre C et C++.

Pour les std::string (et plus généralement la STL), c'est une répercution d'avoir un langage objet, une couche d'abstraction qui nous permet de ne pas nous soucier de la gestion de la mémoire car gérée en interne.
Ça permet de coder plus rapidement et de manière plus sure, et c'est évidement un gros avantage pour le C++.

Pour les templates qui permettent de tester énormément de choses à la compilation c'est aussi un gros plus pour le C++, mais encore une fois, la prise en main n'est pas aisée.

Citation Envoyé par gbdivers  Voir le message
Quelles autres spécificités d'utilisation de ces langages peuvent poser des difficultés d'apprentissage ?[/B]

- le paradigme objet (ça peut sembler con, mais c'est une façon de penser complètement différente).
- déjà cité mais la gestion de la mémoire, qui est vraiment au cœur de ces 2 langages.

TL;DR: les avantages de l'objet sont indéniables mais c'est des principes pas forcément faciles à maîtriser, ce qui rend, selon moi, le C plus simple à appréhender.
Avatar de koala01 koala01
Modérateur
le 21/01/2013 21:45
Salut,
Citation Envoyé par Iradrille  Voir le message
Article sympa.

Je trouve par contre bizarre de comparer C et C++, une comparaison Java et/ou C# vs C++ m'aurait semblé plus approprié (histoire de comparer des langages objets).

l'idée n'était pas de comparer les différents langage OO, mais bien de donner une réponse à une question qui est régulièrement abordée: faut il absolument connaitre C si on veut apprendre C++
Sinon j'ai dans l'ensemble un avis contraire, je pense que le C est plus simple à prendre en main, le concept objet est quand même un gros morceau à apprendre. (Même si les avantages de l'objet en valent le coup )

Le fait de ne voir C++ que comme un langage OO est réducteur, et c'est sommes toutes l'erreur que font tous ceux qui croient qu'il faut impérativement passer par C avant de l'apprendre.

C'est oublier un peu vite que C++ est multi paradigme (l'un des rares langages à l'être à ma connaissance) et que, bien que cela le rende plus complexe, ca le rend aussi particulièrement adapté à l'apprentissage.

En effet, l'un des paradigmes qu'il propose est le paradigme impératif: tu peux donc parfaitement l'utiliser comme base pour l'apprentissage des principes de programmation impérative simple (concept de boucle, de test, de fonctions,...)

Si tu dis que tu reviendras "en temps utiles" sur les collections (qui sont un mélange du paradigme OO et du paradigme générique), le récipiendaire peut déjà aller finalement très loin dans l'étude de la programmation impérative sans avoir à aborder le point le plus problématique que l'on trouve en C (de par tout ce que cela peut représenter): les pointeurs.

On peut aller très loin à condition de dire "je vous parlerai de std::vector<UnType>.push_back(); en temps utiles", aussi bien en terme d'apprentissage des principes qu'en terme d'apprentissage du langage lui-même .

Une fois ces principes et la syntaxe correctement assimilés, on peut alors aborder le paradigme OO, et ce n'est qu'à ce moment là que le besoin des pointeurs commencera à se faire sentir.

Mais, à ce moment là, le récipiendaire saura déjà ce qu'est une fonction, aura déjà assimilé des principes comme le SRP, et autres: la transition sera donc bien plus aisée

Cette partie de l'apprentissage peut d'ailleurs se faire avec un introduction du genre "bon, on a vu comment nous pouvions réfléchir en termes de données, maintenant, on va réfléchir autrement: en terme de services rendus".

La courbe d'apprentissage reste donc beaucoup plus douce que ce qu'elle n'est en C

Et, une fois les principes OO assimilés, il n'y a plus que le paradigme générique à aborder, en changeant une fois de plus l'approche que l'on a, sous la forme de "maintenant, essayons de réfléchir non plus en terme de donnée, non plus en terme de services rendus, mais en termes de manière dont on pourrait manipuler les données et les objets, sans savoir forcément quel en est le type".

Tout cela concourt une fois de plus à une courbe d'apprentissage beaucoup plus douce que celle que l'on peut obtenir avec des langages mono-paradigmes, qu'il soient orientés fonctions (comme C) ou pire, orientés objets (comme java ou C#) car la notion de fonction fait malgré tout partie intégrante du paradigme objets

Ceci dit:

La syntaxe et la "grammaire" d'un langage s'apprend en quelques heures à peine : comment déclarer une fonction ou une variable, comment créer une boucle ou un test, ce n'a vraiment rien de bien compliqué.

De même, apprendre la signification des mots clés n'a pas grand chose de compliqué (il y en a quoi? nonante, en comptant ceux apportés par C++11, en C++ ?).

Toute la difficulté de l'apprentissage du développement logiciel vient exclusivement du fait qu'il faut apprendre à mettre un certain nombre de principe correctement en œuvre, qu'il est difficile d'accepter pour quiconque le fait qu'un principe se doit d'être appliqué "au pied de la lettre" et sans tenter d'aucune manière de les adapter en fonction de nos besoins.

Une fois que le déclic se fait dans la tete du récipiendaire que le principe de Liskov est la clé de voute de tout ce qui touche à l'héritage, une fois que sont compris l'ensemble des principes énoncés par S.O.L.I.D., une fois (surtout) qu'il est clair qu'il ne faut en aucun cas envisager de déroger à ces principes, ne serait-ce qu'en essayant d'y apporter la moindre interprétation plus permissive que ce qui est écrit, il n'y a plus aucun langage OO qui puisse poser problème à l'apprentissage.

Et c'est à ce moment là que l'on se rend compte que les langages comme java ou C# ont tendance à favoriser la médiocrité
Avatar de germinolegrand germinolegrand
Expert Confirmé Sénior
le 21/01/2013 21:55
Je trouve par contre bizarre de comparer C et C++, une comparaison Java et/ou C# vs C++ m'aurait semblé plus approprié (histoire de comparer des langages objets).

Oui, sauf que...
Contrairement au Java/C#, C++ est un langage multiparadigme. Il n'y a pas plus de raisons de le comparer à un langage objet qu'à un langage impératif.

Le C est un langage plus bas niveau et je pense que c'est une bonne chose quand on apprend : beaucoup moins d'abstraction, on sait exactement ce que le code qu'on écrit va faire (on pourrait presque en avoir une représentation en asm dans la tête, ce qui est bien plus dur en C++).

Comme on peut réécrire strictement la même chose au final en restant dans du C++, cet avantage n'en est pas un. C'est même le contraire : en C on est obligé rester ultra-bas niveau, même quand on ne voudrait pas.

Les pointeurs, ya toujours une erreur possible faut vraiment faire gaffe mais là pas vraiment de différence entre C et C++.

Un std::unique_ptr, et le tour est joué, on touche plus au pointeur. Excepté à l'allocation, on peut se balader avec des références : pas de confusion.

-------------------

Pour ma part je considère le C comme obsolète. Non seulement parce qu'il n'est rien en C qui ne soit pas faisable aussi efficacement en C++, mais aussi parce que c'est un langage limité face au C++(11 encore plus) qui l'englobe tout en proposant plus de liberté, plus de flexibilité, et plus de paradigmes. En bref c'est comme si on avait le choix entre le tire-bouchon et le couteau-suisse complet.

-------------------
Edit :
Une fois que le déclic se fait dans la tete du récipiendaire que le principe de Liskov est la clé de voute de tout ce qui touche à l'héritage, une fois que sont compris l'ensemble des principes énoncés par S.O.L.I.D., une fois (surtout) qu'il est clair qu'il ne faut en aucun cas envisager de déroger à ces principes, ne serait-ce qu'en essayant d'y apporter la moindre interprétation plus permissive que ce qui est écrit, il n'y a plus aucun langage OO qui puisse poser problème à l'apprentissage.

C'est pas le sujet ici, mais j'ai juste envie de dire : "Non." à ce paragraphe .
Sinon je suis d'accord avec tout le reste de ce que tu as dit ^^
Avatar de JolyLoic JolyLoic
Rédacteur/Modérateur
le 21/01/2013 23:11
Citation Envoyé par germinolegrand  Voir le message

Pour ma part je considère le C comme obsolète. Non seulement parce qu'il n'est rien en C qui ne soit pas faisable aussi efficacement en C++, mais aussi parce que c'est un langage limité face au C++(11 encore plus) qui l'englobe tout en proposant plus de liberté, plus de flexibilité, et plus de paradigmes. En bref c'est comme si on avait le choix entre le tire-bouchon et le couteau-suisse complet.

Je ne le dirais pas obsolète, car pour moi il a deux avantages où il bat le C++ sans hésiter :
- Il est tellement simple qu'il est possible de trouver un compilateur C partout, et que ce compilateur ne sera pas trop buggé, voire même sera certifié conforme (important dans certaines parties de code embarqué touchant à la sécurité).
- Il reste un très bon dénominateur commun pour interfacer entre eux des langages divers et variés, alors qu'on ne sait même pas toujours interfacer entre eux deux bouts de programmes C++, même écrits avec le même compilateur (mais des options différentes).

A part ces deux usages, en effet, il faudrait vraiment trouver de très bons arguments pour me faire faire du C.
Avatar de Luc Hermitte Luc Hermitte
Expert Confirmé Sénior
le 22/01/2013 0:44
Citation Envoyé par gbdivers  Voir le message
je dois avouer que tu m'as perdu. Tu peux préciser comment tu aurais écrit le code avec realloc ?

Ben... fais remonter l'erreur au cran de la fonction au dessus. Et pense à prévoir comment nettoyer, tout ça quoi.
Tu vois l'enfer ? C'est la plus belle démonstration que le simplisme du C n'en fait pas un langage dans lequel il est simple de développer. C'est pour ça aussi que je ressors régulièrement les exemples de l'article de Lahman qui a été traduit il y a peu.

Citation Envoyé par Iradrille  Voir le message
a- Je trouve par contre bizarre de comparer C et C++, une comparaison Java et/ou C# vs C++ m'aurait semblé plus approprié (histoire de comparer des langages objets).

b- Sinon j'ai dans l'ensemble un avis contraire, je pense que le C est plus simple à prendre en main, le concept objet est quand même un gros morceau à apprendre. (Même si les avantages de l'objet en valent le coup )

c- Le C est un langage plus bas niveau et je pense que c'est une bonne chose quand on apprend : beaucoup moins d'abstraction, on sait exactement ce que le code qu'on écrit va faire (on pourrait presque en avoir une représentation en asm dans la tête, ce qui est bien plus dur en C++).

d- Les pointeurs, y a toujours une erreur possible faut vraiment faire gaffe mais là pas vraiment de différence entre C et C++.

e- Pour les std::string (et plus généralement la STL), c'est une répercution d'avoir un langage objet, une couche d'abstraction qui nous permet de ne pas nous soucier de la gestion de la mémoire car gérée en interne.
Ça permet de coder plus rapidement et de manière plus sure, et c'est évidement un gros avantage pour le C++.

e-
- le paradigme objet (ça peut sembler con, mais c'est une façon de penser complètement différente).
- déjà cité mais la gestion de la mémoire, qui est vraiment au cœur de ces 2 langages.

TL;DR: les avantages de l'objet sont indéniables mais c'est des principes pas forcément faciles à maîtriser, ce qui rend, selon moi, le C plus simple à appréhender.

a- C'est une comparaison qui ne vient pas de nous, mais de débutants qui la posent et demandent leur chemin de temps à autre, et bien plus souvent qu'on ne peut le croire.

b- Ecris des codes robustes aux erreurs et on en reparlera. Et maintenant enseigne des codes corrects et robustes aux débutants en C, et vois à faire la même chose, tout en restant en impératif en C++.
Quel est le langage qui permet d'enseigner correctement (pour montrer des choses justes et robustes et simples) ?

c- Je ne suis pas d'accord. Ada est un excellent langage d'apprentissage, de même que Pascal. Et pourtant ils fournissent des abstractions, non OO, pour les premiers pas -- OK, Pascal moins.
La SL fais parti du langage, ce n'est pas une annexe.

d- Dans une séquence d'apprentissage newbs-friendly, tu n'as pas besoin de perdre les étudiants dès le second chapitre avec les pointeurs en C++. On peut attendre le chapitre sur le polymorphisme pour le faire -- ou du moins le dernier moment avant les classes.
Je renvoie comme d'hab' à /je me lance/ de Francis Glassborrow qui est un bouquin d'initiation pour profil de non-informaticien/geek/technophile avec C++ comme langage support. Le livre n'aborde que la partie impérative du C++ et sa lib standard. Pas un mot (en fait si, une (seule) note de bas page) sur les pointeurs. Pas de classes à écrire, pas des templates à écrire.
Bref, pointeurs ? -> string, vector, RAII, shared_ptr<>, ... Une utilisation idiomatique du C++ utilise les pointeurs d'une façon radicalement différente de celle du C. Et on n'a pas le choix, les idiomes du C ne sont pas applicables à cause des exceptions. Heureusement pour nous le résultat fait que c'est plus facile de coder en C++.

e- Ce n'est pas le sujet. Ce n'est pas la question de "commencer OO ou impératif ?", mais de "C ou C++ pour commencer en impératif ?"
Avatar de Iradrille Iradrille
Membre Expert
le 22/01/2013 1:47
Citation Envoyé par Luc Hermitte  Voir le message
d- Dans une séquence d'apprentissage newbs-friendly, tu n'as pas besoin de perdre les étudiants dès le second chapitre avec les pointeurs en C++. On peut attendre le chapitre sur le polymorphisme pour le faire -- ou du moins le dernier moment avant les classes.
Je renvoie comme d'hab' à /je me lance/ de Francis Glassborrow qui est un bouquin d'initiation pour profil de non-informaticien/geek/technophile avec C++ comme langage support. Le livre n'aborde que la partie impérative du C++ et sa lib standard. Pas un mot (en fait si, une (seule) note de bas page) sur les pointeurs. Pas de classes à écrire, pas des templates à écrire.
Bref, pointeurs ? -> string, vector, RAII, shared_ptr<>, ... Une utilisation idiomatique du C++ utilise les pointeurs d'une façon radicalement différente de celle du C. Et on n'a pas le choix, les idiomes du C ne sont pas applicables à cause des exceptions. Heureusement pour nous le résultat fait que c'est plus facile de coder en C++.

e- Ce n'est pas le sujet. Ce n'est pas la question de "commencer OO ou impératif ?", mais de "C ou C++ pour commencer en impératif ?"

@koala01, germinolegrand, Luc Hermitte
Ok, avec ça de précisé je comprend mieux vos réponses, je pensais jusque là qu'on comparait du C++ orienté objet avec du C.
(éventuellement à préciser dans l'article ?)

Du coup c'est sur que comparer du C++ impératif (du C + la STL en gros) à du C, oui le C++ est plus simple.
Offres d'emploi IT
Développeur Python H/F
CDD CDI
UPFLUENCE - Rhône Alpes - Lyon
Parue le 31/03/2014
H/F Ingénieur Développement PHP
CDI
ONE CUBE - Provence Alpes Côte d'Azur - Aix-en-Provence (13100)
Parue le 16/04/2014
Développeur Android junior (…mais plus pour longtemps) pour un leader du E-commerce
CDI
Mobiskill - Ile de France - Paris (75003)
Parue le 10/04/2014

Voir plus d'offres Voir la carte des offres IT
 
 
 
 
Partenaires

PlanetHoster
Ikoula