Bei folgendem Programm
#include <iostream>
using namespace std;
void foo( char a[100] )
{
cout << "foo() " << sizeof( a ) << endl;
}
int main()
{
char bar[100] = { 0 };
cout << "main() " << sizeof( bar ) << endl;
foo( bar );
return 0;
}
Ausgänge
main() 100
foo() 4
- Warum wird das Array als Zeiger auf das erste Element übergeben?
- Ist es ein Erbe von C?
- Was sagt die Norm?
- Warum wird die strikte Typsicherheit von C++ fallen gelassen?
Ja, es ist von C geerbt. Die Funktion:
void foo ( char a[100] );
Der Parameter wird so angepasst, dass er ein Zeiger ist, und wird so zu:
void foo ( char * a );
Wenn Sie möchten, dass der Array-Typ erhalten bleibt, sollten Sie eine Referenz auf das Array übergeben:
void foo ( char (&a)[100] );
C++ ’03 8.3.5/3:
…Der Typ einer Funktion wird anhand der folgenden Regeln bestimmt. Der Typ jedes Parameters wird von seinem eigenen decl-specifier-seq und declarator bestimmt. Nachdem der Typ jedes Parameters bestimmt wurde, wird jeder Parameter vom Typ „Array von T“ oder „Funktion, die T zurückgibt“ so angepasst, dass er „Zeiger auf T“ oder „Zeiger auf Funktion, die T zurückgibt“ ist.
Zur Erklärung der Syntax:
Suchen Sie in Google nach der “Rechts-Links”-Regel; Eine Beschreibung habe ich gefunden Hier.
Es würde auf dieses Beispiel ungefähr wie folgt angewendet werden:
void foo (char (&a)[100]);
Beginnen Sie bei der Kennung ‘a’
‘a’ ist ein
Gehe nach rechts – wir finden a )
Also kehren wir die Richtung um und suchen nach dem (
. Als wir uns nach links bewegen, passieren wir &
‘a’ ist eine Referenz
Nach dem &
Wir erreichen die Öffnung (
also kehren wir wieder um und schauen nach rechts. Wir sehen jetzt [100]
‘a’ ist ein Verweis auf ein Array von 100
Und wir kehren die Richtung wieder um, bis wir erreichen char
:
‘a’ ist ein Verweis auf ein Array von 100 Zeichen
Jawohl. In C und C++ können Sie keine Arrays an Funktionen übergeben. So ist es nun einmal.
Warum machst du überhaupt einfache Arrays? Hast Du Dir angesehen boost
/std::tr1::array
/std::array
oder std::vector
?
Beachten Sie, dass Sie jedoch eine Referenz auf ein Array beliebiger Länge an eine Funktion übergeben können Vorlage. Aus dem Kopf:
template< std::size_t N >
void f(char (&arr)[N])
{
std::cout << sizeof(arr) << '\n';
}
Es gibt ein großartiges Wort in der C/C++-Terminologie, das für statische Arrays und Funktionszeiger verwendet wird – Verfall. Betrachten Sie den folgenden Code:
int intArray[] = {1, 3, 5, 7, 11}; // static array of 5 ints
//...
void f(int a[]) {
// ...
}
// ...
f(intArray); // only pointer to the first array element is passed
int length = sizeof intArray/sizeof(int); // calculate intArray elements quantity (equals 5)
int ptrToIntSize = sizeof(*intArray); // calculate int * size on your system
Ich verwende in diesen Fällen immer std::array, vermeidet, dass ich mich mit solchen Problemen befassen muss, und funktioniert auch mit std-Algorithmen
– paulm
8. September 2014 um 9:39 Uhr
Welche strenge Art von Sicherheit? Wer hat strenge Typensicherheit versprochen? In C++ gibt es so etwas nicht.
– n. 1.8e9-wo-ist-meine-Aktie m.
8. September 2014 um 9:58 Uhr
TL; DR für die folgenden Antworten: Arrays werden zu Zeigern, wenn sie an die Funktion übergeben werden. Wenn Sie also ihre Größe überprüfen, erhalten Sie nur die Größe eines Zeigers. Wenn Sie nur mit C arbeiten, kann ich nur vorschlagen, dass Sie die Größe, die Sie aus dem Array herausholen möchten, als weiteren Parameter vorberechnen.
– Superkat
27. Dezember 2015 um 22:04 Uhr
Relevanter Linus-Rant
– Millie Smith
4. Dezember 2017 um 21:51 Uhr
Verwandt: Bestimmen Sie die Größe des Arrays, wenn es an die Funktion übergeben wird
– Gabriel Staples
24. September 2020 um 21:17 Uhr