it-swarm.dev

Was ist ein moderner Begriff für "Array/Zeiger-Äquivalenz"

Fast jeder, der dies liest, kennt wahrscheinlich die drei wichtigsten Fakten über C:

  1. Wenn Sie den Namen eines Arrays in einem Ausdruck erwähnen, wertet es (meistens) einen Zeiger auf das erste Element des Arrays aus.
  2. Der Operator "array subscripting" [] funktioniert für Zeiger genauso gut wie für Arrays.
  3. Ein Funktionsparameter, der ein Array zu sein scheint, deklariert tatsächlich einen Zeiger.

Diese drei Fakten sind absolut zentral für die Array- und Pointer-Behandlung in C. Sie sind nicht einmal drei Fakten. Sie sind miteinander verbundene Facetten eines zentralen Konzepts. Es ist nicht möglich, auch nur eine grundlegende C-Programmierung ohne ein anständiges Verständnis dieses Konzepts richtig durchzuführen.

Meine heutige Frage lautet einfach: Wie heißt dieses Konzept?

Ich nehme an, ich bin altmodisch, aber ich habe es immer "Die Äquivalenz zwischen Arrays und Zeigern in C" oder "Array/Zeiger-Äquivalenz" genannt. Aber ich habe gelernt, dass man diese Wörter auf SO fast nicht sagen kann; Sie sind ziemlich tabu. 

Dies mag wie eine abstrakte oder philosophische Frage erscheinen, und um es konkreter zu fassen: Ich suche nach einer einfachen Nominal- oder Nominalphrase, die ich in dem Satz verwenden könnte: "Ja, aufgrund von _____ kann Array-Indexierung gedacht werden als syntaktischer Zucker für die Zeigerarithmetik ", etwa auf diese Frage .

(Beachten Sie jedoch, dass ich nicht nach Antworten auf diese Frage suche oder nach Antworten auf die Frage "Was stimmt nicht mit dem Wort" Äquivalenz "?". Ja, ich weiß, es kann die Lernenden dazu bringen, sich vorzustellen dass Arrays und Zeiger irgendwie gleich sind. Ich hatte diese Verwirrung im Sinn, als ich diesen FAQ Listeneintrag schrieb.)

38
Steve Summit
  1. Der Operator "array subscripting" [] funktioniert für Zeiger genauso gut wie für Arrays.

Nein, eigentlich funktioniert es nur für Zeiger. Immer wenn Sie [] in einen Ausdruck eingeben, erhalten Sie immer einen Zeiger auf das erste Element. Dies ist garantiert, da arr[i] äquivalent zu *(arr + i) sein muss. Ersteres ist "syntaktischer Zucker" für letzteres. 

  1. Ein Funktionsparameter, der ein Array zu sein scheint, deklariert tatsächlich einen Zeiger.

Dies ist eigentlich ein Sonderfall, der als "Array-Anpassung" bezeichnet wird, in dem der Compiler die Deklaration eines Funktionsparameters vom Array-Typ implizit in einen Zeiger auf das erste Element ändert. Der Grund ist sicher, Funktionen so zu gestalten, dass sie mit dem "Array Decay" von Ausdrücken kompatibel sind, aber der C-Standard hält die Begriffe getrennt.

Beide Fälle, Ausdrücke und Funktionsparameter, werden oft informell als "Array Decay" bezeichnet. Manchmal wird dies jedoch nur für Ausdrücke und nicht für Funktionsparameter verwendet. Ich glaube nicht, dass es eine einheitliche Verwendung des Begriffs gibt. "Array Decay" ist meiner Meinung nach das beste, obwohl der C-Standard diesen Begriff nirgendwo verwendet.


(Ich mag den Begriff "Äquivalenz" nicht, weil ein Array sich in einen Zeiger verwandeln kann, aber nicht umgekehrt. In der Tat gibt es unzählige Anfänger, die verwirrte Überzeugungen wie "Arrays und Zeiger sind das Gleiche".). Äquivalent "hilft nicht gerade.)

26
Lundin

Der C-Standard hat dafür kein einziges Wort. Es verwendet das Wort "Konvertierung" bei der Definition des Verhaltens (1) in 6.3.2.1p3, "gleichwertig" bei der Definition des Verhaltens (2) in 6.5.2.1p2 und "Anpassung" bei der Definition des Verhaltens (3) in 6.7.6.3p7.

