2016-04-24 6 views
2


Ich arbeite an einem Arduino-Projekt. Ich versuche, eine bytepointer an eine function übergeben, und lassen Sie function die Größe der Daten berechnen, auf die der Zeiger verweist. Aber wenn ich die Zeiger auf ein Byte verweisen lassen, sizeof() kehrt 2. Ich schrieb den folgenden Code-Schnipsel zu debuggen, um zu versuchen:Größe des Bytes beim Zugriff über Zeiger

byte b; 
byte *byteptr; 
byteptr = &b; 

print("sizeof(b): "); 
println(sizeof(b)); 

print("sizeof(*byteptr) pointing to byte: "); 
println(sizeof(*byteptr)); 

print("sizeof(byteptr) pointing to byte: "); 
println(sizeof(byteptr)); 

das gedruckte Ergebnis ist:

sizeof(b): 1 
sizeof(*byteptr) pointing to byte: 1 
sizeof(byteptr) pointing to byte: 2 

So ist die Größe eines Bytes ist 1, aber über den Zeiger ist es 2 ??

+5

No. Die Größe des Zeigers selbst ist 2. –

+0

Abschließend auf der Arduino, die Größe eines Zeigers 2 Bytes annimmt. –

+0

... und zählen Sie sich glücklich. Auf meinem Desktop braucht es nicht 2, nicht 4, sondern 8 Bytes, um auf ein einzelnes Byte zu zeigen! Was für eine Abzocke. –

Antwort

5

Es scheint, dass Zeiger auf Arduino 16 Bit sind. Ich glaube, dass Ihre Verwirrung davon herrührt, was in diesem Zusammenhang bedeutet, *.

sizeof(*byteptr) entspricht der sizeof(byte). Die * zeigt keinen Zeiger Typ an, es zeigt deneferencing den in byteptr gespeicherten Zeiger an. Ergo, es ist 1 Byte, was Sie vom Typ byte erwarten würden.

sizeof(byteptr) Dereferenziert den Zeiger nicht, und als solche ist die Größe des Zeigers selbst, der auf diesem System 2 Bytes/16 Bits zu sein scheint.

Beachten Sie Folgendes:

#include "iostream" 

using namespace std; 

int main() 
{ 
    char a = 1; 
    char* aP = &a; 

    cout << "sizeof(char): " << sizeof(char) << endl; 
    cout << "sizeof(char*): " << sizeof(char*) << endl; 
    cout << "sizeof(a): " << sizeof(a) << endl; 
    cout << "sizeof(aP): " << sizeof(aP) << endl; 
    cout << "sizeof(*aP): " << sizeof(*aP) << endl; 
} 

Ausgang (auf einem 64-Bit-OS/Compiler):

sizeof(char): 1 
sizeof(char*): 8 
sizeof(a): 1 
sizeof(aP): 8 
sizeof(*aP): 1 
+0

danke für die Eingabe. Aber ich brauche einen Zeiger, um die Größe des Arrays zu entscheiden, wenn ich zB tgis byte b [4], byte * byteptr = b, sizeof (* bytptr) immer noch 1 zurückgebe, irgendwelche Tipps? – Maseb

+1

@Maseb Ich schlage vor, eine andere Frage zu stellen, weil sich das sehr von der unterscheidet, die Sie gepostet haben. –

+1

@Maseb Dies könnte jedoch hilfreich sein: http://StackOverflow.com/Questions/1328223/When-a-Function-has-a-Specific-Size-Array-Parameter-Why-Is-Replaced-mit- ap - das Ermitteln der Größe von Arrays ist ein ärgerliches Problem in C (oder C++ mit Raw-Arrays), also würde ich persönlich vorschlagen, dass Sie einfach die Größe speichern und sie für die größte Klarheit und geringste Fehlerwahrscheinlichkeit weitergeben. –

0

@Maseb Ich glaube, Sie haben eine gute Diskussion über die Unterschiede zwischen der Größe bekommen eines dereferenzierten Zeigers und die tatsächliche Größe des Zeigers selbst. Ich füge einfach hinzu, dass die groß genug sein muss, damit jede Adresse des Speicherplatzes, in dem ein Byte-Wert möglicherweise gespeichert werden könnte, in die Speicherbreite des Zeigers passt. Wenn beispielsweise auf Ihrem Arduino 32.000 Byte Speicher vorhanden sind, können Sie möglicherweise einen Zeiger verwenden, der auf die Adresse 32.000 zeigen muss. Da 2^15 etwa 32.000 ist, benötigen Sie 14 oder 15 Bits, um für jeden Speicherplatz eine eindeutige Adresse zu erstellen. Wir setzen die Zeigeradressraumlänge auf Blöcke von vier Bits. Daher hat Ihr Arduino einen 16-Bit-Adressraum für Zeiger und sizeof (byte_pointer) ist 2 Bytes oder 16 Bits.

Mit diesem gesagt, werde ich weitermachen eine Antwort auf Ihre andere Frage auch. Wenn Sie ein Array und eine Größe übergeben müssen, erstellen Sie einfach Ihre eigene Struktur, die diese beiden Datenelemente enthält. Dann können Sie den Zeiger auf diese Vorlagenstruktur übergeben, die die Größe enthält (Dies ist die grundlegende Implementierung für den C++ - Array-Container).

Ich habe das folgende kurze Codebeispiel geschrieben, um zu demonstrieren, wie Sie Ihre eigene Vorlage für ein Array mit einem Größenelement erstellen und dieses Größenelement dann verwenden, um über die Elemente zu iterieren.

template<int N> 
struct My_Array{ 
    int size = N; 
    int elem[N]; 
}; 

//create the pointer to the struct 
My_Array<3>* ma3 = new My_Array<3>; 

void setup() { 
    //now fill the array element 
    for(int i=0; i < ma3->size; i++) { 
     ma3->elem[0]=i; 
    } 

    Serial.begin(9600); 

    //now you can use the size value to iterate over the elements 
    Serial.print("ma3 is this big: "); 
    Serial.println(ma3->size); 

    Serial.println("The array values are:"); 
    Serial.print("\t["); 
    for(int i=0; i<ma3->size; i++) { 
     Serial.print(ma3->elem[i]); 
     if(i < ma3->size-1) Serial.print(", "); 
    } 
    Serial.println("]"); 
} 

void loop() { 
    while(true) { /* do nothing */ } 
} 
+0

'int size = N' ist eine schlechte Idee, die einfach Speicherplatz in der Struktur verschwendet –

+0

Ich nehme an, seine ursprüngliche Frage war über Bytes, aber wie sonst schlagen Sie vor, die Größe des Arrays zu tragen, damit er Zugriff auf die Größe und hat die Daten über einen Zeiger, der herumgereicht werden kann? – ZacSketches

+0

Es ist im Typ gespeichert, Sie brauchen keine zusätzliche Variable dafür –