Mit void-Zeiger auf ein array
War ich einfach nur versucht, einen void-Zeiger auf ein integer-array habe ich versucht zu sehen, wenn ich drucken Sie das array wieder durch Gießen Sie es zurück in int. Aber es ist mir einige zufällige Wert. Können Sie mir sagen, wohin ich gehe falsch gemacht?
#include<stdio.h>
#include<stdlib.h>
int main(){
int a[5];
int x;
int j;
a[0]=1;
a[1]=2;
a[2]=3;
a[3]=4;
void *arr=a;
for(j=0;j<4;j++){
x = *(int *)(arr+j);
printf("%d",x);
}
return 0;
}
Ausgabe ist diese:
133554432131072512
Warum ist es nicht pinting Elemente eines Arrays a[] ich.e 1,2,3,4 ?
Sie können das Ergebnis verbessern, indem ein Zeilenumbruch in der format-Zeichenfolge, gibt die zahlen:
Yupp.Ich war nicht die Konzentration auf die Formatierung, weil ich das geschrieben habe um mir selbst zu helfen testen Sie diese Funktionalität für ein anderes Programm.
printf("%d\n", x);
.Yupp.Ich war nicht die Konzentration auf die Formatierung, weil ich das geschrieben habe um mir selbst zu helfen testen Sie diese Funktionalität für ein anderes Programm.
InformationsquelleAutor Anusha Pachunuri | 2012-01-11
Du musst angemeldet sein, um einen Kommentar abzugeben.
Müssen Sie gegossen
arr
vor hinzufügenj
. Hier ist ein minimal-Update:aber ich denke, es ist deutlicher zu schreiben:
Ich Frage mich, wieso *(int *)(arr+j) ist falsch? Können Sie bitte mir erklären?
Sehen Sie bitte meine Antwort, aber, um es zusammenzufassen, es ist falsch, weil Sie nicht zahlen hinzufügen
void *
, müssen Sie zum konvertieren vonvoid *
erste, und fügen Sie dann zahlen.InformationsquelleAutor ruakh
Du tust Zeiger-Arithmetik auf
void *
ist nicht gültig im C.In GNU-C (C mit gcc-Erweiterungen), ist es eigentlich zulässig, und die
sizeof (void)
ist als 1.http://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html
void *
ist eine GCC-Erweiterung.InformationsquelleAutor ouah
sollten Sie nicht zahlen hinzufügen void-Pointer. es Stimmen vor. (
x = *((int *)arr+j);
)Wenn Sie Nummer hinzufügen, um einen Zeiger, der compiler multiplizieren Sie diese Zahl mit der Größe des Typs, der ist spitz, so dass, wenn Sie Nummer hinzufügen, um einen Zeiger auf falsche Art, erhalten Sie falsche Ergebnis.
wenn ich mich zu korrigieren, zu ergänzen, zu void* ist illegal, aber einige Compiler fügt die genaue Anzahl in bytes (wie es ist " char*").
`
InformationsquelleAutor asaelr
C-standard nicht definiert Verhalten für die Arithmetik der
void *
sind, so müssen Sie werfen Sie Ihrevoid *
zu einem anderen Typ Zeiger ersten, bevor Sie Arithmetik.Einige Compiler [Erweiterung] Behandlung von Zeiger-Arithmetik von
void *
das gleiche wiechar *
, so dass jeder '+1' erhöht nur die Adresse um 1, sondern durch die Größe des Spitzen-zu-Objekt. Dies ist nicht genormt, obwohl, so dass Sie können nicht Sie verlassen sich auf dieses Verhalten.ISO/IEC 9899:1999. §6.2.5 ¶19 Der leere-Typ umfasst eine leere Menge von Werten; es ist ein unvollständiger Typ, der nicht abgeschlossen werden kann. und dann in ¶20 fügt er Ein Zeiger-Typ kann abgeleitet werden aus einer Funktion vom Typ ein Objekttyp oder eine unvollständige Art ..., wo ein unvollständiger Typ ist eindeutig nicht ein Objekt-Typ, so dass Sie nicht behandeln
void *
als ein Zeiger auf ein Objekt geben. §6.5.2 Der Additions-Operator, sagt Für die Ergänzung, entweder beide Operanden haben arithmetischen Typ oder einer der Operanden ist ein Zeiger auf ein Objekt-Typ und der andere Vertragspartner vom Typ integer. So kann man nicht rechnen aufvoid *
.Das Verhalten ist nicht definiert durch den C-standard, aber es ist nicht explizit undefiniert, entweder, und es in der Regel sind diese Bereiche, in denen C-Implementierungen, die in Verhalten und nennen es eine Erweiterung.
wie bereits von @JonathanLeffler neben einer integer-und einer Operanden
void *
Typ ist ein klarer Verstoß gegen die Einschränkungen der Additiven operator (6.5.6p3). So Bedarf es einer Diagnose und die Umsetzung ist frei, um nicht das Programm übersetzen.Ich bin mir nicht streiten hier nichts, wenn alles, was ich bin einverstanden mit dir, ich sagte, dass einige Compiler behandeln es als eine Erweiterung. Was ich damit sagen will ist, dass es nicht undefined behaviour zu verwenden
void *
im rechnen, ich sage, es ist einfach gar nicht definiert (d.h. in der Norm nicht definiert kein Verhalten für Arithmetik mitvoid *
). Es gibt einen massiven Unterschied zwischen dem undefinierten Verhalten und etwas, das nicht definiert der C-standard.InformationsquelleAutor dreamlax