OVH Cloud OVH Cloud

probleme tableaux

26 réponses
Avatar
giovanni
j ai ces ligne la
int * num=new * int[100,100,100,100,100];
int* nb=new int[999,999,999,999,999];
int* ok=new int[999,999,999,999,999];
t valeur variable de 1 a 999
nb[t][0][0][0][0]=nb_1;
le probleme et que dans nb[t][0][0][0][0] il y a pas la valeur nb_1 ?
pourquoi?j ai mis 999 ne sachant pas taille des donnee j ai mis le max...

10 réponses

1 2 3
Avatar
Vincent Lascaux
Quelle utilisation "pratique" peut-on avoir de l'operateur , ???


Ca peut être utilisé dans les boucles for, par exemple pour incrémenter
plusieurs variables

for(int i = 0, j = 0; i<100; i++, j+=2)
std::cout << "Le double de " << i << " est " << j << std::endl;

Il doit bien avoir un ou deux cas où il est utile de surcharger un tel
opérateur pour faire un sucre syntaxique approprié, mais ca doit être assez
rare à mon avis...

--
Vincent

Avatar
Pierre Maurette
Jean-Marc Bourguet wrote in
news::


int* nb=new int[999,999,999,999,999];


Alloue un tableau de 999 entiers: , est l'operateur , qui evalue les
expressions en sequence donc les 4 premiers 999 sont en pratique ignores.
C'est la meme chose que

int* nb = new int[999];



Quelle utilisation "pratique" peut-on avoir de l'operateur , ???
La lisibilité des C++-ismes (ou C-ismes) comme i++, i >>= 2, opérateur

virgule et quelques autres est souvent affaire personnelle. Ça tombe
bien, ils sont en général d'utilisation facultative.
Comme Vincent, je trouve l'opérateur virgule pratique dans les boucles
for(;;), si on est raisonnable. C'est à dire si on ne joue pas à mettre
tout ce qu'on peut dans la définition de la boucle.
Je crois que l'opérateur virgule a la particularité de garantir un ordre
d'exécution des "instructions", ce qui n'est pas le cas si elles sont
séparées par des ;. Je n'ai jamais utilisé cette particularité.
--
Pierre



Avatar
Falk Tannhäuser
Pierre Maurette wrote:
Quelle utilisation "pratique" peut-on avoir de l'operateur , ???
La lisibilité des C++-ismes (ou C-ismes) comme i++, i >>= 2, opér ateur

virgule et quelques autres est souvent affaire personnelle. Ça tombe
bien, ils sont en général d'utilisation facultative.
Comme Vincent, je trouve l'opérateur virgule pratique dans les boucle s
for(;;), si on est raisonnable. C'est à dire si on ne joue pas à me ttre
tout ce qu'on peut dans la définition de la boucle.


Un autre exemple relativement réaliste :

int a, b;
while(a = readA(), b = readB(), a > X || b < Y)
supercalifraguiextraallegoriquefrobenicate(a, b);

On note que la tentative suivante de se passer de l'opérateur virgule :

int a, b;
while((a = readA()) > X || (b = readB()) < Y)
supercalifraguiextraallegoriquefrobenicate(a, b);

ne marche pas. Au fait il faudrait dupliquer du code (ce qui est Mal !) :

int a = readA();
int b = readB();
while(a > X || b < Y)
{
supercalifraguiextraallegoriquefrobenicate(a, b);
a = readA();
b = readB();
}

en priant pour que personne ne rajoutera derrière un "continue" quelque
part dans la boucle sans s'apercevoir qu'il faut réinitialiser "a" et " b".


Je crois que l'opérateur virgule a la particularité de garantir un ordre
d'exécution des "instructions", ce qui n'est pas le cas si elles sont
séparées par des ;. Je n'ai jamais utilisé cette particularité.


Voir ci-dessus. Cet ordre n'est cependant plus garanti lorsqu'on surcharg e
l'opérateur ",", par exemple :

template<typename Container> class container_init_helper
{
Container& c;
public:
container_init_helper(Container& c) : c(c) {}

container_init_helper& operator=(typename Container::value_type co nst& v)
{ c.clear(); c.push_back(v); return *this; }

container_init_helper& operator,(typename Container::value_type cons t& v)
{ c.push_back(v); return *this; }
}; // class container_init_helper

template<typename Container> inline
container_init_helper<Container> container_init(Container& c)
{ return container_init_helper<Container>(c); }

Cela pourrait servir à initialiser des containers, par exemple :

