Ich habe eine Funktion geschrieben, die ein Array als Argument enthält, und sie aufgerufen, indem ich den Wert des Arrays wie folgt übergeben habe.
void arraytest(int a[])
{
// changed the array a
a[0]=a[0]+a[1];
a[1]=a[0]-a[1];
a[0]=a[0]-a[1];
}
void main()
{
int arr[]={1,2};
printf("%d \t %d",arr[0],arr[1]);
arraytest(arr);
printf("\n After calling fun arr contains: %d\t %d",arr[0],arr[1]);
}
Was ich gefunden habe, ist, dass ich die arraytest()
Funktion aufrufe, indem ich Werte übergebe, die Originalkopie vonint arr[]
geändert aufrufe.
Können Sie bitte erklären, warum?
c
arrays
function
parameters
parameter-passing
Mohan Mahajan
quelle
quelle
main()
muss zurückkehrenint
.Antworten:
Wenn Sie ein Array als Parameter übergeben, ist dies
void arraytest(int a[])
bedeutet genau das gleiche wie
void arraytest(int *a)
so Sie sind Modifizieren der Werte in main.
Aus historischen Gründen sind Arrays keine erstklassigen Bürger und können nicht wertmäßig weitergegeben werden.
quelle
struct
der Sprache hinzugefügt wurde, wurde dies geändert. Und dann wurde es als zu spät angesehen, die Regeln für Arrays zu ändern. Es gab bereits 10 Benutzer. :-)void arraytest(int a[1000])
usw. usw. Erweiterte Antwort hier: stackoverflow.com/a/51527502/4561887 .Wenn Sie ein eindimensionales Array als Argument in einer Funktion übergeben möchten, müssen Sie einen formalen Parameter auf eine der folgenden drei Arten deklarieren. Alle drei Deklarationsmethoden führen zu ähnlichen Ergebnissen, da jeder dem Compiler mitteilt, dass ein ganzzahliger Zeiger ausgeführt wird empfangen werden .
int func(int arr[], ...){ . . . } int func(int arr[SIZE], ...){ . . . } int func(int* arr, ...){ . . . }
Sie ändern also die ursprünglichen Werte.
Vielen Dank !!!
quelle
Sie übergeben das Array nicht als Kopie. Es ist nur ein Zeiger, der auf die Adresse zeigt, an der sich das erste Element des Arrays im Speicher befindet.
quelle
Sie übergeben die Adresse des ersten Elements des Arrays
quelle
Arrays in C werden in den meisten Fällen in einen Zeiger auf das erste Element des Arrays selbst konvertiert. Und detailliertere Arrays, die an Funktionen übergeben werden, werden immer in Zeiger konvertiert.
Hier ein Zitat von K & R2nd :
Schreiben:
void arraytest(int a[])
hat die gleiche Bedeutung wie das Schreiben:
void arraytest(int *a)
Obwohl Sie es nicht explizit schreiben, ist es so, als würden Sie einen Zeiger übergeben und die Werte im Main ändern.
Weiter Ich schlage vor , das Lesen wirklich diese .
Darüber hinaus können Sie andere Antworten SO finden auf hier
quelle
Sie übergeben den Wert des Speicherorts des ersten Mitglieds des Arrays.
Wenn Sie also mit dem Ändern des Arrays innerhalb der Funktion beginnen, ändern Sie das ursprüngliche Array.
Denken Sie daran, das
a[1]
ist*(a+1)
.quelle
In C "zerfällt" eine Array-Referenz mit Ausnahme einiger Sonderfälle immer auf einen Zeiger auf das erste Element des Arrays. Daher ist es nicht möglich, ein Array "nach Wert" zu übergeben. Ein Array in einem Funktionsaufruf wird als Zeiger an die Funktion übergeben, was analog zum Übergeben des Arrays als Referenz ist.
BEARBEITEN: Es gibt drei solche Sonderfälle, in denen ein Array nicht in einen Zeiger auf sein erstes Element zerfällt:
sizeof a
ist nicht dasselbe wiesizeof (&a[0])
.&a
ist nicht dasselbe wie&(&a[0])
(und nicht ganz dasselbe wie&a[0]
).char b[] = "foo"
ist nicht dasselbe wiechar b[] = &("foo")
.quelle
int a[10]
und jedem Element einen zufälligen Wert zugewiesen. Wenn ich dieses Array nun mitint y[]
oderint y[10]
oder an eine Funktion übergebe, verwendeint *y
ich in dieser Funktion diesizeof(y)
Antwort. Der Bytezeiger wurde zugewiesen. In diesem Fall wird es als Zeiger verfallen. Es wäre hilfreich, wenn Sie dies auch einschließen. Siehe diese postimg.org/image/prhleuezdsizeof
operiere in der Funktion in dem ursprünglich definierten Array, dann wird es als Array zerfallen, aber wenn ich eine andere Funktion übergebe, dann wird dort dersizeof
Operator als Zeiger zerfallen.&a
nicht ganz das gleiche ist wie&a[0]
beia
einem Array. Wieso das? In meinem Testprogramm sind beide gleich, sowohl in der Funktion, in der das Array deklariert ist, als auch wenn sie an eine andere Funktion übergeben werden. 2. Der Autor schreibt, dass "char b[] = "foo"
nicht dasselbe ist wiechar b[] = &("foo")
". Letzteres kompiliert für mich nicht einmal. Ist es nur ichÜbergeben eines mehrdimensionalen Arrays als Argument an eine Funktion. Das Übergeben eines One-Dim-Arrays als Argument ist mehr oder weniger trivial. Werfen wir einen Blick auf einen interessanteren Fall, bei dem ein 2-Dim-Array übergeben wird. In C können Sie keinen Zeiger auf das Zeigerkonstrukt (
int **
) anstelle eines 2-Dim-Arrays verwenden. Machen wir ein Beispiel:void assignZeros(int(*arr)[5], const int rows) { for (int i = 0; i < rows; i++) { for (int j = 0; j < 5; j++) { *(*(arr + i) + j) = 0; // or equivalent assignment arr[i][j] = 0; } }
Hier habe ich eine Funktion angegeben, die als erstes Argument einen Zeiger auf ein Array von 5 Ganzzahlen verwendet. Ich kann als Argument jedes 2-Dim-Array mit 5 Spalten übergeben:
int arr1[1][5] int arr1[2][5] ... int arr1[20][5] ...
Möglicherweise kommen Sie auf die Idee, eine allgemeinere Funktion zu definieren, die ein beliebiges 2-Dim-Array akzeptieren und die Funktionssignatur wie folgt ändern kann:
void assignZeros(int ** arr, const int rows, const int cols) { for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { *(*(arr + i) + j) = 0; } } }
Dieser Code würde kompiliert, aber Sie erhalten einen Laufzeitfehler, wenn Sie versuchen, die Werte auf die gleiche Weise wie in der ersten Funktion zuzuweisen. In C sind mehrdimensionale Arrays also nicht dasselbe wie Zeiger auf Zeiger ... auf Zeiger. An
int(*arr)[5]
ist ein Zeiger auf ein Array von 5 Elementenint(*arr)[6]
ist ein Zeiger auf ein Array von 6 Elementen und sie sind ein Zeiger auf verschiedene Typen!Wie definiere ich Funktionsargumente für höhere Dimensionen? Einfach, wir folgen einfach dem Muster! Hier ist dieselbe Funktion, die für ein Array mit drei Dimensionen angepasst wurde:
void assignZeros2(int(*arr)[4][5], const int dim1, const int dim2, const int dim3) { for (int i = 0; i < dim1; i++) { for (int j = 0; j < dim2; j++) { for (int k = 0; k < dim3; k++) { *(*(*(arr + i) + j) + k) = 0; // or equivalent assignment arr[i][j][k] = 0; } } } }
Wie zu erwarten, können 3 dim-Arrays als Argument verwendet werden, die in der zweiten Dimension 4 Elemente und in der dritten Dimension 5 Elemente enthalten. So etwas wäre in Ordnung:
arr[1][4][5] arr[2][4][5] ... arr[10][4][5] ...
Wir müssen jedoch alle Abmessungen bis zur ersten angeben.
quelle
@ Bo Persson sagt in seiner großartigen Antwort hier richtig :
================================================
Wenn Sie ein Array als Parameter übergeben, ist dies
void arraytest(int a[])
bedeutet genau das gleiche wie
void arraytest(int *a)
================================================
Lassen Sie mich jedoch auch hinzufügen, dass es:
bedeutet genau das gleiche wie
void arraytest(int a[0])
was genau das gleiche bedeutet wie
void arraytest(int a[1])
was genau das gleiche bedeutet wie
void arraytest(int a[2])
was genau das gleiche bedeutet wie
void arraytest(int a[1000])
etc.
Tatsächlich dient der Wert "Größe" innerhalb des Array-Parameters anscheinend nur der Ästhetik / Selbstdokumentation und kann eine beliebige positive Ganzzahl (
size_t
Typ, glaube ich) sein!In der Praxis sollten Sie es jedoch verwenden, um die Mindestgröße des Arrays anzugeben, das die Funktion erhalten soll, damit Sie beim Schreiben von Code leicht nachverfolgen und überprüfen können. Der MISRA-C-2012- Standard ( kaufen / herunterladen Sie das PDF mit der 236-Seiten-Version 2012 des Standards für £ 15.00 hier ) geht so weit:
...
...
Mit anderen Worten, sie empfehlen die Verwendung des expliziten Größenformats, auch wenn der C-Standard dies technisch nicht erzwingt. Dies hilft Ihnen als Entwickler und anderen, die den Code verwenden, zumindest zu klären, welche Größenanordnung die Funktion erwartet Sie zu übergeben.
quelle
void arraytest(int (*a)[1000])
ist besser, weil dann der Compiler einen Fehler macht, wenn die Größe falsch ist.Arrays werden immer als Referenz übergeben, wenn Sie
a[]
oder verwenden*a
:int* printSquares(int a[], int size, int e[]) { for(int i = 0; i < size; i++) { e[i] = i * i; } return e; } int* printSquares(int *a, int size, int e[]) { for(int i = 0; i < size; i++) { e[i] = i * i; } return e; }
quelle