"You must take care to allocate enough memory to store the results in
dest (at least nb * sizeof(uint16_t))."
const uint16_t *dest
1) Wieso wird hier const verwendet?
2) uint16_t *dest
bedeutet das jedesmal wen ich ein dest++ mache er den Pointer um 16 bits
bewegt?
Simon schrieb:> bedeutet das jedesmal wen ich ein dest++ mache er den Pointer um 16 bits> bewegt?
??? dest++ inkrementiert den Pointer, da wird gar nicht bewegt.
adf schrieb:> ??? dest++ inkrementiert den Pointer, da wird gar nicht bewegt.
um 16 Bit?
Was wäre anders wenn es so heiszen würde:
const uint8_t *dest)
Ich checks immer noch nicht, warum const?
const sagt aus das die Variable einmal deklariert und zugewiesen wird,
danach nicht mehr geändert.
Bedeutet das nun das ich die Variable innerhalb der funktion nicht vor
habe zu verändern?
1
voidfunktion(constuint16_t*dest);
der Aufruf wäre dann mit
1
funktion(*variable);?
Und was sagt mir uint16_t in dem Zusammenhang? das der Pointer aus einer
16 Bit addresse besteht?
Simon schrieb:> der Aufruf wäre dann mitfunktion(*variable); ?
Nein
mitfunktion(&variable);
Die Funktion erwartet eine Adresse und die bekommst du mit dem
Adressoperator &
> Und was sagt mir uint16_t in dem Zusammenhang?
Das an der Adresse auf die der Zeiger zeigt eine vorzeichenlose 16-Bit
Ganzzahl steht.
Der Compiler muss wissen wie er die Daten an der Adresse interpretieren
soll.
Simon schrieb:> Ich checks immer noch nicht, warum const?
Gute Frage
> const sagt aus das die Variable einmal deklariert und zugewiesen wird,> danach nicht mehr geändert.
An dieser Stelle sagt das const aus, dass die aufgerufene Funktion den
Pointer nicht benutzen wird um über diesen Pointer die Werte an der
Stelle im Speicher zu verändern, auf die der Pointer zeigt.
Beispiel
void foo( uint16_t * pDest )
{
*pDest = 5;
}
int main()
{
uint16_t i;
foo( &i );
}
ich übergebe der Funktion die Adresse von i. Die Funktion benutzt diese
Adresse, um über diese Adresse die Variable i zu verändern.
Und jetzt das ganze const
void foo( const uint16_t * pDest )
{
*pDest = 5;
}
int main()
{
uint16_t i;
foo( &i );
}
jetzt gibt mir die Funktion die Zusicherung, genau das nicht zu tun. Sie
wird die Adresse, die ich ihr gebe, nicht dazu benutzen um die Variable
zu verändern.
Wenn du das compilierst, dann wird es einen Fehler hier
*pDest = 5;
geben. Denn diese Operation versucht genau das, was durch das const in
der Argumentliste ausgeschlossen wurde. Der Compiler verhindert das
daher.
Allerdings:
Ich weiß zwar nicht, was deine Funktion genau macht. Aber wenn ich raten
müsste, würde ich den Argumentnamen 'dest' alsw Kurzform für Destination
ansehen, also das Ziel einer Operation. Und da würde ich mal raten, dass
dieses Ziel irgendwie verändert wird. Wodurch das const keinen Sinn
ergibt.
Aber: Das ist jetzt nur geraten. Genaueres kann man nur sagen, wenn man
weiß was das für eine Funktion ist und welchen Zweck sie hat.
Karl Heinz Buchegger schrieb:> Und da würde ich mal raten, dass> dieses Ziel irgendwie verändert wird. Wodurch das const keinen Sinn> ergibt.
Da brauchst du nicht zu raten, das steht sogar da:
Simon schrieb:> "You must take care to allocate enough memory to store the results in> dest (at least nb * sizeof(uint16_t))."
Da hat der unbekannte Autor der Funktion das mit dem const auch nicht
auf die Reihe gekriegt. Im Sourcecode wurde die aber wohl nicht
ausgeliefert, denn jeder "anständige" C-Compipler würde sich weigern,
den Schreibzugriff in das Feld zu übersetzen.
Oliver
Egal ob du eine Variable als uint16_t oder uint8_t vereinbarst, haben
Pointer eine konstante Größe. Sie beinhalten doch nur die Adresse auf
eine Speicherstelle. Der Datentyp definiert nur wie die Daten an dieser
Speicherstelle zu interpretieren sind.
Wie ein Pointer auf dekrementieren oder inkrementieren reagiert kann
ohne Bezug zu einem realen System nicht definiert werden. Auf der Intel
Plattform ist eine Byteweise Addressierung üblich. Das heißt, ++ und --
verändern die Pointeradresse um ein Byte, egal um welchen Datentyp es
sich handelt.
Decius schrieb:> Das heißt, ++ und --> verändern die Pointeradresse um ein Byte, egal um welchen Datentyp es> sich handelt.
Nein. Da heißt es aufpassen.
Ok, hinsichtlich ++ und -- bin ich jertzt doch etwas unsicher. :-)
Hsabe auch sowas gelesen, daß das Ergebnis in diesen Fällen doch vom
Datentyp abhängig ist. Also wenn du ein Array von short hast, verändert
die Adresse sich um 2Byte.
Aber Systemabhängig muß das ganze aber auch sein. Denn die Byteweiyse
Addressierung der intelplattform ist bei ARM's nicht üblich.
Decius schrieb:> Wie ein Pointer auf dekrementieren oder inkrementieren reagiert kann> ohne Bezug zu einem realen System nicht definiert werden.
Natürlich kann das vollständig definiert werden, und das ist es auch.
Kurz gesagt, zeigt der pointer nach der Inkremetierung auf das folgende
Element gleichen Typs. So einfach ist das. Wie die Bytes im Speicher
angeordnet sind, ist zwar implementationsabhängig, abder der Spache C
völlig egal.
Oliver
Simon schrieb:> Ich checks immer noch nicht, warum const?>> const sagt aus das die Variable einmal deklariert und zugewiesen wird,> danach nicht mehr geändert.>>> Bedeutet das nun das ich die Variable innerhalb der funktion nicht vor> habe zu verändern?
1
constinta;
ist eine Konstante.
1
constint*a;
ist ein (variabler) Zeiger auf eine Konstante.
Der Zeiger selber ist dann keine Konstante!
Stell Dir vor, Du hast eine Tabelle aus Konstanten und Du willst mit
einem Zeiger durch diese Tabelle gehen. Dann muß der Zeiger veränderbar
sein, neech?
1
int*consta;
wäre ein konstanter Zeiger auf eine Variable.
1
constint*consta;
wäre ein konstanter Zeiger auf eine Konstante.
Es gibt tatsächlich Anwendungsfälle für alle Varianten.
Dosmo schrieb:> const int a; ist eine Konstante.const int *a; ist ein (variabler) Zeiger auf
eine Konstante.
Jein.
Genau genommen ist es eine Variable und mit dem const sagt man, daß man
im Geltungsbereich dieser Deklaration diese Variable nicht ändern
möchte.
Der Unterschied ist z.B. dann relevant, wenn man Parameterdeklarationen
hat:
1
voidf1(int*p_i)
2
{
3
*p_i++;
4
// ...
5
}
6
7
voidf2(constint*p_i)
8
{
9
// jetzt nicht mehr möglich: *p_i++;
10
// ...
11
}
12
13
...
14
inti=0;
15
constintci=0;
16
f1(&i);// ok
17
f1(&ci);// falsch, da f1() nicht verspricht, ci nicht zu ändern
18
f2(&i);// ok, auch wenn i nicht const ist
19
f2(&ci);// ok, da f2() verspricht, ci nicht zu ändern
Beim Aufruf f2( &i ) ist *p_i keine Konstante, auch wenn es in f2() so
deklariert ist, sondern eine astreine Variable - sie wird nur in f2()
nicht geändert.
Klaus Wachtler schrieb:> Dosmo schrieb:>> const int a; ist eine Konstante.const int *a; ist ein (variabler)>> Zeiger auf eine Konstante.>> Jein.> Genau genommen ist es eine Variable und mit dem const sagt man, daß man> im Geltungsbereich dieser Deklaration diese Variable nicht ändern> möchte.
Noch genauer genommen gibt es in C gar keine Konstanten (abgesehen von
direkt als Zahl hingeschriebenen Werten). Das ist ja der Grund, warum so
oft Makros als Ersatz dafür verwendet werden.
Decius schrieb:> Aber Systemabhängig muß das ganze aber auch sein. Denn die Byteweiyse> Addressierung der intelplattform ist bei ARM's nicht üblich.>
Sie ist üblich.
Klaus Wachtler schrieb:> void f2( const int * p_i )> {> // jetzt nicht mehr möglich: *p_i++;> }
Doch, *p_i++ geht sehr wohl, weil das *p_i nicht verändert.
Was hingegen nicht geht ist (*p_i)++.
Klaus Wachtler schrieb:
> Dosmo schrieb:>> const int a; ist eine Konstante.const int *a; ist ein (variabler)>> Zeiger auf eine Konstante.>> Jein.> Genau genommen ist es eine Variable und mit dem const sagt man, daß man> im Geltungsbereich dieser Deklaration diese Variable nicht ändern> möchte.
Absolut richtig.
Mir ging es um den Unterschied, ob man den Qualifier vor oder hinter den
* setzt.
Johann L. schrieb:> Klaus Wachtler schrieb:>>> void f2( const int * p_i )>> {>> // jetzt nicht mehr möglich: *p_i++;>> }>> Doch, *p_i++ geht sehr wohl, weil das *p_i nicht verändert.>> Was hingegen nicht geht ist (*p_i)++.
ja, meinte ich natürlich.
Dosmo schrieb:> Absolut richtig.> Mir ging es um den Unterschied, ob man den Qualifier vor oder hinter den> * setzt.
Generell bezieht sich der Qualifier auf das, was unmittelbar links davon
steht. Und dann gibt es noch den Spezialfall, daß links nichts mehr
kommt. Dann bezieht er sich stattdessen auf das, was unmittelbar rechts
davon steht.
Dosmo schrieb:> Mir ging es um den Unterschied, ob man den Qualifier vor oder hinter den> * setzt.
In Gedanken trennt man die Deklaration in durch * getrennte Häppchen
auf. Ein Qualifier wirkt nur auf sein eigenes Häppchen.
Damit ist auch klar, wie welcher Zugriff geschieht in