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 :

Passage par adresse ou par valeur ?


Sujet :

C

  1. #1
    Nouveau membre du Club
    Inscrit en
    Janvier 2007
    Messages
    43
    Points
    31
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 43
    Points : 31
    Par défaut Passage par adresse ou par valeur ?
    Bonjour

    Je suis débutant en C et j'aimerais savoir si le programme ci-dessous utilise le passage par adresse ou par valeur ?? C'est moi qui est écrit ce programme en tatonnant avec les pointeurs. En fait je ne sais jamais s'il faut mettre le * ou pas ??

    Code : 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
    36
    37
     
    #include <stdio.h>
    #include <stdlib.h>
     
    typedef struct bateau_s{
    	int longueur;
    }bateau;
     
    bateau taille( int n_b , bateau *b )
    {
    	int i;
    	for(i=1;i<=n_b;i++)
    	{
    		(b+i)->longueur = i;
    	}	
     return *b;
    }
     
    int main(void)
    {
    	int i, nbre_bato;
    	bateau *bato; 
     
    	printf("nbre de bato: ");
    	scanf(" %d",&nbre_bato);
     
    	bato = (bateau *)malloc( nbre_bato*sizeof(bateau) );
     
    	*bato = taille( nbre_bato , bato );
     
    	for(i=1;i<=nbre_bato;i++)
    	{
    		printf("bato %d = %d\n",i,(bato+i)->longueur);
    	}	
     
     return 0;
    }
    Merci

  2. #2
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Points
    13 926
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Par défaut
    1-
    j'aimerais savoir si le programme ci-dessous utilise le passage par adresse ou par valeur ??
    En C, il n'existe que des passages par valeur. Il est pernicieux de parler de passage par adresse lorsqu'on passe l'adresse d'un objet. En fait, on passe la valeur de l'adresse d'un objet, pas l'objet lui-même.
    2-
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    bateau taille( int n_b , bateau *b )
    {
    	int i;
    	for(i=1;i<=n_b;i++)
    	{
    		(b+i)->longueur = i;
    	}	
     return *b;
    Les indices de tableau vont de 0 à (nombre d'éléments -1) et non pas de 1 à (nombre d'éléments )
    3-
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    *bato = taille( nbre_bato , bato );
    bato est déjà l'adresse du début du tableau. La fonction taille peut donc modifier les éléments du tableau indépendamment de la valeur de retour

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void taille( int n_b , bateau *b )
    {
    	int i;
    	for(i=0;i<n_b;i++)
    		(b+i)->longueur = i;	
    }
    3- Il est inutile (et on considère que c'est plutôt néfaste) de caster le retour de malloc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bato = malloc( nbre_bato*sizeof *bato );

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Points
    41 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 593
    Par défaut
    Comme tu as un tableau de structure, tu peux utiliser directement la notation "tableau" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void taille( int n_b , bateau *b )
    {
    	int i;
    	for(i=0 ; i<n_b ; i++)
    		b[i].longueur = i;	
    }

  4. #4
    Nouveau membre du Club
    Inscrit en
    Janvier 2007
    Messages
    43
    Points
    31
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 43
    Points : 31
    Par défaut
    Merci pour vos réponses diogene et Médinoc

    J'ai maintenant un autre probléme. j'ai séparé mon fichier source en 2 fichiers .c et un .h ainsi qu'un fichier Makefile pour le builder
    Voici mes fichier:

    ex.c
    Code : 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
    #include <stdio.h>
    #include <stdlib.h>
     
    #include "ex.h"
     
    typedef struct bateau_s{
    	int longueur;
    }bateau;
     
    int main(void)
    {
    	int i, nbre_bato;
    	bateau *bato; 
     
    	printf("nbre de bato: ");
    	scanf(" %d",&nbre_bato);
     
    	bato = malloc( nbre_bato*sizeof(bateau) );
     
    	taille( nbre_bato , bato );
     
    	for(i=1;i<=nbre_bato;i++)
    	{
    		printf("bato %d = %d\n",i,(bato+i)->longueur);
    	}	
     
     return 0;
    }
    ex.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void taille( int n_b , bateau *b );
    taille.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <stdio.h>
    #include <stdlib.h>
     
    void taille( int n_b , bateau *b )
    {
    	int i;
    	for(i=1;i<=n_b;i++)
    	{
    		(b+i)->longueur = i;
    	}	
    }
    Makefile
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ex: ex.o taille.o
     
    	gcc -o ex ex.o taille.o
     
    ex.o: ex.c ex.h
     
    	gcc -c ex.c
     
    taille.o: taille.c
     
    	gcc -c taille.c
    Quand j'utilise le commande make, il me dit:
    xxxx@xxxx:~/Bureau/ex$ make
    gcc -c ex.c
    In file included from ex.c:4:
    ex.h:2: erreur: expected declaration specifiers or «...» before «bateau»
    ex.c: Dans la fonction «main» :
    ex.c:20: erreur: trop d'arguments pour la fonction «taille»
    make: *** [ex.o] Erreur 1

    Je pense que cela vient du fait que le type bateau n'est déclaré que dans ex.c ????
    Qu'en pensez vous ??
    Merci

  5. #5
    Membre habitué
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2005
    Messages
    147
    Points
    165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2005
    Messages : 147
    Points : 165
    Par défaut
    Salut,

    En effet, la définition du type bateau est faite après l'inclusion de ex.h, ce qui fait que quand le compilateur arrive sur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void taille( int n_b , bateau *b );
    il ne connait pas le type bateau. Il faut donc mettre le type bateau dans le fichier .h, avant le prototype de la fonction taille.

    D'autre part, je trouve ton découpage un peu étrange. Normalement, pour une fonction avec un fichier d'entete, on donne le meme nom au fichier d'entete (.h) qui déclare la fonction et au fichier source (.c) qui implémente le corps de la fonction.

    Ce qui donne :

    ex.c
    Code : 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
    #include <stdio.h>
    #include <stdlib.h>
    
     
    #include "taille.h"
    
    int main(void)
    {
        int i, nbre_bato;
        bateau *bato; 
     
        printf("nbre de bato: ");
        scanf(" %d",&nbre_bato);
     
        bato = malloc( nbre_bato*sizeof(bateau) );
     
        taille( nbre_bato , bato );
     
        for(i=1;i<=nbre_bato;i++)
        {
            printf("bato %d = %d\n",i,(bato+i)->longueur);
        }    
     
     return 0;
    }
    taille.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #ifndef TAILLE_H
    #define TAILLE_H
    
    typedef struct bateau_s{
        int longueur;
    } bateau;
    
    void taille( int n_b , bateau *b );
    
    #endif
    J'ai rajouté #ifndef TAILLE_H etc pour ne pas déclarer deux fois le type bateau et la fonction taille, meme si taille.h est inclu plusieurs fois

    taille.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <stdio.h>
    #include <stdlib.h>
    
    #include "taille.h"
    
    void taille( int n_b , bateau *b )
    {
        int i;
        for(i=1;i<=n_b;i++)
        {
            (b+i)->longueur = i;
        }    
    }
    Makefile
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    ex: ex.o taille.o
     
        gcc -o ex ex.o taille.o
     
    ex.o: ex.c taille.h
     
        gcc -c ex.c
     
    taille.o: taille.c taille.h
     
        gcc -c taille.c
    Voila, j'espère pas avoir dit trop de bêtises.

  6. #6
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Points
    13 926
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    	bato = malloc( nbre_bato*sizeof(bateau) );
    ... 
    	for(i=1;i<=nbre_bato;i++)
    	{
    		printf("bato %d = %d\n",i,(bato+i)->longueur);
    	}
    Je te rappelle à nouveau que les indices de tableau vont de 0 pour le premier élément à (nombre d'éléments -1) pour le dernier (ici, de 0 à nbre_bato-1) !!!!

  7. #7
    Membre habitué
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2005
    Messages
    147
    Points
    165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2005
    Messages : 147
    Points : 165
    Par défaut
    Exact pour les indices, j'ai fait un bête copier-coller sans relire, et je n'ai pas modifier

  8. #8
    Nouveau membre du Club
    Inscrit en
    Janvier 2007
    Messages
    43
    Points
    31
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 43
    Points : 31
    Par défaut
    C'est bon tout fonctionne (j'ai changé les indices)
    Merci à tous les trois !!!!

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

Discussions similaires

  1. passage de gros tableaux par adresse
    Par ol9245 dans le forum MATLAB
    Réponses: 7
    Dernier message: 10/10/2012, 12h51
  2. Passage de paramètres par adresse ou par copie ?
    Par EpiTouille dans le forum Langage
    Réponses: 6
    Dernier message: 24/12/2011, 11h31
  3. [vocabulaire] passage par adresse et par valeur.
    Par debutantenalgo dans le forum Algorithmes et structures de données
    Réponses: 6
    Dernier message: 21/12/2009, 16h42
  4. Réponses: 12
    Dernier message: 26/01/2008, 21h23
  5. Passage par valeur / passage par adresse
    Par jeje99 dans le forum C++
    Réponses: 13
    Dernier message: 16/02/2006, 11h29

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