C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

UNTERSCHIED: int *v[5] und int (*v)[5] als Parameter in Fu

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Ernst Barner
Guest





PostPosted: Wed Nov 05, 2003 5:27 pm    Post subject: UNTERSCHIED: int *v[5] und int (*v)[5] als Parameter in Fu Reply with quote



Hallo allerseits,
es sind folgende zwei Funktionen gegeben und definiert:

void f1(int (*v)[5])
{
....
}

void f2(int *v[5])
{
....
}

1)
Was ist (an einem möglichst einfachen Beispiel erklärt) der
Unterschied zwischen den beiden Parametern
int (*v)[5]
und
int *v[5]

2)
*Wie* kann man anhand der Syntax erkennen, was genau jeweils
int (*v)[5]
bzw.
int *v[5]
bewirkt ?

Gibt es dazu eine Regel, die mir sagt, was dies genau bedeutet ?

3)
Bei
void g(int *i)
ist mir das klar:
Der Inhalt von i muss ein Integer-Wert sein.
Also ist der Parameter in der Funktion g eine Adresse, die auf einen
Integer-Wert zeigt.
Leider blicke ich überhaupt nicht durch, wie man aber
int (*v)[5]
bzw.
int *v[5]
interpretieren soll, bzw. wie man dazu vorgeht ?

mfg
Ernst

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Thomas Maeder
Guest





PostPosted: Wed Nov 05, 2003 7:40 pm    Post subject: Re: UNTERSCHIED: int *v[5] und int (*v)[5] als Parameter i Reply with quote



Ernst Barner <carlox (AT) web (DOT) de> writes:

Quote:
Was ist (an einem möglichst einfachen Beispiel erklärt) der
Unterschied zwischen den beiden Parametern
int (*v)[5]
und
int *v[5]

Ich erklär's einfach mal in Deutsch:

int (*v)[5] deklariert v als ein Zeiger auf ein Array von 5 int.

int *v[5] deklariert v als ein Array von 5 Zeigern auf int.



Quote:
2)
*Wie* kann man anhand der Syntax erkennen, was genau jeweils
int (*v)[5]
bzw.
int *v[5]
bewirkt ?

Ich verstehe die Frage nicht.


Quote:
Gibt es dazu eine Regel, die mir sagt, was dies genau bedeutet ?

Von innen nach aussen lesen, wobei innen dort ist, wo der deklarierte Name
steht.


Quote:
3)
Bei
void g(int *i)
ist mir das klar:
Der Inhalt von i muss ein Integer-Wert sein.

Den Terminus Inhalt habe ich in diesem Kontext noch nie gehört. i ist ein
Zeiger auf int, das Ding, wo i drauf zeigt, ist also ein int (wenn i nicht
gerade ==0 oder ungültig ist).


Quote:
Also ist der Parameter in der Funktion g eine Adresse, die auf einen
Integer-Wert zeigt.

Vielleicht. i kann auch ==0 sein oder "ins Schilf" zeigen.

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Heinz Saathoff
Guest





PostPosted: Thu Nov 06, 2003 8:19 am    Post subject: Re: UNTERSCHIED: int *v[5] und int (*v)[5] als Parameter i Reply with quote



Hallo Ernst,

zusätzlich zur Antwort von Thomas:
Quote:
2)
*Wie* kann man anhand der Syntax erkennen, was genau jeweils
int (*v)[5]
bzw.
int *v[5]
bewirkt ?

Gibt es dazu eine Regel, die mir sagt, was dies genau bedeutet ?

Es hängt mit der Bindungspriorität der Operatoren zusammen. Der Array
Operator [] hat eine höhere Priorität als der Pointer Operator *
Es ist so, wie Du's auch von den arithmetischen Operatoren für Addition
und Multiplikation erwarten wirst.
Wenn man sich dann die Definition
int *v[5];
ansieht, stellt man, ausgehend vom Namen v fest, dass [] stärker als *
ist. Also muß v ein Array mit 5 Elementen sein. Reduziert man jetzt den
Rest im Kopf zu
int *va; // va steht für das Array
dann haben wir jetzt ein Array von Pointern. Das weiter reduziert zu
int vap;
sagt uns jetzt, dass vap ein Array von Pointern auf int ist.

