vorbei typedef (Feste Größe) array als Wert
Ich bin schwer zu verstehen typedef
Muster für arrays.
typedef char Char10[10];
void fun (Char10 a) //not passing reference (interested in pass by value)
{
if(typeid(Char10) == typeid(char*))
throw 0; //<--- never happens
}
int main ()
{
char a[10]; fun(a); //ok
char b[11]; fun(b); //why works ?
}
Warum die unterschiedlichen Größen der array als Wert akzeptiert fun()
? Sind char[10]
und char[11]
nicht verschiedene Arten ?
Bearbeiten: Für diejenigen, die sagt, es zerfällt zu Zeiger, siehe meinen bearbeiteten code. char[10]
und char*
scheint nicht zu passen.
- Wenn Menschen sagen, dass "array zerfällt zu" pointer " Sie beziehen sich auf parameter
a
specifially. Also, in Ihremif
innerhalb der Funktion sollen Sie zu vergleichentypeid(a) == typeid(char*)
. Dies wird Ihnen zeigen, dass die Typen übereinstimmen. Vergleichentypeid(Char10) == typeid(char*)
nicht alles zeigen. Diese sind in der Tat unterschiedliche Typen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sie sind verschiedene Arten, du hast Recht.
Es ist eine irreführende Eigenart von C++, die Sie gesehen werden können, die eine Funktion haben
Da Sie nicht das übergeben von arrays per Wert, und C++ ist dumm, das ist eigentlich die Funktion
Und, natürlich, die beiden Eingänge abbauen glücklich zu
char*
.Schön wäre es, wenn C++ nicht lassen Sie sogar so tun, um zu akzeptieren ein array als Wert, aber es ist dumm, in dieser Weise.. geerbt von C.
fun(char*)
, weil Empfangs-array per Referenz erlaubt es nurchar[10]
und Irrtümer fürchar[11]
.void f(int(&)[3]);
können Sie nicht einen Zeiger übergeben, das ist wahr. Aber in diesem Fall, Sie können.In beiden Fällen werden die arrays, die Zerfall auf den Zeiger-Typ, und Ihre Funktion ist eigentlich dies:
Deshalb ist seine Arbeit.
Möchte ich betonen, dass
void fun(char*)
ist genau das gleiche wievoid fun(char[10])
. Die10
macht keinen Unterschied. In der Tat10
ist so unwichtig und nutzlos, die kann man auch weglassen, es komplett als:Das bedeutet, alle die folgenden Deklarationen sind genau gleiche:
Hoffe, dass klärt Ihre Zweifel.
Jedoch, wenn Sie dies schreiben:
dann tatsächlich dieses:
Dann
fun(b)
würde nicht kompilieren, wie jetztfun
NUR akzeptieren array von GENAU der Größe 10. Und das array wird nicht Zerfall zu Zeiger, es wird weitergegeben, indem Referenz.void fun(char*)
.Char10
undchar*
gibt ja verschiedene Arten..Versuchen
Online-demo
P. S:
Die folgenden Deklarationen sind äquivalent
Wenn erhalten Sie einen array-parameter, die der compiler versteht Sie als ein Zeiger auf das array das erste element. Da gibt es keinen Unterschied zwischen arrays unterschiedlicher Größe zur Laufzeit. Das ist, warum Sie müssen wissen, die Größe, die Sie arbeiten mit, um zu vermeiden, den Zugriff auf Speicher, der gehört nicht zu Ihrem Programm..
Für Ihre edit: die Typen per se sind unterschiedlich, aber in C++ kann nicht übergeben werden ein array-Wert als argument an eine Funktion, und die array-Typ zerfällt der entsprechende Zeiger geben, wenn Sie es als eine Funktion argument.
Diese Ausgänge
Weil
char *
undchar[10]
sind verschiedene Arten;test
ist einchar[10]
a
ist eigentlich einchar *
, weil in Funktionsdeklarationen die array Deklaration zerfällt der entsprechende Zeiger-Deklaration.Dies ist eine dumme Sache, die hier aus historischen Gründen, aber wir sind dabei geblieben.
Gefunden in der standard: bei §8.3.5 ¶3:
struct
/class
lassen Sie er als Wert übergeben werden (Dank der Tatsache, dassstruct
s kann durch Wert übergeben werden, und der default-Konstruktor Verhalten zu kopieren-Mitglieder). Dies ist, wie die neuestd::array
Feste Größe-low-overhead-container funktioniert.Können Sie akzeptiert jedoch eine Referenz auf ein array der richtigen Größe, an welcher Stelle der compiler wird - Objekt zu.
Können Sie nicht übergeben, array nach Wert weder in C noch in C++. Arrays in C/C++ sind nicht kopierbar, also unabhängig davon, was Sie tun, werden Sie nie erreichen "pass by value" Semantik mit array-Typ.
Sieht es aus wie Sie hofften, dass das verstecken der array-Typ hinter einem typedef-name wird lassen Sie diese Einschränkung umgehen. Es nicht. Ihre
Erklärung entspricht
Erklärung, welche wiederum äquivalent zu
und
So, Ihr
a
parameter hat den Typ Zeiger. Wenn Sie ein array übergeben, wie dassind Sie einfach nur die übergabe eines
char *
Zeiger auf das erste element des Arrays. Die Größe des Arrays spielt keine Rolle, die ist, warum Sie sind in der Lage, arrays zu übergeben, in verschiedenen Größen mit dieser Methode.Innerhalb der
fun
Funktion, wenn Sie möchten, analysieren Sie die Art des Parametersa
sollen Sie geltentypeid
zua
Dies wird Ihnen zeigen, dass die Typen übereinstimmen. Warum Sie sich bewerben die
typeid
direkt zuChar10
und was Sie erwarten, zu leiten daraus ist mir nicht klar. Array-Typen decay Zeiger-Typen in der Funktion parameter-Erklärung, aber Sie nicht Verfall zu Zeiger-Typen intyped
- operator, was bedeutet, dass Ihre version vonif
ist absolut nichts was passiert in der parameter-Deklaration.Char10
undchar*
sind verschiedene Arten. Versuchen Vergleich Art dera
undchar*
wie ich erwähnt habe in meinem Beitrag.typeid(a)
.Können Sie emulieren vorbei fixed-size-arrays durch Wert wie diese.