CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[C] Arguments en trop

-MasterLink-
-MasterLink-
Niveau 6
20 janvier 2008 à 13:14:43

Salut

Je reposte un sujet ici pour une question concernant les arguments envoyés à une fonction.

Je vais prendre l'exemple d'un editeur de niveau. Si on a deux fonctions, map(), qui à chaques lignes apelle une fonction pour placer un sprite sur l'ecran et la deuxieme fonction placement() qui s'occupe de placer ces sprites en fonction des arguments écrit dans map().

La fonction placement() est assez générale, il y aura dedans un bout de code pour placer le sprite, un autre au cas ou le sprite possede une animation etc...

Il y aura donc dans map() des lignes du genre
placement(perso, 1000,800,40,40, 1 ,2,4) //exemple hein :p)
où le premier argument pourra être l'image à afficher, les 4 chiffres suivants des int pour positionner le sprite sur l'ecran, le suivant un bool pour savoir si le sprite est animé ou non, et les 2 derniers pour savoir quel est le sprite de départ et d'arrivée

Je me demandais donc, dans un cas plus évolué, si placement() demandais une 15ene d'arguments, et que je voulais simplement afficher un sprite, il y aura donc des appels de fonctions du genre
placement(perso , 1000,800,40,40 ,0 ,0,0 ,0,0,0,0 ,0,0)
Tous ces 0 qui servent dans des cas d'affichage de sprite "avancé", sont-ils très genant dans le cas d'un simple affichage, où ils ne servent donc qu'a prendre de la place? Ou peut-on fermer l'oeil sur ce genre de choses?

Merci d'avance

godrik
godrik
Niveau 30
20 janvier 2008 à 13:18:03

Ca ne gene probablement pas, empiler quelques entier ne coute généralement pas bien cher.
Cependant, si tu constates des problemes de performance dans ton application et que tu ne vois plus d'optimisation algorithmique a efefctuer, alors tu pourrais tenter d'ecrire une fonction placement et une autre placement-avance.

pilo1488
pilo1488
Niveau 10
20 janvier 2008 à 23:43:56

tu peux aussi faire plusieurs fonction placement, adapté à leur utilisation.
(genre palcement, placement_simple, ou placement avancé, etc).

En ce qui concerne les optimisations et les temps de calculs : utilise un profiler, qui te donnera exactement ou ce situe le bottleneck de ton code (bon bien évidement comme le dit godrik, il faut que des algos soient optimal). Dans ce cas la je doute que ca est un reel impact sur le temps d'execution.

dnob700
dnob700
Niveau 10
21 janvier 2008 à 11:15:57

si ce qui te gène c'est d'écrire ces zéro inutile, tu peut utiliser des arguments optionnels :

Tu prend le prototype de ta fonction placement qui doit ressembler à ça :
void placement(sprite s, int x, int y, int w, int h, int a, int b, etc...);

Et tu écris à la place :
void placement(sprite s, int x, int y, int w, int h, int a=0, int b=0, etc...);

Si tu n'utilise pas de prototype pour ta fonction (i.e., si elle st avant l'autre dans ton programme) tu change ça directement dans la déclaration de la fonction.

Et maintenant, quant tu appelle ta fonction, tu peut ne pas écrire tout les argument qui ont une valeur par défaut genre :
...
placement(s,x,y,w,h);
...
ou alors :
placement(s,x,y,w,h,a);

Sachant que si tu décide de ne pas écrire un des arguments, tu ne peut écrire aucun de ceux qui viennent après.

gizmosup
gizmosup
Niveau 3
21 janvier 2008 à 11:20:14

Salut,

En C++, il existe des fonctions qui permettent d'ajouter un nombre d'arguments illimités. Je me souvient plus trop comment ca marche donc ne pourrait pas parfaitement répondre à ta question ici.

Une deuxième possibilité dans le cas d'autres langages (comme le Java) est de créer une fonction ayant comme paramètre ou un objet ou un array d'éléments (la premier solution étant la meilleure bien sûr).
Tu ferais donc un système comme celui-ci :
persoComplet.setPerso(perso);
persoComplet.setH(1000);
persoComplet.setY(800);
...
persoComplet.setAutre(0);
placement(persoComplet);
ta fonction placement serait du type public void placement(PersoComplet persoComplet)