Beim 2. Beispiel geht's auch so:
int (*v)[5];
Die Rangfolge wird jetzt durch die Klammern geändert. Damit bindet der *
jetzt zuerst und es ergibt sich die Reduktion zu
int vp[5]; // vp steht für v ist pointer auf
Da jetzt erst [] bindet, ergibt sich die Reduktion zu
int vpa; // vpa ist pointer auf array
Damit ergibt sich letztlich, daß vpa ein pointer auf ein Array von int
ist.


- Heinz

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Ernst Barner
Guest





PostPosted: Fri Nov 07, 2003 8:57 am    Post subject: Re: UNTERSCHIED: int *v[5] und int (*v)[5] als Parameter i Reply with quote

Quote:

Gibt es dazu eine Regel, die mir sagt, was dies genau bedeutet ?

Es hängt mit der Bindungspriorität der Operatoren zusammen. Der Array
Operator [] hat eine höhere Priorität als der Pointer Operator *
Es ist so, wie Du's auch von den arithmetischen Operatoren für Addition
und Multiplikation erwarten wirst.
Wenn man sich dann die Definition
int *v[5];
ansieht, stellt man, ausgehend vom Namen v fest, dass [] stärker als *
ist. Also muß v ein Array mit 5 Elementen sein. Reduziert man jetzt den
Rest im Kopf zu
int *va; // va steht für das Array
dann haben wir jetzt ein Array von Pointern.

1)

Diese Schluss ist mir nicht klar.
Könnte man nicht auch folgendes aus
int *v[5];
schliessen:

v[5] ist ein Array.
Dann muss *v[5] ein Pointer auf ein *Array* sein !
Warum ist diese Schlussweise von mir falsch, bzw. wie heisst die
Regel, die deine Schlussfolgerung korrekt werden lässt ?

2)
Wie muss man dann folgendes auffassen ?
int *((*v)[5])[6]
int (*(*v[5]))[7]

3)
Kannst du mir noch andere schwierige "Kombinationen" angeben ?

mfg
Ernst

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Karl Heinz Buchegger
Guest





PostPosted: Fri Nov 07, 2003 10:23 am    Post subject: Re: UNTERSCHIED: int *v[5] und int (*v)[5] als Parameter i Reply with quote



Ernst Barner wrote:
Quote:


Gibt es dazu eine Regel, die mir sagt, was dies genau bedeutet ?

Es hängt mit der Bindungspriorität der Operatoren zusammen. Der Array
Operator [] hat eine höhere Priorität als der Pointer Operator *
Es ist so, wie Du's auch von den arithmetischen Operatoren für Addition
und Multiplikation erwarten wirst.
Wenn man sich dann die Definition
int *v[5];
ansieht, stellt man, ausgehend vom Namen v fest, dass [] stärker als *
ist. Also muß v ein Array mit 5 Elementen sein. Reduziert man jetzt den
Rest im Kopf zu
int *va; // va steht für das Array
dann haben wir jetzt ein Array von Pointern.

1)
Diese Schluss ist mir nicht klar.
Könnte man nicht auch folgendes aus
int *v[5];
schliessen:

v[5] ist ein Array.
Dann muss *v[5] ein Pointer auf ein *Array* sein !
Warum ist diese Schlussweise von mir falsch, bzw. wie heisst die
Regel, die deine Schlussfolgerung korrekt werden lässt ?

Wie Heinz schon sagte: Bindungsprioritaet. [] bindet staerker als *
Das ist aber nur relevant wenn Du eine Deklaration basteln musst
und du rausfinden musst, wo denn nun Klammern hinmuessen.
Zum Lesen einer Deklaration benutzt man die Rechts/Links Regeln
(siehe Link weiter unten)

v[5] ist ein Array
*v[5] ist ein Array von Pointer
int *v[5] ist ein Array von Pointer auf int

In der 'textuellen Langschreibweise' kannst Du immer nur an den bisherigen
Satz was dranhaengen

Quote:

2)
Wie muss man dann folgendes auffassen ?
int *((*v)[5])[6]
int (*(*v[5]))[7]


http://www.ericgiguere.com/articles/reading-c-declarations.html
(Algorithmus fuer die Rechts-Links Regel)