std::list<double> lst;
container_init(lst) = 6.55957, 1.95583, 3.14159265358979323846264338 3279502884197169399375105820974944;
container_init(lst), 2.7182818284590452353602874713527, 40.3399, 166.3 86, 13.7603, 299792458.0;

Par contre, il ne faut pas faire :

int i = 42;
std::vector<int> vec;
container_init(vec) = 1664, i++, 4711, i;

sous peine d'avoir un comportement non défini.
Pour cette raison (comportement inconsistant entre l'opérateur prédé fini et
l'opérateur défini par l'utilisateur), les puristes banniront la surc harge
de l'opérateur ",", mais aussi et surtout de "&&" et "||".
Par ailleurs, les puristes détestent souvent aussi "continue".

Falk


Avatar
James Kanze
Michael wrote:
Jean-Marc Bourguet wrote in
news::


int* nb=new int[999,999,999,999,999];




Alloue un tableau de 999 entiers: , est l'operateur , qui
evalue les expressions en sequence donc les 4 premiers 999
sont en pratique ignores. C'est la meme chose que



int* nb = new int[999];



Quelle utilisation "pratique" peut-on avoir de l'operateur , ???


L'obfuscation.

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



Avatar
Michel Michaud
Dans le message d2ujg8$vob$,
Un autre exemple relativement réaliste :

int a, b;
while(a = readA(), b = readB(), a > X || b < Y)
supercalifraguiextraallegoriquefrobenicate(a, b);

On note que la tentative suivante de se passer de l'opérateur
virgule :
int a, b;
while((a = readA()) > X || (b = readB()) < Y)
supercalifraguiextraallegoriquefrobenicate(a, b);

ne marche pas. Au fait il faudrait dupliquer du code (ce qui est
Mal !) :
int a = readA();
int b = readB();
while(a > X || b < Y)
{
supercalifraguiextraallegoriquefrobenicate(a, b);
a = readA();
b = readB();
}

en priant pour que personne ne rajoutera derrière un "continue"
quelque part dans la boucle sans s'apercevoir qu'il faut
réinitialiser "a" et "b".


Merci de donner encore des munitions à ceux qui croient qu'il
faut accepter naturellement la boucle et demie :

for(;;)
{
int a = readA(); // Déclarer a et b à l'extérieur si
int b = readB(); // nécessaire seulement
/***/
if (a <= X && b >= Y) break;
/***/
supercalifraguiextraallegoriquefrobenicate(a, b);
}

L'autre alternative étant évidemment de modulariser un peu plus
avec une fonction intermédiaire :

bool AB(int& a, int& b)
{
a= readA();
b= readB();
return a > X || b < Y;
}

int a, b;
while (AB(a, b))
supercalifraguiextraallegoriquefrobenicate(a, b);

Mais l'emploi de la virgule (comme le premier code) est ici, à mon
humble avis, la pire des solutions possibles...

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/

Avatar
Pierre Maurette
[...]
Un autre exemple relativement réaliste :

int a, b;
while(a = readA(), b = readB(), a > X || b < Y)
supercalifraguiextraallegoriquefrobenicate(a, b);

On note que la tentative suivante de se passer de l'opérateur virgule :

int a, b;
while((a = readA()) > X || (b = readB()) < Y)
supercalifraguiextraallegoriquefrobenicate(a, b);

ne marche pas. Au fait il faudrait dupliquer du code (ce qui est Mal !) :

int a = readA();
int b = readB();
while(a > X || b < Y)
{
supercalifraguiextraallegoriquefrobenicate(a, b);
a = readA();
b = readB();
}

en priant pour que personne ne rajoutera derrière un "continue" quelque
part dans la boucle sans s'apercevoir qu'il faut réinitialiser "a" et "b".
Bel exemple, bon exercice...


Sinon, sans dupliquer de code, avec ou sans break:

int a, b;
bool fini = false;
// rien
while(!fini)
//while(true)
{
a = readA();
b = readB();
if(a > X || b < Y)
supercalifraguiextraallegoriquefrobenicate(a, b);
else
fini = true;
// break;
}

ou:

int a, b;
bool pasfini = true;
do
{
a = readA();
b = readB();
if(pasfini = (a > X || b < Y))
supercalifraguiextraallegoriquefrobenicate(a, b);
}while(pasfini);

Bon, je préfère l'opérateur virgule quand même.

[je zappe la partie C++ qui me dépasse un peu ;-)]

Par ailleurs, les puristes détestent souvent aussi "continue".
Un bon goto, hein, y'a pas mieux ...

--
Pierre

