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 

typedef, array, pointer

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





PostPosted: Thu Apr 15, 2004 10:10 am    Post subject: typedef, array, pointer Reply with quote



Hallo,
ich habe eine kleine Verständnisfrage und ich hoffe,
dass Ihr's mir erklärt.

Habe folgenden Code:

typedef RGB_Structure TRGBArray[100]; //Zeile 1
typedef TRGBArray* PRGBArray; //Zeile 2
....
PRGBArray pLine=new TRGBArray[100]; //Zeile 3
pLine[99]->... //Zeile 4

Warum muss ich in Zeile 3 die Arraygröße nochmal
explizit angeben? Das habe ich doch schon in
Zeile 1 getan... Kann ich es irgendwie vermeiden,
die Arraygröße ein 2. Mal angeben zu müssen?
--
Viele Grüße,
Stephan Collet

--
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
Horst Kraemer
Guest





PostPosted: Fri Apr 16, 2004 3:50 am    Post subject: Re: typedef, array, pointer Reply with quote



On Thu, 15 Apr 2004 12:10:45 +0200, "SteCol" <stecol (AT) gmx (DOT) de> wrote:

Quote:
Hallo,
ich habe eine kleine Verständnisfrage und ich hoffe,
dass Ihr's mir erklärt.

Bauernregel 1: Definiere nie ein Array-Typedef. Du machst Dich
ungluecklich.

Quote:
Habe folgenden Code:

typedef RGB_Structure TRGBArray[100]; //Zeile 1
typedef TRGBArray* PRGBArray; //Zeile 2
...
PRGBArray pLine=new TRGBArray[100]; //Zeile 3

Hier legst Du dynamisch ein Array von 100 Arrays von RGB_Structure an,
Die von Dir angegebenen 100 hat mit der 100 im typedef nichts zu tun.

Quote:
pLine[99]->... //Zeile 4

Ich vermute, dass Du gar kein "Zeiger auf Array" willst, sondern dass
Du nur ein Array von 100 RGB_Structure dynamisch anlegen moechtest.
Dazu musst Du keinen Zeiger auf Arraytyp, sondern nur schlicht einen
Zeiger auf den Elementtyp des Arrays anlegen.

RGB_Structure *pLine = new TRGBArray;

pLine[99].R = 4711;

delete [] TRGBArray;

Hier ist ein [] noetig, obwohl im new kein [] zu sehen ist: das [] im
new wird durch die typedefs-Syntax versteckt.

Arrays zusammen mit typedefs und new sind tueckisch, da die Syntax
nicht das wiedergibt, was der Programmierer erwarten mag.

Wenn Du schreibst

new tBla;

und tBla ist ein Typ, erwartest Du, dass new tBla ein Objekt vom Typ
tBla anlegt und einen "Zeiger auf tBla" zurueckgibt, Nicht so bei
Array-Typedefs als "Typ". Dein

new TRGBArray;

entpricht

new RRG_Structure[100];

und dies liefert synataktisch eine Zeiger auf RGB_Strcuture, der auf
das erste Elemente eines danymisch angelegten namenlosen Arrays von
100 RGB_Structure zeigt - und *nicht* einen Zeiger auf Array von 100
RRG-Structure. D.h. die [100] im new gehoert nicht zum Typ, sondern
modifiziert nur die Anzahl der Elemente, die angelegt werden, sondern
gehoert effektiv zum 'new'. Der eigentliche Typ des new ist der Typ
des Arrayelements. Wie Du siehst, reisst das new die Semantik des
typedefs auseinander und damit ist die Syntax new Arrray-Typedef
"sinnentstellend". Daher meine oben erwaehnte Bauernregel ;-)

Um das zu bekommen, was Deinem Zeigertyp entspricht, koenntest Du z.B.

PRGBArray pLine=new TRGBArray[1]; //Zeile 3

sagen. Damit erstellst Du dynamisch ein zweidimensionales Array

PRGBArray pLine=new RGB_Structure[1][100];

und Du kannst mit der Syntax

(*pLine)[3].R = 4711;

oder mit der perversen Syntax

pLine[0][3].R = 4711;

auf die Arrayelemente zugreifen. Aber ich vermute, dass Du das gar
nicht willst, es sei denn Du moechtest


Quote:
Warum muss ich in Zeile 3 die Arraygröße nochmal
explizit angeben?

Wie Du siehst, wiederholst Du damit nicht die Arraygroesse, sondern
legst ein Array von 100 TRGBArrays an. Der Zeiger auf das erste
Element eines zweidimensionalen Arrays[100][100] von RGB_Structure ist
ein Zeiger auf Array von 100 RGB_Structure, als ein Zeiger auf
TRGBArray - wie gewuenscht ;-)

--
Horst

--
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
Albrecht Fritzsche
Guest





PostPosted: Fri Apr 16, 2004 5:13 pm    Post subject: Re: typedef, array, pointer Reply with quote



