Laissez-moi vous expliquer avec un exemple –
#include void foo( int a[2], int b[2] ) // I understand that, comstackr doesn't bother about the // array index and converts them to int *a, int *b { a = b ; // At this point, how ever assignment operation is valid. } int main() { int a[] = { 1,2 }; int b[] = { 3,4 }; foo( a, b ); a = b; // Why is this invalid here. return 0; }
Est-ce parce que, tableau passe à un pointeur lorsqu’il est passé à une fonction foo(..)
, l’opération d’affectation est possible. Et main
, est-ce parce qu’ils sont de type int[]
ce qui invalide l’opération d’affectation. A a,b
dans les deux cas ne signifient-ils pas la même chose? Merci.
Modifier 1:
Lorsque je le fais dans une fonction foo
, il assigne l’emplacement de l’élément de départ b's
à a
. Donc, en termes de ce qui précède, ce qui a empêché les développeurs de langage de faire la même chose dans main()
. Voulez-vous connaître la raison.
Vous avez répondu à votre propre question.
Parce que ces
int a[] = { 1,2 }; int b[] = { 3,4 };
avoir le type de int[2]
. Mais ceux-ci
void foo( int a[2], int b[2] )
avoir le type de int*
.
Vous pouvez copier des pointeurs mais pas des tableaux.
La réponse est dans le concept “passer par valeur”, ce qui signifie que la fonction appelée reçoit des copies des arguments – qui sont des pointeurs sur les ints. Ainsi, a
et b
sont des copies locales de ces pointeurs (qui n’existent pas dans l’appelant; ils sont le résultat de conversions à partir des tableaux, c’est-à-dire les adresses de leurs premiers éléments). Ce ne serait pas différent si vous écriviez
void foo( int aparam[2], int bparam[2] ) { int* a = aparam; int* b = bparam; a = b ; }
Dennis Ritchie a reconnu que la syntaxe de tableau pour les parameters est une verrue sur le langage et n’était là que pour faciliter la conversion des programmes B – l’histoire ancienne! Cela a également eu un effet néfaste sur la conception de C ++, car les tableaux ne peuvent pas être passés par valeur. Cette syntaxe est une source constante de confusion. Alors … ne l’utilisez pas ; prétendre que ce n’est pas légal. Si tout le monde fait cela, cela peut disparaître et peut-être qu’une sémantique appropriée pourra être donnée dans quelques décennies.
Mise à jour : pour plus d’informations sur l’appel par valeur (la seule forme d’appel en C et Java; voir mes commentaires ci-dessous), l’appel par référence (ajouté en C ++) et d’autres stratégies d’évaluation, voir http: // en .wikipedia.org / wiki / Evaluation_strategy
Dans la fonction principale
a et b sont des pointeurs constants. En réalité, ils sont l’adresse des premiers éléments. Ils sont comme l-valeur. vous ne pouvez pas copier vers la valeur l, mais vous pouvez modifier la valeur des entiers vers lesquels elles pointent.
Dans la fonction foo
a et b sont des pointeurs. afin que vous puissiez changer leurs valeurs.