IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Récupérer a la sortie d'une fonction une matrice de taille inconnue


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti

    Inscrit en
    Juin 2009
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 25
    Par défaut Récupérer a la sortie d'une fonction une matrice de taille inconnue
    Bonjour.

    Je dois actuellement recoder une appli python en C pour un gain de temps de calcul, mais étant débutant (mauvais serait le terme plus exact) dans ce langage, j'ai besoin de vos lumieres.


    Je cherche a recuperer dans ma fonction principale une matrice écrite par une fonction, mais la taille de cette matrice sera imposé par la fonction et je n'ai donc aucun moyen de connaitre sa taille dans le main.

    J'ai essayé la methode que je trouvais instinctive, c'est a dire lire dans le main le pointeur (pointant la matrice) renvoyé par la fonction, mais la ou seule 4 caracteres doivent s'affiché, j'en ai un vingtaine.

    Quelqu'un a une idée de principe pour se probleme.

    Question subsiliaire : comment passer une matrice a 3 dimensions a une fonction.

    Merci de votre aide.

    Lau

  2. #2
    Membre émérite Avatar de sloshy
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2005
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Janvier 2005
    Messages : 728
    Par défaut
    Bonjour,

    Citation Envoyé par lapinoufly Voir le message
    Je cherche a recuperer dans ma fonction principale une matrice écrite par une fonction, mais la taille de cette matrice sera imposé par la fonction et je n'ai donc aucun moyen de connaitre sa taille dans le main.
    Tu es sur le bon chemin.
    Dans ton main tu déclare un pointeur, tu le passe à ta fonction qui vas malloc le pointeur et remplir la matrice.
    Une fois de retour dans le main, n'oublie pas de free ^^

    Citation Envoyé par lapinoufly Voir le message
    J'ai essayé la methode que je trouvais instinctive, c'est a dire lire dans le main le pointeur (pointant la matrice) renvoyé par la fonction, mais la ou seule 4 caracteres doivent s'affiché, j'en ai un vingtaine.
    Donne nous un code à debug


    Citation Envoyé par lapinoufly Voir le message
    Question subsiliaire : comment passer une matrice a 3 dimensions a une fonction.
    en passant un pointeur de pointeur de pointeur?

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par lapinoufly Voir le message
    Je dois actuellement recoder une appli python en C
    Quel dommage !!! Moi qui connait les deux langages, après avoir goûté à Python je pleurerais si je devais revenir au C...

    Citation Envoyé par lapinoufly Voir le message
    pour un gain de temps de calcul
    J'ai eu une fois un pb de temps de calcul en Python et j'avais aussi envisagé, beaucoup de dégoût, de passer par le C. Puis j'ai réfléchi. Comme j'utilisais aussi une bdd Postgres, j'ai alors choisi de déporter mes calculs dans des tables temporaires Postgres en laissant à ce moteur le soin d'effectuer tous les calculs et les liens entre les infos à la place de Python. Et ça a marché. Comme quoi, comme le dit sloshy, il n'y a jamais une seule solution à un problème...

    Citation Envoyé par lapinoufly Voir le message
    Question subsiliaire : comment passer une matrice a 3 dimensions a une fonction.
    Si tu dois passer un tableau d'int à une fonction, style int tab[x], tu passes tab et ta fonction stocke ce "tab" dans un "int *pt" ou un "int pt[] ou un "int pt[x]"

    Si tu dois passer un tableau 2D d'int à une fonction, style int tab[y][x], tu passes toujours tab mais ta fonction le stockera dans un "int *pt[x]" ou un "int pt[y][x]". En aucun cas elle ne pourra le stocker dans un "int **pt" parce qu'elle a besoin de la dimension [x] pour pouvoir se caler. En effet, la case [m][n] se calcule comme "m * x + n" (n'oublie pas qu'un tableau, même 2D, n'est en réalité qu'une grosse suite de cases et que la 2D n'est que simulée).

    Ainsi, si tu dois passer un tableau 3D d'int à une fonction, style int tab[z][y][x], tu passes toujours tab mais ta fonction le stockera dans un "int *pt[y][x]" ou un "int pt[z][y][x]". Pour la même raison que précédemment, elle ne pourra pas le stocker dans un "int ***pt"

    En fait, l'équivalence pt[] <=> *pt n'est valable que pour la première dimension d'un tableau...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre émérite Avatar de sloshy
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2005
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Janvier 2005
    Messages : 728
    Par défaut
    merci pour l'info, je me coucherai moins bête ce soir

  5. #5
    Membre averti

    Inscrit en
    Juin 2009
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 25
    Par défaut
    Merci de votre aide, mais la réponse m'amène a un autre problème....

    Pour vous mettre un peu dans le bain, je fais actuellement du traitement d'image pour des automatismes.

    Mon main envoie une image déformée a une fonction qui a pour but de la "redresser". Pour faire simple je connais la taille de l'image que j'envoie, mais je ne connais pas la taille de l'image que je récupère (deformation...).


    Les 2 methodes instinctives que j'avais, c'etais de renvoyer directement l'image redressé en sortie de la fonction avec un return, un truc du genre :

    *image_redresse = fonction_redressage (image_deforme)

    Mais le compilateur ne connaissant pas les dimensions de image_redresse, ca part en vrille et le resultat n'est pas ce que je veux.

    La seconde methode était de donner en argument de la fonction le pointeur de debut de matrice:

    fonction_redressage (image_deforme , *debut_pointeur)

    mais ne connaissant pas la taille de ma matrice, je ne peut faire une allocation memoire propre.....

    Voila ou commence mes problemes....
    Si vous avez des solutions a proposer...


    Et oui je suis degouté de repasser en C...
    J'utilise python pour valider mes algorithmes de traitements d'image, et je m'en sortais jusque la, mais la c'est trop lourd... j'ai besoin de 25 images/ secondes et pour l'instant j'en ai que 12... passage en C obligé!

  6. #6
    Membre averti

    Inscrit en
    Juin 2009
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 25
    Par défaut
    1-pour le probleme de base une idée me viens....

    si ma fonction retourne un vecteur donnant : ref_image=[nb_ligne , nb_colonne, debut_pointeur], ce qui donnerais vu du main

    *ref_image= fonction_redressage (image_deforme)

    il doit etre possible de reformer image redressé en 2/3 lignes, non?

    2-Existerait il une classe "matrice" deja toute faite qui me permettrais de passer simplement une matrice

    3- pour un autre probleme je suis en train de seuiller un vecteur A, et je veux recuperer la position des valeurs superieurs au seuil dans un autre vecteur B.
    Probleme je ne connais pas la dimension du vecteur B donc je ne peux pas le declarer proprement.

    Si j'alloc pas assez de memoire j'efface des données et si j'alloc trop de memoire ben je consomme trop de memoire....
    Quel solution est couramment utilisés?
    Realoc a chaque fois que je veux ajouter une valeur?

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par lapinoufly Voir le message
    1-pour le probleme de base une idée me viens....

    si ma fonction retourne un vecteur donnant : ref_image=[nb_ligne , nb_colonne, debut_pointeur], ce qui donnerais vu du main

    *ref_image= fonction_redressage (image_deforme)

    il doit etre possible de reformer image redressé en 2/3 lignes, non?

    2-Existerait il une classe "matrice" deja toute faite qui me permettrais de passer simplement une matrice
    Désolé. Le C est très primaire. Il ne peut manipuler que des types simples (int, char, short, etc) et des adresses. Il ne sait même pas manipuler une simple chaine alors une matrice...
    A toi de faire avec ce que le C te donne. Ton seul atout: une zone allouée est toujours contigüe en mémoire. Et donc avec
    - l'adresse de début
    - le nb d'éléments
    Tu peux alors tout récupérer. La suite, c'est de la gestion, de l'algorithmie et de l'intuition...

    Citation Envoyé par lapinoufly Voir le message
    3- pour un autre probleme je suis en train de seuiller un vecteur A, et je veux recuperer la position des valeurs superieurs au seuil dans un autre vecteur B.
    Probleme je ne connais pas la dimension du vecteur B donc je ne peux pas le declarer proprement.

    Si j'alloc pas assez de memoire j'efface des données et si j'alloc trop de memoire ben je consomme trop de memoire....
    Quel solution est couramment utilisés?
    Realoc a chaque fois que je veux ajouter une valeur?
    Un realloc c'est relativement long. On essaye donc de faire des compromis. Et donc généralement, quand on gère des flux de taille inconnue, on fait des allocations par blocs. On alloue N et on gère une taille allouée et une taille utilisée. Et dès que la taille utilisée atteint la taille allouée, on réalloue N de plus. Ca évite le realloc à chaque tour de boucle (et c'est relativement souple puisqu'on peut, si on désire, positionner quand-même N à 1).
    Et comme toutes ces variables de gestion vont ensemble, ben on les groupe dans une structure ce qui est ensuite plus simple à manipuler.

    Exemple pour stocker des char qui arrivent en flot continu
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    typedef struct {
        char *tab;
        char *new;
        size_t alloc;
        size_t current;
    }t_dynamic;
     
    char carac;
    t_dynamic zone;
    zone.tab=NULL;
    zone.new=NULL;
    zone.alloc=0;
    zone.current=0;
     
    while (carac=donnee_arrive())
    {
        // Si besoin mémoire (au premier appel, un realloc se comporte comme un malloc)
        if (zone.current == zone.alloc)
        {
            zone.alloc+=N;
            zone.new=realloc(zone.tab, zone.alloc * sizeof(char));
            if (zone.new == NULL)
            {
                 // malloc/realloc échoué - Cas à traiter - Il se terminera probablement par une libération de ce qui a déjà été alloué et une interruption de la fonction
                 ...
            }
     
            // malloc/realloc réussi - Le nouveau pointeur remplace l'ancien
            zone.tab=zone.new;
        }
     
        // Stockage caractère lu
        zone.tab[zone.current]=carac;
        zone.current++;
    }
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. appliquer une fonction à une fonction
    Par stracoma dans le forum C++
    Réponses: 6
    Dernier message: 20/03/2015, 16h35
  2. Réponses: 2
    Dernier message: 14/01/2011, 11h05
  3. Récupérer le nom du fichier qui appelle une fonction
    Par DeezerD dans le forum Langage
    Réponses: 2
    Dernier message: 24/03/2007, 14h37
  4. Réponses: 2
    Dernier message: 08/10/2006, 11h44
  5. passer en paramettre d'une fonction une fonction
    Par RoM3Ro dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 23/06/2006, 15h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo