Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[debutant] Que doit-on attendre de ce code ?

30 réponses
Avatar
bpascal123
Bonjour,
En apparence, ce code ne produit pas de r=E9sultat ni de message
d'erreur :

#include <stdio.h>

void print_vertical(char *str) ;

int main(int argc, char *argv[])
{
if (argc > 1)
print_vertical(argv[1]) ;

return 0 ;
}

void print_vertical(char *str)
{
while (*str)
printf("%c\n", *str++) ;
}

Merci

10 réponses

1 2 3
Avatar
Hamiral
Lucas Levrel wrote:
Le 27 novembre 2009, Hamiral a écrit :

Donc les paramètres passés à ton programme sont stockà ©s dans argv[1],
argv[2]...argv[argc]



... argv[argc-1], non ?




Euh, oui.

Ham, ridiculisé ;)
Avatar
candide
Antoine Leca a écrit :

Pourquoi « embrouillons » ?



Parce qu'il embrouille le PO. Et bien que -ed- soit un autodidacte, il
manque franchement d'empathie.

Surtout que tu as coupé l'autre phrase



La suite tu veux dire ? oui, je ne l'ai pas cité car l'embrouille dont
je parle n'est pas là.

d'Emmanuel, qui expliquait ce qui est propre au langage C, c'est-à-dire




"expliquait" est un bien grand mot pour un commentaire aussi court,
vague et abstrait que celui qu'il donne et qui de toute façon n'arrive
pas à prendre en compte la problématique gloabale du PO. Problème
d'empathie récurrent chez -ed- ...

(le PO, c'est qui ? oui, c'est toi : bpascal123)


le concept de tableau argv[*] prédécoupé.




Il n'explique rien d'aussi précis, il fait un discours vague que le PO
est incapable d'assimiler. Et je n'ai rien coupé, j'ai juste dit que son
pseudo recadrage n'avait qu'un effet de surcharge (--> embrouille)






Qui plus est, Emmanuel n'est pas rentré dans les détails des différents
systèmes de passage de paramètres ;



Encore heureux, il aurait été encore plus embrouillant. Mais je sais
qu'il peut l'être.


car la ligne de commande n'est qu'un
système comme un autre, avec Unix tu peux utiliser execxx() à la place,
avec les environnements graphiques ce sera une icone etc.; on s'en
moque, c'est le boulot du compilateur de faire la transition pour
présenter des arguments découpés.





Faut même pas parler de tout ça à un débutant comme le PO.




Ce qui compte c'est de savoir qu'elle sont de classe
'static',


Les paramètres de la ligne de commande sont de classe static ?????



Tu n'as pas lu le texte que tu as coupé ?



Aucun rapport, -ed- répond à autre chose

Les paramètres de la ligne de commande sont un concept extérieur.




Oui et non. La Norme elle-même parle de la ligne de commande (même si
elle n'utilise par ce terme) donc ce n'est pas un concept totalement
"extérieur".



On parle donc uniquement des arguments passés par l'environnement
d'exécution C à la fonction main()).




Mais on s'en fout de ça. Essaye de regarder comment le PO voit les
choses. Pour lui, la ligne de commande c'est du C, réponds lui en C. Il
a pas besoin de savoir que la ligne de commande existe au niveau système
sinon il va penser qu'il faut connaitre tout le système, tous les
systèmes, avant d'apprendre le C.


Les arguments (les valeurs) passés au programme dans le tableau argv,
ainsi que leur nombre argc (les noms des paramètres sont des
conventions), sont effectivement des variables de durée de stockage
statique, c'est-à-dire ni automatique ni dynamique.



1°) Chapitres et versets ?
2°) Que ce soit vrai ou pas, c'était une réponse inadapté au niveau
avéré du PO.
Avatar
-ed-
On 27 nov, 21:41, candide wrote:
2°) Que ce soit vrai ou pas, c'était une réponse inadapté au nive au
avéré du PO.



Alors on attend toujours ta réponse adaptée... Car tu critiques
beaucoup mais tu ne proposes toujours rien ...
Avatar
candide
-ed- a écrit :
On 27 nov, 21:41, candide wrote:
2°) Que ce soit vrai ou pas, c'était une réponse inadapté au niveau
avéré du PO.



Alors on attend toujours ta réponse adaptée... Car tu critiques
beaucoup mais tu ne proposes toujours rien ...




