Archiv verlassen und diese Seite im Standarddesign anzeigen : Pointer - endlich verstehen
Hallo zusammen!
Ich habe schon Pointer benutzt ohne sie je zu verstehen. Bisher habe ich solange rumgebastelt, bis alle Fehler-/Warnmeldungen weg waren. Jetzt habe ich aber ein Array und da hilft alles Basteln nichts mehr :-)
Meine Funktion:
int m3dmg_getOrientationMatrix( int16_t *M ) {
//UART Buffer auslesen
for ( int i=1 ; i <= 18 ; i=i+2 ) {
*M [i] = ( (int16_t) responseBuffer[i] << 8 | (int16_t) responseBuffer[i+1] );
}
return *M;
}
Meine Main:
int main(void) {
int16_t M[9];
...
int itest2=m3dmg_getOrientationMatrix( &M );
...
}
Error:
*M [i] =.....: invalid type argument of 'unary *' (have 'int16_t')
Warning:
int itest2=m3dmg_getOrientationMatrix( &M )...: passing argument 1 of 'm3dmg_getOrientationMatrix' from incompatible pointer type
M ist meine Transformationsmatrix, die ich in einer Unterfunktion einlese. Jetzt will ich das noch in meine Main weitergeben. Neben den Fehlermeldungen habe ich * und & mit denen ich nichts anfangen kann. Habe den starken Verdacht, dass ich gar nicht weiß was ich tue und das mache ich besonders gut :-)
Mein schickes C-Buch ist nicht für meine Gehirnwindungen gemacht worden.
Für Anmerkungen zum Thema und Lösungsvorschläge bin ich sehr dankbar.
Liebe Grüße!
emm
BurningWave
31.05.2010, 11:05
Also, mal ganz von vorne:
Ein Pointer ist ein Zeiger, der auf eine bestimmte Speicherstelle zeigt, man kann ihn neu zuweisen, also ihn auf eine andere Speicherstelle verweisen lassen und die Daten, die sich an der Speicherstelle, auf die er zeigt, befinden, manipulieren.
Hier mal ein Beispiel:
int i = 50; //i = 50
int *p = &i; //Zeiger p erstellen (*-Operator für Zeigerdekleration) und ihm die Adresse von i zuweisen (& ist der Adressoperator, mit ihm kommt man an die Adresse von i)
*p = 20; //i = 20, *p = 20 - *-Operator ist notwendig, da man dem Zeiger sonst eine neue Adresse zuweisen würde
int ii = 30;
p = ⅈ //*p = 30, ii = 30 - dem Zeiger eine neue Adresse (die von ii) zuweisen
p = NULL //den Zeiger, wenn er nicht mehr verwendet wird, auf NULL setzen
char acEinArray[256]; //Array mit 256 char-Elementen, Zugriff über z.B. acEinArray[50] = ...
char *p = acEinArray; //Zeiger p erstellen, der auf das Array zeigt (kein &-Operator, da acEinArray ohne []-Operator schon die Adresse ist!)
//p zeigt auf acEinArray[0], kann mit *p ausgelesen werden
p++; //p zeigt jetzt auf acEinArray[1]
So jetzt zu deinem Code:
*M [i] = ( (int16_t) responseBuffer[i] << 8 | (int16_t) responseBuffer[i+1] );
muss heißen:
M[i] = ( (int16_t) responseBuffer[i] << 8 | (int16_t) responseBuffer[i+1] );
da der []-Operator den Zeiger schon dereferenziert.
Und lass bei return *M; den *-Operator weg, damit die Adresse zurückgegeben wird und schreibe statt:
int itest2=m3dmg_getOrientationMatrix( &M );
int16_t *pitest2=m3dmg_getOrientationMatrix( &M );
Danke für die Erklärung, die Geschichte mit den Arrays ist ja quasi ein bisschen anders mit der Dereferenzierung.
Habe das ganze mal gemacht wie geschrieben und bekomme nun noch Warnings:
warning: passing argument 1 of 'm3dmg_getOrientationMatrix' from incompatible pointer type
warning: initialization makes pointer from integer without a cast
int *pitest2=m3dmg_getOrientationMatrix( &M ); <-- muss Pointer gleiches Format wir M haben?
warning: unused variable 'pitest2' <-- ist mir egal, will ja nur M
Es scheint nicht besser geworden zu sein :-( der error ist weg :-)
zum einen machst du immer noch den Fehler mit &M einen Pointer auf den Int16-Pointer zu setzen, anstatt du einfach M benutzt. Der Arraybezeichner ist ja bereits ein Pointer auf die erste Stelle im Array und zum anderen ist deine Funktion sicher immer noch als int bekannt gegeben du wirst jetzt aber versuchen einen Pointer zurückzugeben. Falls ich falsch liege, wäre es sinnvoll, wenn du den geänderten Code mal posten würdest.
sast
Meine Funktion:
int m3dmg_getOrientationMatrix( int16_t M ) { <-- so ist auch der Header
//UART Buffer auslesen
for ( int i=1 ; i <= 18 ; i=i+2 ) {
M [i] = ( (int16_t) responseBuffer[i] << 8 | (int16_t) responseBuffer[i+1] );
}
return M;
}
Meine Main:
int main(void) {
int16_t M[9];
...
int16_t *pitest2=m3dmg_getOrientationMatrix( M );
...
}
Error:
M[i]=...: error: subscripted value is neither array nor pointer
Das ist der aktuelle Stand.
BurningWave
01.06.2010, 12:51
Benutz doch bitte die Code-Tags, das ist so unübersichtlich sonst.
int m3dmg_getOrientationMatrix( int16_t M ) { <-- so ist auch der Header
Der Header ist falsch. Es muss
int16_t* m3dmg_getOrientationMatrix( int16_t *M ) {
heißen.
Vielen Dank!
Jetzt läuft es.
Und ich habe gelernt so ein Code-Tag zu nehmen :-)
Grüße,
eMM
BurningWave
01.06.2010, 15:12
So jetzt habe ich dafür noch zwei Fragen:
1. Funtionieren auch Referenzen?
2. kann man in C mittels int *pi = new int; Speicher reservieren oder geht das nur in C++? Funktionen wie malloc() funktionieren ja meines Wissens nach nicht, oder?
Erst lief es, besser: keine Warnings mehr, nun sind sie wieder da :-)
Also Header ist jetzt:
// Get Gyro Orientation Matrix
int16_t* m3dmg_getOrientationMatrix( int16_t *M );
Main:
int16_t *pitest2=m3dmg_getOrientationMatrix( &M );
Funktion:
int16_t* m3dmg_getOrientationMatrix( int16_t *M ) {
//UART auslesen
for ( int i=1 ; i <= 18 ; i=i+2 ) {
// x = cast MSB um 8 Bits nach links verschieben und cast LSB, dann schreiben
M[i] = ( (int16_t) responseBuffer[i] << 8 | (int16_t) responseBuffer[i+1] );
}
return M;
}
Warnings:
int16_t *pitest2=m3dmg_getOrientationMatrix( &M );
: warning: passing argument 1 of 'm3dmg_getOrientationMatrix' from incompatible pointer type
und
int16_t *pitest2=m3dmg_getOrientationMatrix( &M );: warning: unused variable 'pitest2'
Selber doof :-)
(M) statt (&M)
Und was mache ich mit meinem Zeiger *pitest2 damit er nicht mehr unused ist? Den brauche ich ja nicht mehr, habe ja mein M?
@mauro warum verwendest du beim Funktionsaufruf immer noch &M. Darauf hatte ich dich doch schon hingewiesen?
@R2D2 warum soll malloc in C nicht funtionieren. Das new in C funktioniert wäre mir allerdings neu.
Edit: dann lass doch die Variable pitest2 einfach weg und benutze dein M nach dem Funktionsaufruf
BurningWave
01.06.2010, 15:30
Und was mache ich mit meinem Zeiger *pitest2 damit er nicht mehr unused ist? Den brauche ich ja nicht mehr, habe ja mein M?
Du kannst entweder nur die Funktion aufrufen und den Rückgabewert nicht beachten oder du kannst den Zeiger benutzen.
int16_t *pitest2=m3dmg_getOrientationMatrix( &M );
& weglassen!!
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.