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 :

Affectation de 2 tableau (T1=T2)


Sujet :

C

  1. #1
    Membre confirmé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2008
    Messages
    141
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 141
    Par défaut Affectation de 2 tableau (T1=T2)
    Bonjour,

    je me pose actuellement une question : lorsque l'on programme en C l'affectation d'un tableau t1=T2 se fait par ou une recopie ?



    merci

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Citation Envoyé par nzo70 Voir le message
    je me pose actuellement une question : lorsque l'on programme en C l'affectation d'un tableau t1=T2 se fait par une recopie de pointeur ou une recopie case a case?
    La recopie case à case est impossible en C et sera rejetée par le compilateur. Il faut utiliser memcpy pour recopier case à case (ou une boucle pour parcourir le tableau).

    Maintenant, si le compilateur autorise l'affectation, c'est que c'est une copie de pointeur qui a été faite.

    Citation Envoyé par nzo70 Voir le message
    De plus je voudrais savoir comment son réalisésles passages de paramètres par valeur et par adresse d'un tableau?
    La règle est très simple, un tableau est toujours passé par adresse à une fonction
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    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
    Par défaut
    Pour compléter la réponse de ram-0000 :

    La question des tableaux est relativement simple bien qu'étant une exception dans le traitement des objets en C :

    1- Dans tous les cas excepté lorsqu'il est associé aux opérateurs unaires & (adresse de) et sizeof, l'identificateur d'un tableau est une valeur représentant l'adresse du premier élément du tableau. Son type est donc "adresse d'un élément du tableau" et elle peut être affectée à un objet pointeur du type adéquat : "pointeur = tableau".
    Comme l'adresse d'un objet n'est pas modifiable et a été fixée à sa création, cette valeur (représentée par l'identificateur du tableau) n'est pas modifiable et on n'a jamais le droit d'écrire "tableau = .......".

    2- La question
    lorsque l'on programme en C l'affectation d'un tableau t1=T2 se fait par une recopie de pointeur ou une recopie case a case?
    ne se pose pas : il est interdit d'écrire ce code (si t1 est un tableau). Il faut que t1 soit un pointeur.

    3-
    De plus je voudrais savoir comment son réalisésles passages de paramètres par valeur et par adresse d'un tableau?
    En C, les paramètres des fonctions sont sans exception aucune passés par valeur.
    Si dans le cas de l'identificateur d'un tableau, c'est l'adresse de son premier élément qui est passé en argument, c'est en vertu de ce qui est exposé en (1)

  4. #4
    Membre éprouvé
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2008
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2008
    Messages : 143
    Par défaut
    Citation Envoyé par nzo70 Voir le message
    ok! En revanche il y a encore un point que je ne comprends pas. Si l'identificateur du tableau est une valeur représentant l'adresse du premier élement du tableau, comment sont calculés les cases pour obtenir l'élément y figurant?

    merci d'avance
    Les "cases", c'est toi qui les a fixées.

    Tu passe en paramètres un tableaux de type SHORT tu peut très bien faire le tour du tableau avec un pointeur de type CHAR, sauf que tu parcourra ton tableau deux fois moins vite.


    Chaque "cases" équivaut à la taille du type du tableau (ou plutôt du TYPE qu'il est sensé contenir).

  5. #5
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    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
    Par défaut
    Citation Envoyé par nzo70 Voir le message
    ok! En revanche il y a encore un point que je ne comprends pas. Si l'identificateur du tableau est une valeur représentant l'adresse du premier élement du tableau, comment sont calculés les cases pour obtenir l'élément y figurant?

    merci d'avance
    On connait l'adresse du premier élément : tab
    On connait la taille en byte d'un élément du tableau puisque on connait le type T des éléments du tableau
    On sait que les éléments d'un tableau sont consécutifs en mémoire
    Il est donc facile de calculer l'adresse du nieme élément du tableau.

    D'un point de vue du C, si T est le type des éléments du tableau tab, le type de tab (hors & et sizeof) est T*. C'est une adresse et l'arithmétique associée à tab est l'arithmétique des adresses. Par conséquent, l'adresse de l'élément d'indice n est tab+n. L'élément lui-même est donc *(tab+n). En fait, lorsque tu écris tab[n], le compilateur l'interprète comme *(tab+n) et la notation [] est là pour nous donner un simplification syntaxique (très avantageuse surtout dans les tableaux à plusieurs dimensions).

  6. #6
    Membre confirmé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2008
    Messages
    141
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 141
    Par défaut
    merci pour vos reponses. Une autre question me trotte dans la tête. D'un

  7. #7
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Que veux-tu dire ici par "pile" ?
    Ceci est plutôt le genre de chose qui se fait avec les registres. Ici, au minimum, deux registres sont nécessaires:
    Code pseudocode : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    R1 := y;
    R2 := x;
    R1 := *R1;
    R1 *= R2;
    R2 := R1;
    R1 := y;
    *R1 := R2;
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Membre confirmé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2008
    Messages
    141
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 141
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    int y;
    void h(int d, int *r) {
    int y;
    J'ai une derniere question a laquelle je souhaiterais bien pourvoir repondre...



    merci

  9. #9
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    La variable locale y dans g() masque la variable globale y dans la fonction, celle-ci n'y accède donc pas en tant que telle.

    Ici, seules les fonctions f() et main() accèdent directement à y. Par contre, g() reçoit un pointeur vers y, et la modifie donc indirectement.

    Voici un code avec les variables renommées:
    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
    int glob_y;
     
    void g(int const gd, int * const gr) {
    	int gy;
    	gy = *gr;
    	*gr = gd+1;
    }
     
    void f(int const fd, int * const fr) {
    	int fx;
    	fx = fd+1;
    	glob_y = 1;
    	*fr = fx;
    	g(*fr, fr);
    }
     
    int main() {
    	int mx;
    	mx = 3;
    	f(mx, &glob_y);
    	return 0;
    }
    Au moins, je peux te décrire le déroulement (= signifie ici équivalence, j'utilise := pour l'affectation):
    • appel de main() : glob_y non initialisé (ou initialisé à zéro, je ne sais plus)
    • variable locale mx := 3
    • appel de f(fd := mx = 3, fr := &glob_y)
    • variable locale fx := fd + 1 = 4
    • glob_y := 1
    • *fr = glob_y := fx = 4
    • appel de g(gd := *fr = glob_y = 4, gr := fr = &glob_y)
    • variable locale gy := *gr = glob_y = 4
    • *gr = glob_y := gd + 1 = 5
    • retour de g à f
    • retour de f à main
    • Si je ne me suis pas trompé, glob_y vaut 5 ici.
    • retour de 0
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Membre confirmé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2008
    Messages
    141
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 141
    Par défaut
    merci mais donc par rapport a un programme qui ne possede pas de variables globales ex :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    void f(int x, int *y) {
    if (x == 0) (*y) = 1;
    else {
    f(x-1,y);
    (*y) = (*y) * x;
    }
    }
    int main(void) {
    int x;
    x = 4;
    f(x,&x);
    return 0;
    }
    quelle nouvelle information figure dans la pile quand les fonctions (du programme contenant la variable globale) f et g s'exécutent?

    merci d'avance

  11. #11
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Là, c'est plus difficile, car il y a récursivité (et non-terminale, en plus).
    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
    void f(int const x, int * const y) {
    	if (x == 0) {
    		 *y = 1;
    	} else {
    		f(x-1, y);
    		 (*y) *= x;
    	}
    }
     
    int main(void) {
    	int mx;
    	mx = 4;
    	f(mx, &mx);
    	return 0;
    }
    Ce qui est sûr, c'est que le pointeur ne change pas, donc y pointe toujours sur la même variable: mx.
    f() est rappelée avec à chaque fois une valeur inférieure (qui est une copie à chaque fois, donc ne modifie rien), jusqu'à ce qu'une fonction soit appelée avec x==0. Après, on initialise la variable pointée (ici, mx) à 1, puis au fur et à mesure qu'on remonte on multiplie par la valeur de x dans la fonction. Ceci est juste un exemple plus compliqué que la normale de calcul récursif d'une factorielle, un cas d'école sur la récursivité (mais inutile en soi, car un calcul itératif de la factorielle est plus simple et plus efficace).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  12. #12
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    En gros, sur la pile, si on mettait un breakpoint juste avant le *y = 1, on aurait ça:
    • main()
    • f(4, &mx)
    • f(3, &mx)
    • f(2, &mx)
    • f(1, &mx)
    • f(0, &mx)

    Ce qui donne, avec convention d'appel C (en noir, les variables locales et registres sauvegardés; en rouge, les appels de fonction) :
    • adresse de retour hors du programme
    • registres sauvegardés par main()
    • mx = 4
    • adresse de mx
    • 4
    • adresse de retour dans main
    • registres sauvegardés par f
    • adresse de mx
    • 3
    • adresse de retour dans f
    • registres sauvegardés par f
    • adresse de mx
    • 2
    • adresse de retour dans f
    • registres sauvegardés par f
    • adresse de mx
    • 1
    • adresse de retour dans f
    • registres sauvegardés par f
    • adresse de mx
    • 0
    • adresse de retour dans f
    • registres sauvegardés par f
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  13. #13
    Membre confirmé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2008
    Messages
    141
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 141
    Par défaut
    donc en fait dans le programme contenant la variable globale lorsque f s'exécute il y a seulement l'adresse de la variable locale qui est stockée en plus que lorsque la fonction f s'execute dans l'autre programme?

    C'est pareil pour g?

  14. #14
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Redis-ça lentement, car je n'arrive pas à comprendre ce que tu penses avoir compris.

    Un dessin peut aider.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. problème affectation d'un tableau de char
    Par midotek dans le forum Collection et Stream
    Réponses: 5
    Dernier message: 07/12/2008, 22h50
  2. Affectation d'un tableau
    Par alouha dans le forum Collection et Stream
    Réponses: 14
    Dernier message: 14/06/2008, 22h46
  3. Affectation d'un tableau
    Par rico3434 dans le forum Débuter
    Réponses: 1
    Dernier message: 19/11/2007, 17h42
  4. Affectation dans un tableau d'objet
    Par kheiro dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 30/08/2007, 13h13
  5. affectation sur un tableau dynamique
    Par oranoutan dans le forum C
    Réponses: 35
    Dernier message: 27/06/2007, 01h16

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