ou encore pour le système d'Array
perso = new Array();
perso.add(perso);
perso.add(1000);
perso.add(800);
...
perso.add(0);
placement(perso);
ta fonction placement serait du type public void placement(Array perso)

Dernier point en C pur, tu pourrais (comme pour l'Array) utiliser une liste chaînée contenant tes données l'une après l'autre.

Voilà, en espérant que tu ais compris et que cela te soit utile.

Nepser
Nepser
Niveau 5
21 janvier 2008 à 14:24:51

Déjà, il y au n forum pour la programmation ici: https://www.jeuxvideo.comom/forums/0-47-0-0-0-0-0-0.htm

Ensuite, je vais te donner 2 méthodes:
Il existe, en C (et non en C++) un moyen de mettre un nombre d'argument variable, ce que l'on appelle va_list, un tuto est dispo sur cette page: http://homepage.mac.com/pierremousel/LangC/LangCArgumentsVar.html (2° résultat google)

Aussi, je te conseilles de te baser plutot sur une structure (ou tableau) que tu remplis avant de l'envoyer sur ta fonction. Tu gagner

Nepser
Nepser
Niveau 5
21 janvier 2008 à 14:25:34

Tu gagneras énormément en lisibilité de ton code et en praticité.

PS: il demande du code C et non du C++

pilo1488
pilo1488
Niveau 10
21 janvier 2008 à 14:55:37

les va_list c'est normalement utilisé quand on ne connais pas le nombre d'argument à priori (et il faut savoir comment le connaitre), la ca serait bcp trop compliqué.

Les structures c'est pas mal en effet comme solution.

godrik
godrik
Niveau 30
22 janvier 2008 à 09:12:02

"void placement(sprite s, int x, int y, int w, int h, int a=0, int b=0, etc...);"
a priori, c'est du C++ ca. a moins que ca aie été intégré dans le C99 ?

Utiliser des va_args pour ca c'est de la connerie. D'ailleurs (amha), les va_arg, c'est de la connerie...

Passer des structures en parametre ne va absolument pas regler le probleme. Fondamentalement, il y aura autant de parametre (si vous me parlez de structure sur le tas, alors il faut faire une ecriture et une lecture en mémoire, c'est en l'occurence bien plus long qu'un passage en registre). De plus, ce n'est pas beaucoup plus simple a ecrire.

personellement, je vote: faire deux fonctions. Si les traitements sont similaires, en faire une qui appele l'autre (et faire confiance au compilateur pour inliner le code). Ou si les traitements sont differents, en faire deux.

Nepser
Nepser
Niveau 5
22 janvier 2008 à 21:20:49

@godrik:
N'importe quoi... t'es sur que tu sais programmer?

"Passer des structures en parametre ne va absolument pas regler le probleme. Fondamentalement, il y aura autant de parametre (si vous me parlez de structure sur le tas, alors il faut faire une ecriture et une lecture en mémoire, c'est en l'occurence bien plus long qu'un passage en registre). De plus, ce n'est pas beaucoup plus simple a ecrire."

Le problème c'est de devoir ou pas écrire une quinzaine de paramètres sur une fonction.
Tu vasm e dire que demander une structure pour simplifier ça c'est de la connerie? dis pas n'improte quoi, ça ramène le tout à un seul argument. Aucun rapport avec le tas/ registre ou autre, ne parle pas de choses que tu ne maitrises pas.

Le passage d'une structure initialisée à 0 avec les valeurs que tu veux est vachement rapide:

ta_structure * machin = malloc(sizeof(*machin);
memset(machin, 0 , sizeof(machin) );
/* la tu mets les valeurs que tu souhaites dans ta structure
enfin tu envois ta structure à la fonction*/
placement(machin);

et voilà c'est terminé.

Maintenant, avant de dire que les choses c'est de la connerie ou autre godrik, essaie de savoir ce que c'est.

godrik
godrik
Niveau 30
23 janvier 2008 à 00:25:25

preuve par l'exemple:
cas numero 1:
placement(perso , 1000,800,40,40 ,0 ,0,0 ,0,0,0,0 ,0,0)

cas numero 2:
dans un enetete ailleurs:
struct plouf {
Sprite s;
double posX, posY, width, height, angle, alpha;
};
dans la fonction
plouf parametre;
parametre.angle=parametre.alpha=0.0;
paramete.s=perso;
parametre.posX=1000.0;
parametre.posY=800.0;
parametre.width = parametre.height = 40;

placement (&parametre);

cas numero 2 me semble pas plus court ou plus facil a utiliser que cas numero 1... De plus, dans un programme bien ecrit, on ne devrait pas avoir 50 appel a la fonctions position, racourcir son ecriture ne devrait pas alors etre si importante que ca.

Si je parle du passage des parametres a une fonction, c'est parceque l'auteur du topic se posait la question du surcout impliqué par le passage de parametre inutile dans son contexte.

dnob700
dnob700
Niveau 10
23 janvier 2008 à 21:04:54

D'autre part nepser, avant de t'en prendre à godrik qui code probablement bien mieux que beaucoup de personnes ici, je te conseille de lire quelques cours sur le C comme sur le C++ et sur le design d'un bon programme.

Parce que, entre autre, proposer de faire joujou avec des pointeurs et la représentations en mémoire des données est certainement une très mauvaise idée dans n'importe quel programme. C'est source de bogue, la preuve c'est que rien que dans tes 3 lignes de codes, il y a une erreur (sizeof(machin)==4 et donc tu ne mets pas suffisamment de 0 dans ta structure) ...

Bref, pour celui qui prétendait que "[on] gagner[a] énormément en lisibilité de [notre] code et en praticité" à utiliser cette technique. Je pense que tu devrais commencer par être un peu plus respectueux dans tes réponse et ne pas insulter tout le monde, surtout si c'est pour sortir de telles énormités.

Nepser
Nepser
Niveau 5
23 janvier 2008 à 22:02:54

Woops, manque un *: (sizeof(*machin)) est correct.

Pour répondre au reste:
@godrik: l'iniatialisation sera plus longue si on passe var par var effectivement, mais ça m'étonnerait qu'il ai un programme au final avec 50 lignes:
placement(perso , 1000,800,40,40 ,0 ,0,0 ,0,0,0,0 ,0,0)
placement(perso1 , 1000,800,40,40 ,0 ,0,0 ,0,0,0,0 ,0,0)
placement(perso2 , 1000,800,40,40 ,0 ,0,0 ,0,0,0,0 ,0,0)
placement(perso3 , 1000,800,40,40 ,0 ,0,0 ,0,0,0,0 ,0,0)

Il arrivera rapidement au besoin de passer tout par des variables, et pour éviter d'avoir à changer à tout bout de champs le prototype de la fonction au cours du développement, autant passer par une structure. C'est un problème d'organisation et de modularité qu'il va certainement rencontrer.

@dnob700: j'me suis enflammé sur ses répliques
"a priori, c'est du C++ ca. a moins que ca aie été intégré dans le C99 ?

Utiliser des va_args pour ca c'est de la connerie. D'ailleurs (amha), les va_arg, c'est de la connerie... "
Il me paraissait partir totalement hors sujet au problème et raconter n'importe quoi au début.

@godrik: j'ai regardé vite fait ton site, j'ai noté de grosses erreurs:

  1. define CONCAT(x, y) x##y

printf ("%s", CONCAT (toto, tata));
/*equivalent a printf ("%s", "tototata");*/

tout à fait faux, c'est équivalent à:
printf ("%s", totocaca);

Soit un nom de variable et non une chaine de caractère.
Peut s'utiliser dans ce genre de cas:

  1. define my(x) my_##x

int my_chocolat = 2;
printf("%d", my(chocolat) );

godrik
godrik
Niveau 30
23 janvier 2008 à 22:52:20

en meme temps, j'ai ecrit ca il y a dix ans...
je relirais.

Sous forums
  • Aide à l'achat Mac
  • Création de Jeux
  • Linux
  • Programmation
  • Création de sites web
  • Internet
  • Steam Deck
  • Macintosh
  • Hardware
La vidéo du moment