6
votes

Type de tableau - Règles d'attribution / utilisation en tant que paramètre de fonction

Lorsque j'ai besoin de transmettre un tableau à une fonction, il semble que toutes les déclarations suivantes de la fonction fonctionnent xxx

pour ceci: xxx

mais lorsque j'identifie un tableau à un autre tableau, il échoue xxx

alors pourquoi un tableau passé comme argument d'une fonction est correct, mais utilisé sur le RHS de simple affectation est faux?


1 commentaires

Le titre de la question doit être réécrit, l'un actuel est excessivement générique et minuscule.


7 Réponses :


7
votes
void f(int *arr);

1 commentaires

Oui, cependant (en C99) VOID F (int Arr [statique 4]) {...} est spécial car cela permet au compilateur de supposer que arr compiler est non- null et a une taille au moins 4.



6
votes

c ne prend pas en charge l'affectation de tableaux. Dans le cas d'un appel de fonction, la matrice se désintègre à un pointeur. C soutenir l'affectation des pointeurs. Ceci est interrogé ici à peu près tous les jours - Qu'est-ce que le livre de texte C est votre lecture qui ne veut pas expliquer cela?


0 commentaires

3
votes

Essayez memcpy.

int a[]={1,2,3,4};
int b[4];
memcpy(b, a, sizeof(b));


1 commentaires

MemCy (B, A, 4 * Taille de taille (int) . ou Tailleof (B) .



12
votes

Pour comprendre la différence, nous devons comprendre deux contextes différents em>.

  • dans la valeur em> les contextes, le nom d'un tableau de type t code> est équivalent à un pointeur pour taper t code> et est égal à un pointeur sur le premier élément de la matrice. LI>
  • dans Objet em> Contexts, le nom d'un tableau de type t code> ne diminue pas à un pointeur. LI> ul>

    Quel est le contexte de l'objet? p>

    dans A = B; code>, A code> est dans le contexte de l'objet. Lorsque vous avez pris l'adresse d'une variable, elle est utilisée dans le contexte de l'objet. Enfin, lorsque vous utilisez Tailleof code> Opérateur sur une variable, il est utilisé dans le contexte de l'objet. Dans tous les autres cas, une variable est utilisée dans le contexte de la valeur. P>

    Maintenant que nous avons cette connaissance, lorsque nous le faisons: p> xxx pré>

    c'est Exactement em> équivalent à p> xxx pré>

    Comme vous l'avez découvert, nous pouvons omettre la taille (4 ci-dessus) de la déclaration de fonction. Cela signifie que vous ne pouvez pas connaître la taille de la "matrice" transmise à f () code>. Plus tard, lorsque vous faites: p> xxx pré>

    dans l'appel de la fonction, le nom A code> est dans le contexte de la valeur, de sorte qu'il réduit à un pointeur sur INT code>. C'est bon, car f code> attend un pointeur à un int code>, donc la définition de la fonction et l'utilisation correspondance. Ce qui est transmis à f () code> est le pointeur sur le premier élément de A code> ( et a [0] code>). P>

    Dans le cas de p> xxx pré>

    Le nom B code> est utilisé dans un contexte d'objet et ne réduit pas à un pointeur. (Incidemment, A code> ici est em> dans un contexte de valeur et réduit à un pointeur.) P>

    maintenant, int b [4]; code> attribue la valeur de stockage de 4 int code> s et donne le nom B code>. A code> a également été attribué un stockage similaire. Donc, en effet, le moyen d'affectation ci-dessus signifie "Je veux rendre l'emplacement de stockage identique à l'emplacement précédent". Cela n'a pas de sens. P>

    si vous voulez copier em> le contenu de a code> dans b code>, alors vous pouviez faire: p> xxx pré>

    ou, si vous vouliez un pointeur b code> qui pointe vers a code>: p>

    int a[4] = {1, 2};
    



1
votes

Pour obtenir votre intuition à ce sujet, vous devez comprendre ce qui se passe au niveau de la machine.

La sémantique d'initialisation (= {1,2,3,4}) signifie "Mettez-le sur votre image binaire exactement de cette façon" afin que cela puisse être compilé.

L'affectation du tableau serait différente: le compilateur devrait le traduire en boucle, ce qui serait réellement itérer sur des éléments. C compilateur (ou c ++, pour cette affaire) ne fait jamais une telle chose. Cela s'attend légitimement que vous le faites vous-même. Pourquoi? Parce que vous pouvez. Donc, il devrait être un sous-programme, écrit en C (memcpy). Tout cela concerne la simplicité et la proximité de votre arme, qui est C et C ++.


0 commentaires

0
votes

Notez que le type de a in int A [4] est int [4] .

mais type de ( & a ) == int (*) [4] ! = int [4]

Notez également que le type de la valeur de A est int * , qui est distinct de tout ce qui précède! < P> Voici un exemple de programme que vous pouvez essayer: xxx


1 commentaires

Vous devez utiliser "% zu" pour imprimer Taille_T (en C99).



0
votes

Je veux clarifier. Il y a quelques astuces trompeuses dans les réponses ... toutes les fonctions suivantes peuvent prendre des tableaux entier: xxx pré>

mais arguments formels strong> ne sont pas les mêmes. Donc, le compilateur peut les gérer différemment. Dans le sens de la gestion de la mémoire interne, tous les arguments mènent à des pointeurs. P> xxx pré>

... f () prend une matrice de toutes tailles. P>

void f(int *arr)


0 commentaires