OVH Cloud OVH Cloud

Amélioration de la syntaxe d'une boucle

8 réponses
Avatar
PurL
Bonjour,

Soit l'algorithme suivant :
Paramètres d'entrée :
-> strTexte : const char * : chaine de recherche
-> cCar : char : caractere à rechercher
Sortie : comptage du nombre d'occurences de cCar dans strTexte.

J'utilise une fonction Position() existante qui renvoie l'indice de la
premiere occurence d'un caractere dans une suite de caractère, 0 si le
celui-ci n'est pas présent.
Prototype : int Position(const char *string, char car);

code de l'algorithme :

CODE 1
---------
int Cpt = 0;
int iPos = Position(strTexte, cCar);
while (iPos)
{
Cpt++;
iPos = Position(strTexte + iPos, cCar);
}

(Il faut bien comprendre que l'algo du début, le fonction Position et le
code ne sont que des exemples pour illustrer mon post.)
Face à ce code, j'optimise comme ceci :

CODE 2
---------
int Cpt = 0;
int iPos = 0;
while (iPos = Position(strTexte + iPos, cCar))
{
Cpt++;
}

Le probleme (qui n'en est pas vraiment un) est que mon compilateur, à la
compilation, m'affiche "Affectation incorrecte possible" à la ligne du
while, ce qui est correct quand on pense à la confusion entre "=" et "= =".
J'utilise cette écriture (CODE2) de tres nombreuse fois dans mon programme
et je la préfère à celle de CODE1 car elle évite d'écrire 2 fois la
condition du while (1 avant de rentrer dans le while, l'autre dans le while)
ce qui est source d'erreur. Par contre je me retrouve noyé par les
avertissements. Je ne voudrais pas désactiver cet avertissement car je ne
suis pas non plus à l'abri de la confusion entre "=" et "= =".

Ma question est donc comment peut-on coder l'algo en écrivant qu'UNE SEULE
FOIS la condition du while SANS générer d'avertissement ?

Merci pour votre aide,

PurL

8 réponses

Avatar
Pierre Maurette
Bonjour,

Soit l'algorithme suivant :
Paramètres d'entrée :
-> strTexte : const char * : chaine de recherche
-> cCar : char : caractere à rechercher
Sortie : comptage du nombre d'occurences de cCar dans strTexte.

J'utilise une fonction Position() existante qui renvoie l'indice de la
premiere occurence d'un caractere dans une suite de caractère, 0 si le
celui-ci n'est pas présent.
Prototype : int Position(const char *string, char car);

code de l'algorithme :

CODE 1
---------
int Cpt = 0;
int iPos = Position(strTexte, cCar);
while (iPos)
{
Cpt++;
iPos = Position(strTexte + iPos, cCar);
}

(Il faut bien comprendre que l'algo du début, le fonction Position et le
code ne sont que des exemples pour illustrer mon post.)
Face à ce code, j'optimise comme ceci :

CODE 2
---------
int Cpt = 0;
int iPos = 0;
while (iPos = Position(strTexte + iPos, cCar))
{
Cpt++;
}

Le probleme (qui n'en est pas vraiment un) est que mon compilateur, à la
compilation, m'affiche "Affectation incorrecte possible" à la ligne du
while, ce qui est correct quand on pense à la confusion entre "=" et "= =".
J'utilise cette écriture (CODE2) de tres nombreuse fois dans mon programme
et je la préfère à celle de CODE1 car elle évite d'écrire 2 fois la
condition du while (1 avant de rentrer dans le while, l'autre dans le while)
ce qui est source d'erreur. Par contre je me retrouve noyé par les
avertissements. Je ne voudrais pas désactiver cet avertissement car je ne
suis pas non plus à l'abri de la confusion entre "=" et "= =".

Ma question est donc comment peut-on coder l'algo en écrivant qu'UNE SEULE
FOIS la condition du while SANS générer d'avertissement ?


while ((iPos = Position(strTexte + iPos, cCar)) != 0)

(d'ailleurs, je préfère également, dans CODE 1 :
while (iPos != 0)
iPos ne me semblant pas être un booléen)
--
Pierre

Avatar
Jean-Marc Bourguet
"PurL" writes:

Bonjour,

Soit l'algorithme suivant :
Paramètres d'entrée :
-> strTexte : const char * : chaine de recherche
-> cCar : char : caractere à rechercher
Sortie : comptage du nombre d'occurences de cCar dans strTexte.


std::count

Note que l'interface de Position me semble mal concue: elle ne prevoit
pas que le texte puisse commencer par le caractere cherche.

Sinon pour le probleme de la boucle et demie, cherche les archives.
Ca a ete le sujet de discussions dans ce groupe.

Ma question est donc comment peut-on coder l'algo en écrivant qu'UNE
SEULE FOIS la condition du while SANS générer d'avertissement ?


Certains compilateurs (je ne sais pas si c'est le cas de tous),
n'avertisse pas si l'assignation est seule dans des parentheses (et
pas au niveau le plus haut). Donc

while ( (v = exp) != 0 )


A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
PurL
while ((iPos = Position(strTexte + iPos, cCar)) != 0)


Merci, ca marche, j'aurais du y penser !


(d'ailleurs, je préfère également, dans CODE 1 :
while (iPos != 0)
iPos ne me semblant pas être un booléen)


Une expression (pas forcement une variable) booleenne est FAUSSE si egale à
0 et VRAI si différente de 0.

PurL

Avatar
PurL
std::count


???


Note que l'interface de Position me semble mal concue: elle ne prevoit
pas que le texte puisse commencer par le caractere cherche.


Juste par curiosité (car, mon exemple n'est pas mon probleme mais un exemple
pour expliquer mon post), comment peux-tu voir cela ?
rien n'indique que le premier caractere de la chaine de recherche porte le
numéro 0 !


Sinon pour le probleme de la boucle et demie, cherche les archives.
Ca a ete le sujet de discussions dans ce groupe.



Toutes mes excuses...

Ma question est donc comment peut-on coder l'algo en écrivant qu'UNE
SEULE FOIS la condition du while SANS générer d'avertissement ?


Certains compilateurs (je ne sais pas si c'est le cas de tous),
n'avertisse pas si l'assignation est seule dans des parentheses (et
pas au niveau le plus haut). Donc

while ( (v = exp) != 0 )


c'est effectivement la solution, merci.

PurL


Avatar
Jean-Marc Bourguet
"PurL" writes:

std::count


???


Dans l'entete algorithm, il y a une fonction template std::count qui
fait exactement ca.

std::count(strTexte, strTexte+strlen(strTexte), cCar)

te donne ce que tu cherche.

Note que l'interface de Position me semble mal concue: elle ne
prevoit pas que le texte puisse commencer par le caractere
cherche.


Juste par curiosité (car, mon exemple n'est pas mon probleme mais un
exemple pour expliquer mon post),


OK.

comment peux-tu voir cela ? rien
n'indique que le premier caractere de la chaine de recherche porte
le numéro 0 !


Exact et en plus ca ne fonctionnerait pas. Mais definir une fonction
Position qui ne renvoie pas un index correct (cad autre chose que ce
que string::find aurait renvoye en cas de succes) ne me semble pas une
bonne idee. La preuve je ne l'avais meme pas imagine. Au fait, il y
a strchr qui fait aussi a peut pres ce que ton Position fait.

Sinon pour le probleme de la boucle et demie, cherche les archives.
Ca a ete le sujet de discussions dans ce groupe.


Toutes mes excuses...


Il n'y a pas a t'excuser (ce serait assez difficile de retrouver les
fils sans connaitre le terme). Mais j'ai pas envie de redonner tous
les arguments. Et il est mieux de les voir presenter par ceux qui y
croient...

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org


Avatar
Jean-Marc Bourguet
"PurL" writes:

while ((iPos = Position(strTexte + iPos, cCar)) != 0)


Merci, ca marche, j'aurais du y penser !


(d'ailleurs, je préfère également, dans CODE 1 :
while (iPos != 0)
iPos ne me semblant pas être un booléen)


Une expression (pas forcement une variable) booleenne est FAUSSE si egale à
0 et VRAI si différente de 0.


On le sait. Mais pas mal de gens et de conventions preferent comparer
explicitement tout ce qui n'est pas booleen.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org


Avatar
Pierre Maurette
while ((iPos = Position(strTexte + iPos, cCar)) != 0)



Merci, ca marche, j'aurais du y penser !


(d'ailleurs, je préfère également, dans CODE 1 :
while (iPos != 0)
iPos ne me semblant pas être un booléen)



Une expression (pas forcement une variable) booleenne est FAUSSE si egale à
0 et VRAI si différente de 0.
Merci. Ça me fait un paquet de lignes de code à modifier ;-)

--
Pierre


Avatar
kanze
PurL wrote:
while ((iPos = Position(strTexte + iPos, cCar)) != 0)


Merci, ca marche, j'aurais du y penser !


Ça marche, mais on arrive vite fait à du code complétement
illisible.

(d'ailleurs, je préfère également, dans CODE 1 :
while (iPos != 0)
iPos ne me semblant pas être un booléen)


Une expression (pas forcement une variable) booleenne est
FAUSSE si egale à 0 et VRAI si différente de 0.


Une expression booléene est « false » ou « true », non 0 ou 1.
Une expression arithmétique non-booléene peut se convertir en
booléene ; dans ce cas-là, une valeur 0 se convertit en
« false », et une valeur non 0 en « true ».

Là aussi, c'est un bon truc pour obfusquer le code, mais sans
beaucoup d'intérêt autrement.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34