Tel que nous connaissons bpascal123 depuis plusieurs mois, le silence
était une réponse plus adaptée que ton verbiage technique (et qui en
outre est probablement faux : j'attends tes citations de la Norme ou
celles d'Antoine) et de toutes façons complètement incompréhensible de
la part du PO.

bpascal123 a besoin d'un recadrage complet, un tel recadrage ne tient
pas dans une réponse technique hermétique (ou pas) et un forum tel que
celui-ci n'y est pas adapté.
Avatar
espie
In article ,
wrote:
Bonjour,
En apparence, ce code ne produit pas de résultat ni de message
d'erreur :



#include <stdio.h>



void print_vertical(char *str) ;



int main(int argc, char *argv[])
{
   if (argc > 1)
           print_vertical(argv[1]) ;



   return 0 ;
}



void print_vertical(char *str)
{
   while (*str)
           printf("%cn", *str++) ;
}




[...]
...
Quand je passe un paramètre, je modifie la valeur retournée par une
fonction. Maintenant, je ne sais pas ce que c'est que passer un
paramètre en ligne de commande. Je devrais avoir 10/20 si c'était un
exercice?



ce paragraphe n'a aucun sens. Tu as des petits soucis de vocabulaire.
On va preciser un peu.

Si tu es "dans" ton programme C, tu as des fonctions telles que:


void f(int a)
{
...
}

En C, les passages de parametres se font toujours par valeur. Avec les
type de base du langage (tel que int), tu ne peux rien "modifier" en
passant un parametre a une fonction.

Comme le C est un langage procedural classique, les fonctions ne sont pas
des fonctions au sens mathematique usuel: elles peuvent avoir des "effets
de bord". Typiquement:

void f(int a)
{
printf("%dn", a);
}


Lorsque tu appelles f, tu ecris un truc comme
f(5);

mathematiquement, il ne se passe rien (5 n'est pas modifie, heureusement, et
f ne renvoie rien), MAIS f est quand meme utile: elle affiche 5 sur la sortie.
C'est ca qu'on appelle un effet de bord.


Si tu veux une interaction directe entre tes fonctions et ton programme, il
te faut des fonctions qui renvoient un truc.

Par exemple:

int square(int n)
{
return n * n;
}

et dans ton programme principal:

b = square(15);

par exemple. Juste histoire de fixer les idees.



Maintenant, cette histoire de passer des parametres a ton programme.

La fonction main() a un statut particulier, puisque c'est la ou ton programme
demarre.

En C standard, la fonction main() admet deux declarations valides (ton
systeme peut admettre d'autres declarations, qui doivent etre documentees,
mais ce n'est plus du C standard);

int main()

ou

int main(int argc, char *argv[])


Tu as l'habitude du premier cas: tu communiques avec le systeme par le biais
des entrees-sorties, le systeme te permettant de recuperer des trucs au
clavier et d'afficher des trucs a l'ecran. Plus precisement, tu as deux fichiers
ouverts a disposition: stdin et stdout. stdin en lecture, et stdout en
ecriture. scanf() marche avec stdin, printf() avec stdout et par defaut,
ces deux "fichiers" sont connectes a ton clavier et ton ecran.
(j'emploie le terme fichier de maniere un peu flou... c'est pas necessairement
des vrais fichiers sur disque, mais juste des trucs sur lesquels tu peux
faire des entrees-sorties).

Il existe une autre facon d'interagir avec le systeme: les parametres passes
au lancement du programme. Je ne sais pas du tout ce que tu utilises comme
systeme/compilateur/ide, mais tu dois pouvoir dire au lancement du programme
"oh ben, je voudrais passer des parametres a mon programme" (peut-etre
les options d'une entree "executer" dans ton ide, peut-etre des proprietes
de la jolie icone qui te permet d'executer ton programme).
Traditionnellement, sous Unix, on tape plein de trucs. Typiquement, on
ouvre un terminal, et le systeme te donne un interpreteur de commande.
Pour executer un programme compile (appelle monprog), on tape alors:
monprog
si on veut rajouter des choses, on peut taper:
monprog p1 p2

C'est a ca que sert la 2e forme de main: argv[] est un tableau de chaines
de caracteres, et le systeme te les remplit, a raison d'un mot par case
(les mots etant betement separes par des espaces). argc te donne la taille
du tableau... A l'arrivee, on aura ici:
argv[0] = "monprog";
argv[1] = "p1";
argv[2] = "p2";
argc = 3;

Nota bene 1: le nom du programme se retrouve egalement dans argv... en fait,
on a tout ce qui a ete tape dans l'interpreteur de commande qui se retrouve
dans argv.

Nota bene 2: Unix et C sont tres tres lies. C est ne en meme temps qu'Unix,
a ete ecrit par les memes personnes. Il y a pas mal de choses dans le
langage qui font pleinement du sens sous Unix. Typiquement, argv est une
notion qui est fortement liee a la ligne de commande. En principe, ton
environnement de developpement DOIT te permettre de "faire la meme chose",
donc de "passer des parametres en ligne de commande" a ton programme, meme
si tout est une interface graphique.

Nota bene 3: dans pas mal d'environnements graphiques, tu auras d'autres
prototypes valides pour main(). Mais ca sort du cadre de ce newsgroup (qui
traite du C standard). Tu peux trouver ce genre d'info dans la doc de
ton environnement de developpement, ou en allant fouiller sur un newsgroup
plus approprie a ton systeme...
Avatar
Senhon
"candide" a écrit dans le message de groupe de
discussion : 4b10fe38$0$322$
-ed- a écrit :
On 27 nov, 21:41, candide wrote:
2°) Que ce soit vrai ou pas, c'était une réponse inadapté au niveau
avéré du PO.



Alors on attend toujours ta réponse adaptée... Car tu critiques
beaucoup mais tu ne proposes toujours rien ...





Il n'y pas pire sourd que celui qui ne veut pas entendre.




Tel que nous connaissons bpascal123 depuis plusieurs mois, le silence
était une réponse plus adaptée que ton verbiage technique (et qui en
outre est probablement faux : j'attends tes citations de la Norme ou
celles d'Antoine) et de toutes façons complètement incompréhensible de
la part du PO.

bpascal123 a besoin d'un recadrage complet, un tel recadrage ne tient
pas dans une réponse technique hermétique (ou pas) et un forum tel que
celui-ci n'y est pas adapté.




Bravo, heureusement qu'il existe des personnes capable de discernement.
Avatar
Antoine Leca
candide a écrit :
Antoine Leca a écrit :

Pourquoi « embrouillons » ?



Parce qu'il embrouille le PO.



Franchement, en l'occurrence c'est un peu aussi lui qui l'a cherché, en
changeant de thème en plein milieu d'un fil:
<news:
Re: Que doit-on attendre de ce code ?
: Je n'avais pas encore vu cette partie du langage c. Par curiosité, les
: variables de la ligne de commande sont stockées en mémoire?
: Directement dans un ou des registres?

Par contre, Emmanuel aurait dû changer le sujet du fil.


"expliquait" est un bien grand mot pour un commentaire aussi court,
vague et abstrait que celui qu'il donne et qui de toute façon n'arrive
pas à prendre en compte la problématique gloabale du PO. Problème
d'empathie récurrent chez -ed- ...



Je ne comprend pas pourquoi tu cherches absolument à faire taire
Emmanuel, même si tu lui diagnostiques un manque d'empathie.


Qui plus est, Emmanuel n'est pas rentré dans les détails des différents
systèmes de passage de paramètres ;




<mini-snip>
Faut même pas parler de tout ça à un débutant comme le PO.


<snip>
Mais on s'en fout de ça.



Cela signifie-t-il que ce sujet est tabou (dans ce groupe ou dans ce fil) ?


Antoine
Avatar
Antoine Leca
candide a écrit :
Antoine Leca a écrit :

Ce qui compte c'est de savoir qu'elle sont de classe
'static',


Les paramètres de la ligne de commande sont de classe static ?????


Les paramètres de la ligne de commande sont un concept extérieur.



Oui et non. La Norme elle-même parle de la ligne de commande (même si
elle n'utilise par ce terme) donc ce n'est pas un concept totalement
"extérieur".



La norme parle (5.1.2.2.1) de chaînes fournies à partir de
l'environnement par l'implémentation. Pas vu de concept de ligne (qui
impliquerait une certaine unité) à ce niveau.

À moins que j'ai loupé une partie de ton argument, dans ce cas je te
remercie de me donner quelques pistes.


On parle donc uniquement des arguments passés par l'environnement
d'exécution C à la fonction main()).



Mais on s'en fout de ça.



Mmmm... désolé, mais je ne suis pas totalement d'accord.
Tu écris que pour toi, les « paramètres de la ligne de commande » sont
tout sauf de « classe statique » ; je suis de l'avis d'Emmanuel sur ce
point (au vocabulaire près), donc je me permets d'expliquer pourquoi je
pense qu'il a raison d'écrire cela.


Essaye de regarder comment le PO voit les choses.



J'ai pris le soin de changer le titre du fil, justement parce que je
pense que le posteur initial ne va pas suivre (et n'a pas vraiment
besoin) cette discussion.


Les arguments (les valeurs) passés au programme dans le tableau argv,
ainsi que leur nombre argc (les noms des paramètres sont des
conventions), sont effectivement des variables de durée de stockage
statique, c'est-à-dire ni automatique ni dynamique.



1°) Chapitres et versets ?



Je suis extrêmement désolé pour m'être trompé d'un dans ma citation
<news:heok7j$fj7$, au dernier paragraphe.
La référence corecte est le chapitre 5, paragraphe 5.1.2.2.1, 2e alinéa.
— The parameters /argc/ and /argv/ and the strings pointed to
by the /argv/ array shall be modifiable by the program,
and retain their last-stored values between program
startup and program termination.

Pour les durées de stockage: 6.1.2.4/6.2.4 Storage durations of objects,
en particulier le 2e/3e alinéa.
Tu remarqueras que les _arguments_ passés au programme ne sont ni nommés
ni même (explicitement) déclarés, d'où le raisonnement de mon message
précvédetn, que je ne vais pas répéter ; il ne faut évidemment pas les
confondre avec les _paramètres_ (nommés conventionnellement argc et
argv) de la fonction main, qui peuvent être très différents, par exemple
en cas d'appel récursif à la fonction main.


Antoine
Avatar
candide
Antoine Leca a écrit :




La norme parle (5.1.2.2.1) de chaînes fournies à partir de
l'environnement par l'implémentation. Pas vu de concept de ligne




Oui, c'était une façon de parler, "ligne de commande" est le raccourci
habituel pour parler des arguments de main().

Mmmm... désolé, mais je ne suis pas totalement d'accord.
Tu écris que pour toi, les « paramètres de la ligne de commande » sont
tout sauf de « classe statique » ; je suis de l'avis d'Emmanuel sur ce
point (au vocabulaire près), donc je me permets d'expliquer pourquoi je
pense qu'il a raison d'écrire cela.





1°) Chapitres et versets ?



Je suis extrêmement désolé pour m'être trompé d'un dans ma citation
<news:heok7j$fj7$, au dernier paragraphe.
La référence corecte est le chapitre 5, paragraphe 5.1.2.2.1, 2e alinéa.
— The parameters /argc/ and /argv/ and the strings pointed to
by the /argv/ array shall be modifiable by the program,
and retain their last-stored values between program
startup and program termination.





T'en fais pas j'avais lu et relu tout le paragraphe concernant "la ligne
de commande"



Pour les durées de stockage: 6.1.2.4/6.2.4 Storage durations of objects,
en particulier le 2e/3e alinéa.




Oui, je l'ai lu et relu.



Tu remarqueras que les _arguments_ passés au programme ne sont ni nommés
ni même (explicitement) déclarés,



J'avais remarqué ce point en effet.


d'où le raisonnement de mon message
précvédetn, que je ne vais pas répéter ;




J'ai pas vu un message précédent où tu fais un raisonnement relatif à
"la ligne de commande" (si tu pouvais citer le lien http de
groups.google plutôt que le liens <new&###!15744154584uiydgbciu...>
auquel je comprends rien ;) )




il ne faut évidemment pas les
confondre avec les _paramètres_ (nommés conventionnellement argc et
argv) de la fonction main, qui peuvent être très différents, par exemple
en cas d'appel récursif à la fonction main.




Oui, j'ai bien saisi la nuance.

Maintenant discutons du sexe des anges. Sur le fond, Emmanuel et toi
avez probablement raison. D'une certaine façon, les arguments de la
ligne de commande sont de "classe" (ce n'est pas le terme de la Norme)
"static". Ils partagent avec ce type d'objet le fait que leur durée de
vie est celle du programme et qu'ils sont alloués avant le début de son
exécution. Néanmoins, la Norme ne le dit pas formellement. Cela tient à
mon avis au statut particulier de ces objets : ils ne sont pas alloués
par le programme mais par l'environnement. En fait il y a 4 objets :
-- argc (fourni par l'environnement)
-- la copie de argc passé en argument à main() (les arguments sont
passés par valeur),
-- argv
-- les chaînes pointées dans le "tableau" argv .

J'aurais tendance à dire que argc et argv sont de classe automatique et
seules les chaînes pointées sont de classe statique. Mais la Norme ne
dit rien. Pourtant, dans un autre cas similaire où le programme alloue
un objet sans le déclarer, celui des chaînes littérales, la Norme prend
bien soin de préciser que les chaînes sont de classe statique.

Par ailleurs, il y a une autre difficulté : la Norme ne donne pas
précisément la définition de la "classe" static, ni d'"automatic" ni
même d'"allocated" (rien de formel en tous cas). Elle dit d'abord qu'il
existe trois types de durée de mémorisation. Ensuite, elle dit que dans
telle ou telle circonstance tel objet est de classe statique, en général
à la déclaration de l'objet sauf, comme je l'ai dit ci-dessus, pour les
chaînes littérales. Voilà pourquoi j'ai trouvé abusif de qualifier les
arguments de la ligne de commande de classe statique bien
qu'effectivement ils en ont les caractéristques. Mais à la limite, je ne
vois pas où la Norme m'empêcherait de considérer que les arguments du
programme (les chaînes) sont de classe automatique !!
Avatar
espie
In article <4b13ef03$0$24788$,
candide wrote:
Maintenant discutons du sexe des anges. Sur le fond, Emmanuel et toi
avez probablement raison. D'une certaine façon, les arguments de la
ligne de commande sont de "classe" (ce n'est pas le terme de la Norme)
"static". Ils partagent avec ce type d'objet le fait que leur durée de
vie est celle du programme et qu'ils sont alloués avant le début de son
exécution. Néanmoins, la Norme ne le dit pas formellement. Cela tient à
mon avis au statut particulier de ces objets : ils ne sont pas alloués
par le programme mais par l'environnement. En fait il y a 4 objets :
-- argc (fourni par l'environnement)
-- la copie de argc passé en argument à main() (les arguments sont
passés par valeur),
-- argv
-- les chaînes pointées dans le "tableau" argv .



J'aurais tendance à dire que argc et argv sont de classe automatique et
seules les chaînes pointées sont de classe statique. Mais la Norme ne
dit rien. Pourtant, dans un autre cas similaire où le programme alloue
un objet sans le déclarer, celui des chaînes littérales, la Norme prend
bien soin de préciser que les chaînes sont de classe statique.



C'est pas exactement comme ca que ca fonctionne, c'est pour ca que ta norme
ne te dit rien. Sur les implementations usuelles, ton programme ne commence
pas dans main(), mais sur un autre symbole, souvent __start, qui va faire
des choses pour s'arranger pour t'appeler main (appelons-le __start pour
simplifier).

Sur certaines implementations, c'est __start qui te fabrique argc et argv
a la mano (j'en ai deja croise, ou le systeme te fournit une bete chaine de
caracteres, et ou c'est __start qui te la decoupe en petits mots).
Sur d'autres, ca peut etre l'appel systeme, par exemple execve,
qui lance le programme qui te fait le boulot. Appelons-le execve.

Donc a l'arrivee, argc et argv peuvent etre dans une zone memoire de meme
nature que tes chaines litterales (c'est une bonne idee si le systeme
le permet), ou peuvent etre de betes variables locales propres a __start, avec
de betes malloc/free (ou equivalents) pour l'allocation des chaines
correspondantes (voire du alloca si ton systeme en a un. Vu que c'est pas
cense etre du code portable, anything goes).

C'est un peu pour ca que c'est tres flou. :-)

Si j'ai bonne memoire, c'est d'ailleurs un petit point de difference entre
C et C++. Il me semble que la norme C++ donne un statut tres particulier
a main(), qui n'est vraiment pas une fonction comme les autres, et qu'en
particulier tu ne peux pas la rappeler de l'interieur de ton programme...
1 2 3