Avatar
Pierre Maurette
[...]
Mais l'emploi de la virgule (comme le premier code) est ici, à mon
humble avis, la pire des solutions possibles...
Ça vous dirait que nous passions des vacances ensemble ?

;-)
--
Pierre

Avatar
Gabriel Dos Reis
James Kanze writes:

| Michael wrote:
| > Jean-Marc Bourguet wrote in
| > news::
|
| >>>int* nb=new int[999,999,999,999,999];
|
| >>Alloue un tableau de 999 entiers: , est l'operateur , qui
| >>evalue les expressions en sequence donc les 4 premiers 999
| >>sont en pratique ignores. C'est la meme chose que
|
| >>int* nb = new int[999];
|
| > Quelle utilisation "pratique" peut-on avoir de l'operateur , ???
|
| L'obfuscation.

Ou non.

-- Gaby
Avatar
Falk Tannhäuser
Gabriel Dos Reis wrote:
James Kanze writes:
| Michael wrote:
| > Quelle utilisation "pratique" peut-on avoir de l'operateur , ???
| L'obfuscation.
Ou non.


-v

Falk

Avatar
kanze
Michel Michaud wrote:
Dans le message 42544300$0$12183$,
Michel Michaud wrote:



[...]
Mais en fin de compte, je crois que tout dépend du poids
qu'on donne aux différents critères, parce que le problème,
c'est qu'on ne peut pas les remplir tous.


Seulement parce que tu as un critère qui dit « pas de boucle
et et demie ». Alors évidemment, il n'y a pas de solution
puisque la logique c'est celle d'un boucle et demie (comme l'a
expliqué Knuth bien avant moi).


Je reconnais simplement qu'il n'y a pas de solution totalement
satisfaisante. C'est tout.

[...]
-- Ce qui contrôle la boucle doit se trouver à des endroits
« standard ». C-à-d ou bien au début ou bien à la fin.


Ça me paraît tout à fait arbitraire. Le résultat d'une
mauvaise habitude :-) Tu ne dis pas pourquoi ni ce que ça
t'apporte, sauf de l'obfuscation...


Ça apporte qu'on peut trouver facilement les contrôles de la
boucle. Qu'on peut raisonner aussi en termes d'invariante de
boucle, parce que dans tout le corps de la boucle, les contrôles
ne varient pas. Le problème avec la boucle et démi, c'est que
dans la partie au dessus du test de sortie, on n'a aucune
garantie sur les invariantes.

Note qu'un tel raisonnement argue aussi souvent contre le
do..while. Le test de la condition (qui exprime en quelque sort
les invariantes) doit se faire avant chaque passage dans la
boucle, y compris le premier. Aussi, il ne faut pas modifier les
variables de contrôle dans le corps de la boucle, parce qu'après
la modification, il se peut que les invariantes ne tiennent
plus. Du coup, la modification ne doit avoir lieu qu'après
l'exécution complète de la boucle.

Mais c'est une position radicale. On admet certaines entorses. À
condition qu'elles rapportent plus qu'elles coûtent.

[...]
Encore : je crois que jusqu'aujourd'hui, personne n'a trouvé
de solution vraiment satisfaisant dans tous les cas pour le
problème de la boucle et démi.


Mais si, la solution est simplement d'écrire ce qu'on pense,
c'est-à-dire une boucle et demie.


Écrire ce qu'on pense, ça ne marche que si on a une pensée
encore plus rigueureuse que la mienne. Je suis obligé à
m'imposer des règles logiques supplémentaires, comme le maintien
des invariantes, si je veux écrire du code qui marche.

Ce n'est pas dans tes règles de base ça, d'écrire exactement
ce que tu veux dire ? Pense à Ada qui contient une instruction
de boucle généralisée...


Je ne me rappelle plus. J'ai essayé d'apprendre l'Ada une fois,
mais je ne me suis jamais servi. Mais je n'ai jamais dit non
plus que tout ce qui se fait en Ada était bien.

En fait, à part peut-être la présence de continue (dont je ne
vois réelement pas l'utilité), je suis assez content de la
situation en C++. Certes, il permet tout genre de choses
inacceptable (il y a même un goto). Mais de l'autre côté, comme
j'ai dit, il n'y a pas de solution universelle parfaite, et le
C++ me permet toujours la solution que je trouve le plus
appropriée, quelque soit le contexte. C'est un peu le couteau
suisse : et si on peut se sert de la lime aux ongles pour
enlever le bouchon de la bouteille de vin, il y a un
tire-bouchon aussi, et la lime aux ongles est bien pratique
quand il s'agit de limer les ongles.

--
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


1 2 3