gert wrote:
> T_TEST_TBL xTestTbl[] = {> {1, (T_TEST *)&xTestA},> {2, (T_TEST *)&xTestB}> }
Die Typecasts sind überflüssig.
> wie kann ich nun zb. in einer schleife strlen von cTest aller elemente> von xTestTbl ausgeben, dh:
Gar nicht. Du hast Tabellen dynamischer Größe, hast aber weder deren
Länge irgendwo festgehalten noch ein Endekennzeichen in jeder Tabelle
hinterlassen. Damit kann man beim Blick ,,von oben'' nicht mehr
wissen, auf wie viele Tabellenelemente der jeweilige Zeiger nun wirklich
zeigt.
p.s.: Bitte Code-Markierungen benutzen.
>ist compiler/sdk spezifisch
warum sollte das so sein? C ist C, das muß erst einmal jeder Compiler
gleich verstehen.
Mich stört zwar das Komma am Ende von "{"12345"},", aber den Compiler
anscheinend nicht. Funktionieren sollte die erste Variante auch.
Ich hab hiermit ein Problem:
1
T_TEST_TBLxTestTbl[]={
2
{1,(T_TEST*)&xTestA},
3
{2,(T_TEST*)&xTestB}
4
}
&xTestA ist KEIN T_TEST*, sondern ein T_TEST**, deshalb hast du wohl
auch die (eigentlich überflüssigen) Typecasts eingefügt. Gemeint ist
wohl:
Oliver wrote:
> &xTestA ist KEIN T_TEST*, sondern ein T_TEST**
Nein, die Adresse eines Arrays ist die Adresse seines ersten Elements.
Überflüssig ist das & natürlich trotzdem, und es deutet darauf hin,
dass derjenige, der es geschrieben hat, die ganze Pointer&Array-
Geschichte noch nicht verstanden hat, sondern trial&error benutzt.
ich habs eh ohne cast gemacht, es war nur zuerst das const drinnen und
der compiler hat bei der initialisierung natürlich gemeckert (looses
const qualifier)
gert wrote:
> looses const qualifier
Ja zu Recht! Und anstatt deinen Fehler zu beheben, benutzt du die
Allzweckwaffe Cast um die Symptome zu vertuschen. TZTZTZ!
>> &xTestA ist KEIN T_TEST*, sondern ein T_TEST**>> Nein, die Adresse eines Arrays ist die Adresse seines ersten> Elements.
Der numerische Wert von &xTestA und xTestA ist zwar der gleiche, der
Datentyp aber ein anderer:
xTestA ist ein T_TEST-Array und somit vom Typ T_TEST[] bzw. T_TEST[1].
Es kann verwendet werden wie ein konstanter Zeiger auf das erste
Element, also wie ein T_TEST*.
&xTestA hingegen ist ein Zeiger auf ein T_TEST-Array (nicht auf das
erste Element) und somit vom Typ T_TEST(*)[] bzw. T_TEST(*)[1]. Für
diesen Datentyp gibt es im vorliegenden Programm aber keine sinnvolle
Verwendung.
Und damit du das const nicht weg-casten musst (was übrigens
programmiertechnisch eine ziemliche Schweinerei ist!), musst du folgende
Definition ändern:
1
typedefstruct{
2
UCHARucKey;
3
constT_TEST*pTest;/* Zeiger auf ein konstantes T_TEST */
Moment mal... xTestA ist doch ein Array (T_TEST*), also steht in xTestA
die Adresse des ersten Elementes des Arrays.
Um den Wert dieses Elementes zu ändern kann ich
*xTestA oder xTestA[0] benutzen.
Wenn ich &xTestA schreibe bekomme ich die Adresse des Zeigers, der auf
die Adresse des ersten Elementes des Arrays zeigt.. also durchaus ein
T_TEST**
Oder hab ich da was nicht ganz verstanden?
> Moment mal... xTestA ist doch ein Array
Bis hierher ist es richtig.
> (T_TEST*),
T_TEST* ist kein Array, sondern ein Zeiger. Array-Variablen können
zwar in vielen Kontexten wie Zeiger benutzt werden, trotzdem sind das
zwei unterschiedliche Dinge. So hat bspw. ein Zeiger die Größe einer
Adresse auf dem Zielsystem, die Größe eines Arrays hängt von der
Anzahl und der Größe der Elemente ab. Einer Zeigervariable kann
ein Wert zugewiesen werden, einer Arrayvariable nicht (nur deren
Elementen).
> also steht in xTestA die Adresse des ersten Elementes des Arrays.
Nein, in xTestA stehen die Arrayemelente. Erst wenn man bspw. p=xTestA
schreibt, wird xTestA durch die Adresse des ersten Elements ersetzt
und p zugewiesen.
> Um den Wert dieses Elementes zu ändern kann ich *xTestA oder> xTestA[0] benutzen.
Richtig.
> Wenn ich &xTestA schreibe bekomme ich die Adresse des Zeigers, der> auf die Adresse des ersten Elementes des Arrays zeigt.. also> durchaus ein T_TEST**
Nein, das ist einer der Fälle, wo xTestA nicht durch einen Zeiger
auf das erste Elemente ersetzt wird, sondern ein Array bleibt. Somit
ist &xTestA kein Zeiger auf einen Zeiger das erste Element (T_TEST**),
sondern ein Zeiger auf das ganze Array(T_TEST(*)[] oder T_TEST(*[1]).
Wie schon oben geschrieben sind diese beiden Zeiger numerisch
natürlich gleich, trotzdem sind es aber zwei unterschiedliche
Datentypen.
> Oder hab ich da was nicht ganz verstanden?
Jetzt hoffentlich schon ;-)
Ah ja, diese Sonderrolle der statischen Arrays war mir nicht bewusst.
Ich dachte bis jetzt immer, dass "int a[5];" dazu führt, dass ein
konstanter Zeiger auf ein Integer mit dem Namen a angelegt wird, 5 mal
ein Integer im Speicher reserviert wird und die Adresse des ersten
Integers in a gespeichert wird.
Also so wie man es dynamisch machen würde, nur dass halt der Compiler
die Arbeit erledigt.
Man lernt nie aus, danke yalu!
Ganz durchdacht finde ich die Sache dann allerdings nicht. Wenn es hier
also eh einen eigenen Datentypen gibt und sizeof(a) sogar die komplette
Arraygröße zurückliefert, dann hätte man doch in die Compiler auch noch
eine Bereichsprüfung für den [] Operator einbauen können, so dass bei
statischen Arrays eben a[5] = ... nicht mehr möglich ist.
A. N. wrote:
> Ganz durchdacht finde ich die Sache dann allerdings nicht. Wenn es hier> also eh einen eigenen Datentypen gibt und sizeof(a) sogar die komplette> Arraygröße zurückliefert, dann hätte man doch in die Compiler auch noch> eine Bereichsprüfung für den [] Operator einbauen können, so dass bei> statischen Arrays eben a[5] = ... nicht mehr möglich ist.
C besitzt von der Sprachdefinition einfach mal kein Laufzeitsystem,
was derartige Überprüfungen hergeben könnte (anders als bspw. Pascal).
Allerdings verbietet der Standard einer Implementierung nicht, ein
derartiges Feature anzubieten. Es wird nur in der Regel nicht gemacht,
weil es einfach Performance kostet.
Ja das zur Laufzeit ist mir schon klar, aber wenigstens bei
offensichtlichen Bereichsüberschreitungen müsste der Compiler beim
Compelieren meckern.
z.B.
a[5] = 1;
bei nur 5 Elementen im Array.
Aber egal, hier ging es ja um ein anderes Thema :)