Ich bin altmodisch und glaube nicht, dass es falsch ist, diese "Array/Zeiger-Äquivalenz" zu nennen, vorausgesetzt, es ist klar, dass Sie über Ausdrücke sprechen, bei denen (1) oder Funktionsdeklarationen bei (3) auftreten. Eine schmackhaftere Bezeichnung für die Leute, die "Äquivalenz" nicht mögen, wäre vielleicht "Array-to-Pointer-Konvertierung", da dies die Leute am häufigsten verwirrt, wenn (1), denke ich.

13
zwol

Ich würde mit dem Begriff Array Decay gehen. Dieser Begriff passt gut zu dem, was er suggeriert. Der C-Standard sagt in diesem Zusammenhang nichts darüber aus und ja, am ersten Tag, als ich den Begriff hörte, den ich für die Suche im Standard suchte, konnte ich ihn nicht finden. Alternativ kann man auch schreiben, weil"das meiste Szenario Array in Zeiger umgewandelt wird" ...- Nein, dies ist kein einzelnes Noun. Dies lässt jedoch keine Fehlinterpretation zu. Standard selbst sagt es die "Konvertierung". 

Meistens versuche ich es lange zu sagen und dann das Wort ("Array Decaying") in Klammer zu setzen. In der Tat gibt es Antworten, bei denen ich es nicht einmal erwähnt habe und nur mit den Standardwörtern der-Umwandlung in den Zeigerging. 

9
coderredoc

Ich schlage vor, "Array-to-Pointer-Decay" ist eine vernünftige Abkürzung, da "Decay" Ein üblicher Jargon ist, wenn auf die Typkonvertierung Bezug genommen wird, an anderer Stelle in der C-FAQ: Frage 6.12 :

F: Da Array-Referenzen in Zeiger zerfallen, ist .__ wenn arr ein Array ist. Was ist der Unterschied zwischen arr und & arr?

Eine erweiterte technische Bedeutung von "decay", die diesen enthält, wurde Seit C++ 11 in die C++ - Standardbibliothek aufgenommen: std::decay

5
Mike Kinghan

Es gibt keinen einzigen Namen für die drei genannten Konzepte, aber ich denke, es ist kontraproduktiv, wenn man sie als "Äquivalenz" bezeichnet, zumindest wenn man "modernes" C beschreibt. Die Ergebnisse des Array-Zerfalls verhalten sich im Allgemeinen wie Zeiger. C99 gibt an, dass die durch Array-Zerfall hervorgerufenen Zeiger sich nicht auf dieselbe Weise verhalten müssen wie Zeiger, die auf andere Weise erzielt werden. Gegeben:

char fetch_byte_at(void *p, int x) { return ((char*)p)[x]; }

struct {char arr[5][7];} s;
char test1(int x) { return s.arr[0][x]; }
char test2(int x) { return fetch_byte_at(&s, x); }

der Standard gibt keinen Grund an, weshalb der in s.arr[0] verwendete Zeigerwert test1 nicht mit dem Zeigerwert ((char*)(void*)s) übereinstimmen sollte, der verwendet wird, wenn fetch_byte_at von test2 aufgerufen wird. Dies impliziert jedoch gleichzeitig, dass test2 in der Lage sein sollte, alle Bytes von s auszulesen [was bedeutet, dass es mit Werten von x bis mindestens 34 vorhersehbar arbeiten sollte], wobei s.arr[0][x] nur für Werte von x von Bedeutung ist 6.

Während nichts im Standard einem Ihrer ersten beiden Punkte einzeln widersprechen würde, können beide nicht halten. Entweder ist das Ergebnis eines Array-Zerfalls etwas anderes als ein "normaler" Zeiger auf das erste Element des Arrays, oder das Anwenden des []-Operators auf ein Array hat eine andere Semantik als das Anwenden eines Arrays auf einen Zeiger. Während unklar ist, welche von # 1 und # 2 durch C99 ungültig gemacht wurde, bilden sie im modernen C. keine Art von "Äquivalenz" mehr.

Wenn Sie eine Unterscheidung zwischen traditionellem C und "modernem" C erkennen, kann es nützlich sein, Begriffe für die Dinge festzulegen, die das erstere nützlich machen. Solche Dinge gehen jedoch über die Punkte hinaus, die Sie erwähnen. Ich kenne leider keine Standardbegriffe für solche Dinge und würde nicht nach dem Standard suchen, der eine solche Terminologie bereitstellt, wenn er die betreffenden Konzepte nicht mehr unterstützt.

5
supercat

Danke an alle. Ich verwende diese "Antwort", um die Antworten der Leute und meine Einschätzung zusammenzufassen, nicht als richtige Antwort, von der ich erwarte, dass irgendjemand irgendetwas befürwortet.