Quote:
int *((*v)[5])[6]

v v is
v) v is
*v) v is a pointer to
(*v) v is a pointer to
(*v)[5] v is a pointer to array with size 5
(*v)[5]) v is a pointer to array with size 5
((*v)[5]) v is a pointer to array with size 5
((*v)[5])[6] v is a pointer to array with size 5 of array size 6
*((*v)[5])[6] v is a pointer to array with size 5 of array size 6 of pointer to
int *((*v)[5])[6] v is a pointer to array with size 5 of array size 6 of pointer to int

Die andere Deklaration:
Folge den Anweisungen auf der Web-Seite :-)

Quote:
3)
Kannst du mir noch andere schwierige "Kombinationen" angeben ?

Bau mal ein paar Funktionspointer mit rein :-)

--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Christoph Horst
Guest





PostPosted: Fri Nov 07, 2003 11:44 am    Post subject: Re: UNTERSCHIED: int *v[5] und int (*v)[5] als Parameter i Reply with quote

Quoth Karl Heinz Buchegger:
Quote:
http://www.ericgiguere.com/articles/reading-c-declarations.html
(Algorithmus fuer die Rechts-Links Regel)

int *((*v)[5])[6]

Sinnvoller finde ich persönlich die "Declaration-looks-like-use"-Regel:

v wird, wenn es in einem Ausdruck verwendet wird, der dem auf der rechten
Seite ähnelt, den Typ int ergeben. Man kann den Deklarator jetzt genauso
auflösen, wie man einen Ausdruck auswertet, d.h. indem man auf die
Operatorrangfolge zurückgreift:

*v v kann dereferenziert werden, ist also ein Pointer
(*v)[5] *v kann indiziert werden, ist also ein Array
=> v ist Zeiger auf Array 5
((*v)[5])[6] ein Element dieses Array kann wiederum indiziert werden, ist
also selbst wieder ein Array.
=> v ist Zeiger auf Array 5 von Array 6
(die Klammern sind hier übrigens überflüssig, (*v)[5][6]
reicht aus.)
*(*v)[5][6] das ganze kann wiederum dereferenziert werden, dh ein Element
des 6er Arrays ist ein Zeiger
=> v ist Zeiger auf Array 5 von Array 6, welches Zeiger enthält

Die aufeinanderfolgenden Schritte ergeben sich durch die jeweilige
Operatorenrangfolge. Damit hätten wir den Deklarator aufgeschlüsselt.
Der Typ, den dieser ganze Ausdruck haben soll, sollte int sein. Das heißt,
v wird als

Zeiger auf Array 5 von Array 6, welches Zeiger auf int enhält

deklariert. Diese Regel stammt aus dem alten Testament (K&R) und wurde
inzwischen etwas verwässert, z.B. durch const/volatile-Qualifier oder
Referenzen, aber wenn man sie einmal verstanden hat, dürften sich dadurch
keine neuen Schwierigkeiten ergeben. Dass ich durch diese Regel ein
Klammerpaar eliminieren konnte seh ich mal als Hinweis darauf, dass sie dem
Rechts-Links-Algorithmus überlegen ist ;-)

-- Christoph

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Thomas Belger
Guest





PostPosted: Fri Nov 07, 2003 4:46 pm    Post subject: Re: UNTERSCHIED: int *v[5] und int (*v)[5] als Parameter i Reply with quote

Ernst Barner <carlox (AT) web (DOT) de> writes:

Hallo,

Quote:
Wie muss man dann folgendes auffassen ?
int *((*v)[5])[6]
int (*(*v[5]))[7]

da gibt es noch ein nettes tool: cdecl
es liefert für die obigen fälle:

int *((*v)[5])[6]
declare v as pointer to array[5] of array[6] of pointer to int;

int (*(*v[5]))[7]
declare v as array[5] of pointer to pointer to array[7] of int;


Quote:
3)
Kannst du mir noch andere schwierige "Kombinationen" angeben ?

mit cundecl kannst du dir selber welche ausdenken:

aus:
cast f into pointer to function (int) returning void;
wird:
(void (*)(int))f;


Viele Grüße,
Thomas

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Rolf Magnus
Guest





