Hallo alle zusammen, ich habe ein Anfängerproblem und hoffentlich kann
mehr jemand von euch helfen.
Ich habe eine Struktur, besser gesagt einen Zeiger darauf:
1
channel_t*pchn
nun muss ich aus verschiedenen Umständen heraus die Daten dieser
Struktur, oder besser gesagt Teile davon, in eine andere Struktur
kopieren.
Ich schreibe in C und weiß, dass es Anfängersachen sind, doch im Netz
finde ich kein passendes Beispiel dafür und mein Buch ist zu ungenau.
Danke
Scarface wrote:
> // So war es eigentlich gemein>> int i;> channel_t *newp;>>> for(i = 0; i < SIZEOF(channel_t);i++)> {> *(newp+1) = *(pchn+i);> }
Ist trotzdem Käse
* die Idee dahinter mag noch angehen, ist aber unnötig kompliziert
* das funktioniert so nicht.
Hausaufgabe: Was wird durch newp + 1 adressiert?
Was wird durch newp + i adressiert?
(Hinweis: Es ist nicht das i-te Byte der Struktur)
Und ausserdem reden wir alle an der Frage des OP vorbei:
> nun muss ich aus verschiedenen Umständen heraus die Daten> dieser Struktur, oder besser gesagt Teile davon
Teile davon.
1
typedefstruct{
2
intWertA;
3
intWertB;
4
intWertC;
5
charWertD;
6
doubleWertE;
7
charText[20];
8
}channel_t;
9
10
11
...
12
13
channel_t*pchn;
14
channel_tcopy;
15
16
...
17
18
copy.WertB=pchn->WertB;
19
copy.WertD=pchn->WertD;
20
strcpy(copy.Text,pchn->Text);
> und mein Buch ist zu ungenau.
Dann schmeiss es weg und kauf dir ein besseres :-)
Das sind wirklich Basics.
>
Jetzt muesste vom OP eigentlich eine Frage kommen.
Ich nehm sie mal vorweg, weil mein Compilerlauf im
Hintergrund zuende geht und ich dann wieder an die
Arbeit muss.
Die Frage lautet:
Warum greift man einmal mit einem . und das andere mal
wieder mit einem -> auf Strukturelemente zu?
Nun. Grundsätzlich kann man immer mit einem . auf ein
Strukturelement zugreifen.
copy.WertB
nur ist pchn ein Pointer, und dieser Pointer muss dereferenziert
werden, damit man an die Daten kommt auf die der Pointer zeigt.
Wie immer wird ein Pointer mit einem vorangestellten * derferenziert:
*pchn.WertB
Jetzt gibt es da aber ein Problem: Die Operatorenpriorität in C
wurde so festgelegt, dass . eine höhere Priorität hat als ein *
Das heist aber auch, der Compiler sieht den letzten Ausdruck
als:
*(pchn.WertB)
und das kann klarerweise nicht funktionieren, weil pchn ja ein
Pointer ist und ein Pointer hat nun mal keinen WertB. Man
muesste das also so schreiben:
(*pchn).WertB
und in der Tat ist das die korrekte Syntax.
pchn Nimm den Pointer
*pchn dereferenziere ihn (das bringt uns zu Struktur)
(*pchn).WertB und aus der Struktur wähle den Member WertB
Nur: Das ist eine grausliche Syntax und schlecht zu tippen.
Daher hat man die Syntax um das 'Zeichen' -> erweitert.
a->b <==> (*a).b
> Hausaufgabe: Was wird durch newp + 1 adressiert?
> Was wird durch newp + i adressiert?
> (Hinweis: Es ist nicht das i-te Byte der Struktur)
newp + 1 sollte newp + i heissen.
nein. Es ist nicht das i-te Byte sondern das (i-1)-te Byte der Struktur.
---> Deshalb auch die Abfrage i < size und nicht i >= size...
Scarface wrote:
>> Hausaufgabe: Was wird durch newp + 1 adressiert?> > Was wird durch newp + i adressiert?> > (Hinweis: Es ist nicht das i-te Byte der Struktur)>> newp + 1 sollte newp + i heissen.>> nein. Es ist nicht das i-te Byte sondern das (i-1)-te Byte der Struktur.> ---> Deshalb auch die Abfrage i < size und nicht i >= size...
Ist es nicht.
Du wärst gut beraten in einem Buch deiner Wahl über Pointerarithmetik
und wie das mit dem konkreten Pointertyp zusammenhängt nachzulesen.
>Ist es nicht.>Du wärst gut beraten in einem Buch deiner Wahl über Pointerarithmetik>und wie das mit dem konkreten Pointertyp zusammenhängt nachzulesen.
Wie so soll es nicht das (i-1)-te byte sein, bzw welches soll es denn
sonst sein? Ich habe eine Adresse, in newp gespeichert, welcher ich ein
offset hinzufüge, i, und mit * auf den Wert in dieser Adresse
verweise...
>Ist es nicht.>Du wärst gut beraten in einem Buch deiner Wahl über Pointerarithmetik>und wie das mit dem konkreten Pointertyp zusammenhängt nachzulesen.
Wie so soll es nicht das (i-1)-te byte sein, bzw welches soll es denn
sonst sein? Ich habe eine Adresse, in newp gespeichert, welcher ich ein
offset hinzufüge, i, und mit * auf den Wert in dieser Adresse
verweise...
Und ja, Pointerarithmetik habe ich nachgelesen, sollte stimmen.
Angenommen, Deine Struktur sei 0x10 Bytes groß.
channel_t *newp;
Dieser Pointer zeige nun auf eine Struktur an der Adresse 0x2000.
Wohin zeigt dann (newp + 1)?
NEIN, es zeigt NICHT auf die Adresse 0x2001, sondern auf die Adresse
0x2010.
Scarface wrote:
> wieso nicht?
:-)
Weil sonst die ganze Arrayindizierung, so wie sie in C definiert
ist nicht mehr funktionieren würde.
datatyp * pPtr;
*( pPtr + Offset ) <==>
*( (unsigned char*)pPtr + ( Offset * sizeof( datatyp ) ) ) <==>
pPtr[Offset]
Mit anderen Worten
channel_t * pPtr;
*(pPtr + 4) liefert dir die Daten der 5. Struktur deren
Anfangsadresse bei pPtr liegt. Ist also äquivalent zu
pPtr[4]
(Wenn den das worauf pPtr zeigen würde auch wirklich ein
Array aus channel_t Objekten wäre)
Daten der '5. Struktur', nicht das 5. Byte
Was du wolltest, müsstest du so schreiben:
Scarface wrote:
> NEIN! newp repräsentiert eine Adresse, und diese wird um eins erhöht,>> Ausführlicher beschrieben:>> int x;>> x = newp;> newp = x+1;
Sorry für die rüden Worte.
Aber das ist Bullshit. Pointerarithmetik funktioniert nicht so
in C.
Ja, stimmt, das Typecasting ist mir irgendwie entfallen, auf meinen
DSP's verwende ich eigentlich nur longs, da 32 Bit, daher bin ich dem
Problem noch nie begegnet. Aber danke, doch noch was sinnvolles gelernt
heute...