Horst Kraemer wrote:

Quote:
On Thu, 15 Apr 2004 12:10:45 +0200, "SteCol" <stecol (AT) gmx (DOT) de> wrote:


Hallo,
ich habe eine kleine Verständnisfrage und ich hoffe,
dass Ihr's mir erklärt.


Bauernregel 1: Definiere nie ein Array-Typedef. Du machst Dich
ungluecklich.

....


Bauernregel 0:
Verwende fuer dynamische Arrays stets std::vector.

(Ist jedefalls einfacher, kuerzer und eleganter!!!)

Ali

--
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
Albrecht Fritzsche
Guest





PostPosted: Fri Apr 16, 2004 5:18 pm    Post subject: Re: typedef, array, pointer Reply with quote

SteCol wrote:

Quote:
Hallo,
ich habe eine kleine Verständnisfrage und ich hoffe,
dass Ihr's mir erklärt.

Habe folgenden Code:

typedef RGB_Structure TRGBArray[100]; //Zeile 1
typedef TRGBArray* PRGBArray; //Zeile 2
...
PRGBArray pLine=new TRGBArray[100]; //Zeile 3
pLine[99]->... //Zeile 4

Warum muss ich in Zeile 3 die Arraygröße nochmal
explizit angeben? Das habe ich doch schon in
Zeile 1 getan... Kann ich es irgendwie vermeiden,
die Arraygröße ein 2. Mal angeben zu müssen?

typedef std::vector<RGB_Structure> RGB_Array;
RGB_Array line(100); // legt eine Array von 100 RGB_Structures an
line[99].r = 255; // oder so aehnlich

Dabei kommst Du ganz ohne Memory-Allokationen und -Freigaben aus.

Ali

--
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
SteCol
Guest





PostPosted: Fri Apr 16, 2004 6:15 pm    Post subject: Re: typedef, array, pointer Reply with quote

In Nachricht news:blju70la48lt7bu9ac12sp883vinu7uuqt (AT) 4ax (DOT) com,
Horst Kraemer <horst.kraemer (AT) epost (DOT) de> schrieb:

Hallo Horst,

Quote:
Bauernregel 1: Definiere nie ein Array-Typedef. Du machst
Dich ungluecklich.

Na das habe ich schon gemerkt, da es so wie ich dachte gar
nicht ging:

Hintergrund:

Ich wollte automatisch den "pLine" auf die Bytes einer
Bitmap zeigen lassen, da ich die mir aus Delphi liebgewonnene
Funktion "PRGBArray TBitmap.Scanline(x)" nachbilden wollte.
Aber ich hatte zuerst zu kompliziert gedacht und mich von
Delphi verleiten lassen.

Jetzt sieht das ganze so aus:

typedef struct RGB_StructureTag {
//Die Reihenfolge der Member ist wichtig
BYTE B;
BYTE G;
BYTE R;
} RGB_Structure;

typedef RGB_Structure* PRGBArray;

.....

PRGBArray AdvBitmap::scanLine(const unsigned int iLine) {

unsigned int iSum=(4-3*this->iWidth%4);
if (iSum==4) iSum=0;

/*Bitmap steht auf dem Kopf*/
const unsigned int iPos=
(this->iHeight-1-iLine)*(this->iWidth*3+iSum);

/*Pointer auf die Bitmapbytes aus der DIBSECTION holen*/
BYTE* pPos=(BYTE*)this->tDib.dsBm.bmBits;

/*Direkt auf den Speicher der Bitmap zugreifen
und ins RGB-Triple casten*/
PRGBArray pLine=((PRGBArray)(&pPos[iPos]));

return pLine;
}

....

Zugriff geht dann so:

PRGBArray pLine;

for (unsigned int y=0; y<this->iHeight; y++) {
pLine=scanLine(y);
for (unsigned int x=0; x<this->iWidth; x++) {
pLine[x].R=...
...
}
}

Es widerspricht zwar der OOP direkt auf dem Speicher zu
arbeiten (bekomme ja so lesenden und schreibenden Zugriff
und kann über die Grenzen hinaus), aber dafür ist es schön
performant (So wie es sein soll).

[Erklärung abgeschnitten]

Quote:
Wie Du siehst, wiederholst Du damit nicht die Arraygroesse,
sondern legst ein Array von 100 TRGBArrays an.

Yep, das war's. Ich habe mich auch schon über den enormen
Speicherverbrauch gewundert und meine Kist so ewig langsam
wurde... ;-)

Vielen Dank für Deine Erklärungen, ich werde mich an Zukunft an
die Bauernregel 1 halten!

Sag mal, Horst, hattest Du mir nicht schonmal bei meinem
Tetraederproblem Ende 2002 in de.sci.mathematik geholfen? Langsam
bin ich Dir eine gute Flasche Wein schuldig!
--
Viele Grüße,
Stephan Collet

--
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.