PostPosted: Sat Nov 08, 2003 12:22 pm    Post subject: Re: UNTERSCHIED: int *v[5] und int (*v)[5] als Parameter i Reply with quote

Thomas Maeder wrote:

Quote:
Ernst Barner <carlox (AT) web (DOT) de> writes:

Was ist (an einem möglichst einfachen Beispiel erklärt) der
Unterschied zwischen den beiden Parametern
int (*v)[5]
und
int *v[5]

Ich erklär's einfach mal in Deutsch:

int (*v)[5] deklariert v als ein Zeiger auf ein Array von 5 int.

int *v[5] deklariert v als ein Array von 5 Zeigern auf int.



2)
*Wie* kann man anhand der Syntax erkennen, was genau jeweils
int (*v)[5]
bzw.
int *v[5]
bewirkt ?

Ich verstehe die Frage nicht.


Gibt es dazu eine Regel, die mir sagt, was dies genau bedeutet ?

Von innen nach aussen lesen, wobei innen dort ist, wo der deklarierte
Name steht.


3)
Bei
void g(int *i)
ist mir das klar:
Der Inhalt von i muss ein Integer-Wert sein.

Den Terminus Inhalt habe ich in diesem Kontext noch nie gehört.

So habe ich das auch gelernt. Inhalt der Speicherstelle, auf die i
zeigt. Wenn ich also "x = *i;" schreibe, steht das * für Inhalt. Es
würde also sowas wie "x wird der Inhalt der Speicherstelle, auf die i
zeigt, zugewiesen", und da das etwas lang ist, sagt man einfach "x wird
Inhalt-x zugewiesen". Scheint nicht weit verbreitet zu sein, aber so
wurde mir das beigebracht, als ich mit Programmierung angefangen habe,
und damit ist das bei mir "eingebrannt" :-)

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Ernst Barner
Guest





PostPosted: Sun Nov 09, 2003 4:55 pm    Post subject: Re: UNTERSCHIED: int *v[5] und int (*v)[5] als Parameter i Reply with quote

Quote:

Sinnvoller finde ich persönlich die "Declaration-looks-like-use"-Regel:

v wird, wenn es in einem Ausdruck verwendet wird, der dem auf der rechten
Seite ähnelt, den Typ int ergeben.

Ich glaube zwar, dich verstanden zu haben, aber was meinst du

*konkret* damit an einem Besipiel (z.B. mit der "der dem auf der
rechten Seite ähnelt") ?

Ich habe das so verstanden. An einem Beispiel:
int *(*v)[5][6];
ergibt z.B. folgende mögliche Anweisung:
*(*v)[1][2] = 13;
1)
(*v)[1] ist das 1. Element eines Array mit Länge 5.
*v ist also ein Array.
Also zeigt v auf ein Array der Länge 5.
2)
((*v)[1])[2] ist das 2. Element eines Array der Länge 6.
Also zeigt v auf ein Array der Länge 5, dessen Elemente wiederum
Arrays der Länge 6 sind.
3)
*(*v)[1][2] ist das 2. Element eines Array der Länge 6. Dieses Element
zeigt auf einen Integer-Wert.
Also zeigt v auf ein Array der Länge 5, dessen Elemente wiederum
Arrays der Länge 6 sind und jeweils auf Integer-Werte zeigen.

mfg
Ernst

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Christoph Horst
Guest





PostPosted: Mon Nov 10, 2003 6:24 pm    Post subject: Re: UNTERSCHIED: int *v[5] und int (*v)[5] als Parameter i Reply with quote

Quoth Ernst Barner:
Quote:
Ich glaube zwar, dich verstanden zu haben, aber was meinst du
*konkret* damit an einem Besipiel (z.B. mit der "der dem auf der
rechten Seite ähnelt") ?

Ich denke, du hast es verstanden:

Quote:
int *(*v)[5][6];

Also zeigt v auf ein Array der Länge 5, dessen Elemente wiederum
Arrays der Länge 6 sind und jeweils auf Integer-Werte zeigen.

Und wenn das so ist, kann ich folgende Anweisung schreiben:

int i = *(*v)[0][0];

in der der Initialisierer offensichtlich bis auf die Array-Indizes mit der
Deklaration von v übereinstimmt.

-- Christoph

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.