Viele Leute haben ernsthaft über diese Frage nachgedacht, und ich weiß das zu schätzen. Aber an dieser Stelle kann ich nur zu dem Schluss kommen, dass ich zumindest heute keine Antwort auf meine Frage habe.

Nicht wenige Leute schlugen "Array Decay" vor, und das ist eine sehr schöne Einstellung, aber bei mir funktioniert das nicht. Sie bezieht sich meist auf Fakt 1 und möglicherweise auf Fakt 3, wie in der ursprünglichen Frage aufgeführt, aber nicht wirklich Fakt 2. Sie können nicht sagen: "Ja, aufgrund von Array-Zerfall kann Array-Subskription als syntaktischer Zucker für die Zeigerarithmetik betrachtet werden." (Zumindest können Sie dies nicht sagen, wenn Ihre Absicht klar und aufschlussreich sein soll.) Sie müssten etwas sagen wie: "Ja", aufgrund von Array-Zerfall und der Art und Weise, wie die Zeigerarithmetik definiert wird Englisch: emagazine.credit-suisse.com/app/art ... = 118 & lang = en Array - Subskriptionen können als syntaktischer Zucker für die Zeigerarithmetik verstanden werden, was durchaus ein ganz anderer Fisch ist.

Obwohl ich das nicht ausdrücklich gesagt habe, suchte ich nach einem gemeinsamen, weit verbreiteten, akzeptierten Gebrauch, obwohl es nicht erforderlich war, dass es sich um Wörter handelt, die im Standard verwendet werden. In Anbetracht der Tatsache, dass niemand einen solchen Begriff ausspuckte, da alle mit einer gewissen Spekulation und "Was ist mit ...?" Beschäftigt waren, komme ich zu dem Schluss, dass es keinen einheitlichen Begriff für das Konzept des Trios des verwandten Trios gibt Fakten. (Anders als "Äquivalenz", was ausgeschlossen ist.)

Eine Reihe von Antwortern und Kommentatoren haben dies auf verschiedene Weise gesagt (dass es keine Antwort gibt). Ich werde weitermachen und Lundins Antwort auf dieser Grundlage akzeptieren, und weil andere es anscheinend am besten gefallen haben.

Ich könnte in der Zukunft versuchen, "Die Entsprechung zwischen Arrays und Zeigern in C" zu verwenden, um zu sehen, ob es ankommt. Arrays und Zeiger sind so verschieden wie Männer und Frauen, und zwar ziemlich weit auseinander, aber sie tauschen häufig Briefe. :-)

2
Steve Summit

Dies mag wie eine abstrakte oder philosophische Frage erscheinen, und um es konkreter zu fassen: Ich suche nach einem einfachen Substantiv oder Nominalphrase. Ich könnte den Satz verwenden: "Ja, aufgrund von _____ kann eine Array-Subskription als gedacht werden syntaktischer Zucker für die Zeigerarithmetik ", als Antwort auf diese Frage.

Die gesuchte Phrase lautet "Ja, da Array-Subskription Zeigerarithmetik unter der Haube ist, kann Array-Subskription als syntaktischer Zucker für die Zeigerarithmetik betrachtet werden."

Das ist natürlich dumm, denn der Grund dafür, dass das Abonnement von Arrays syntaktischer Zucker für die Zeigerarithmetik ist, ist, dass es genau das ist, was es ist. Es bedarf keiner weiteren Erklärung, es sei denn, die Person, die Sie dies sagen, weiß nicht, was ' Array-Subskription ',' Zeigerarithmetik 'oder' syntaktischer Zucker 'bedeuten. Dies bedeutet nicht, dass der Compiler den Unterschied zwischen den beiden nicht kennt (er ist es, weil er derjenige ist, der für den gesamten syntaktischen Zucker verantwortlich ist, den Sie als Ergebnis davon erhalten).

Dieselbe Frage könnte für alles, was jede Sprache für uns tut, aufgeworfen werden, was wir selbst tun könnten, indem eine höhere Anzahl von Anweisungen auf niedrigerer Ebene verwendet wird und daher auf sie unter Verwendung mehrerer Begriffe zurückgegriffen werden kann, die nur die Menge an verwendetem syntaktischem Zucker verändern. Es geht nicht darum, so zu tun, als wären sie anders (sie sind immer im Weg, aber darum geht es nicht), sondern um das Programmieren zu erleichtern (denken Sie nur daran, Code zu schreiben, ohne den Operator [] als syntaktischen Zucker für die Zeigerarithmetik und Sie erkennen schnell den Grund für seine Existenz - nicht weil es anders ist, sondern weil es einfacher ist, zu schreiben, zu lesen und zu verwalten.

(Beachten Sie jedoch, dass ich nicht nach Antworten auf diese Frage suche oder nach Antworten auf die Frage "Was ist los mit dem Wort" Gleichwertigkeit "?"). Ja, ich weiß, es kann die Lernenden dazu verleiten, sich vorzustellen, dass Arrays und Zeiger irgendwie sind das gleiche. Ich hatte das vor Augen, als ich diesen Listeneintrag FAQ schrieb.)

Ihre Frage scheint zu sein "Was ist ein moderner Begriff für Array-Zeiger-Äquivalenz in dem Sinne, dass Array-Subskription nur syntaktischer Zucker für Zeigerarithmetik ist?"

Die Antwort ist:

  1. "Array-Subskription", wenn Sie mit dem Operator [] ein Array indizieren.
  2. "Zeigerarithmetik", wenn Sie einen Zeiger manuell verschieben (im Gegensatz zur Verwendung des Operators []). Sie haben vielleicht auch den Eindruck, dass Sie diesen Begriff für alle Berechnungen verwenden, die Sie für den Wert, den Sie dem [] - Operator geben, tun, aber Sie führen dort keine Zeigerarithmetik aus, sondern "Berechnen eines Index", was der Ausdruck für die Syntax ist Zucker von der Größe der Objekte im Speicher automatisch für Sie berücksichtigt werden (was wiederum nicht anders ist, nur einfacher zu schreiben, zu lesen und zu verwalten, also: syntaktischer Zucker).
1
pie

Dies ist eine subtile Frage. Beim Durchsuchen eines englischen Thesaurus und eines Wörterbuchs kam ich zu dem Ergebnis, dass der Begriff Gleichheit für Ihren Kontext geeignet sein könnte.

Nach der Definition des Online-Wörterbuchs von Oxford wird das Wort Similar definiert als:

eine Ähnlichkeit in Aussehen, Charakter oder Menge aufweisen, ohne identisch zu sein.

und das Wort Similitude als:

die Qualität oder der Zustand, etwas ähnlich zu sein.

Da Arrays und Zeiger nicht identisch sind, aber manchmal ähnlich behandelt werden, könnte man sagen:

Ja, aufgrund von Array/Pointer Gleichheit kann die Subskription von Arrays als syntaktischer Zucker für die Pointer-Arithmetik angesehen werden. "

1
machine_1

Ich stimme zu, dass Begriffe wie "Zeiger/Array-Äquivalenz" oder "Array-Zerfall" (in einen Zeiger) ungenau sind und sehr irreführend sein können.

Ich würde folgendes vorschlagen:

Zugriff auf ein Array mit dem Operator [] mit einem Index hat einen äquivalenten Zeigerarithmetikausdruck. Es gibt jedoch keine Äquivalenz zwischen einem Zeiger und einem Array: Ich kann den Wert eines Zeigers (Inhalt) gerne ändern, um vielleicht einen separaten Iterationszähler zu speichern, aber ich kann das nicht mit dem "verfallenen" Array tun. Es ist unveränderlich und zeigt in gewisser Hinsicht ein ähnliches Verhalten wie C++ - Referenzen.

Die beiden Verben "to decay" und "to convert" bedeuten im Englischen immer, dass das Original im Prozess verändert wird. Wenn Sie den Namen eines Arrays oder den unären '&' - Operator verwenden, ändern Sie den Operanden nicht.

Ein Ausdruck wie "ergibt einen Zeiger" oder "erzeugt einen Zeiger" wäre daher genauer. Dies spiegelt sich in der Tatsache wider, dass der resultierende Zeiger in beiden Fällen eine temporäre Sache ist, die (normalerweise) in einem GP-Register der CPU sitzt und kann nicht zugewiesen werden.

Zumindest ist das mein Verständnis, der Blick auf Disassemblies scheint das zu bestätigen.

0
GermanNerd

Standard verwendet den Begriff konvertiert in. Äquivalenz von Arrays und Zeigern ist immer noch besser als Array decay auf Zeiger. Standard erwähnen diesen Begriff nicht wo, aber es ist nur ein gegenseitiges Verständnis zwischen Programmierern, dass im Zusammenhang mit Arrays und Zeigern die Äquivalenz von Arrays und Zeigern verstanden wird. Und was Zeiger- und Array-Äquivalenz bedeutet: Zeigerarithmetik und Array-Indizierung [das] ist in C gleichwertig, Zeiger und Arrays sind unterschiedlich.

0
haccks