À l'aide de nulle pointeur vers un tableau
J'essayais juste d'utiliser un vide pointeur vers un tableau d'entiers ,j'ai essayé de voir si je peux imprimer le tableau en le jetant en arrière dans int. Mais il me donne quelque valeur aléatoire. Pouvez-vous me dire où je vais mal?
#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;
}
Sortie est ceci:
133554432131072512
Pourquoi n'est-il pas pinting éléments du tableau a[] j'.e 1,2,3,4 ?
Vous pouvez améliorer le rendement en mettant un retour à la ligne dans la chaîne de format qui imprime les numéros:
Yupp.Je n'étais pas à se concentrer sur la mise en forme parce que j'ai écrit cela pour m'aider à tester cette fonctionnalité pour un autre programme.
printf("%d\n", x);
.Yupp.Je n'étais pas à se concentrer sur la mise en forme parce que j'ai écrit cela pour m'aider à tester cette fonctionnalité pour un autre programme.
OriginalL'auteur Anusha Pachunuri | 2012-01-11
Vous devez vous connecter pour publier un commentaire.
Vous avez besoin de jeter
arr
avant ajoutantj
. Ici est un minimum de correction:mais je pense que c'est plus clair d'écrire:
Je me demandais pourquoi * * * (int *)(arr+j) est le problème? Pouvez-vous svp m'expliquer?
Veuillez voir ma réponse, mais pour résumer, c'est mal parce que vous ne pouvez pas ajouter des numéros de
void *
, vous avez besoin de convertir levoid *
premier et ensuite ajouter des chiffres.OriginalL'auteur ruakh
Que vous faites de l'arithmétique des pointeurs sur
void *
qui n'est pas valide en C.Dans GNU C (C avec gcc extensions), il est effectivement autorisé et le
sizeof (void)
est considéré comme 1.http://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html
void *
est un GCC extension.OriginalL'auteur ouah
vous ne devez pas ajouter des numéros à vide pointeurs. jeter en avant. (
x = *((int *)arr+j);
)Lorsque vous ajouter un numéro à un pointeur, le compilateur multipliez ce nombre par la taille du type pointé, donc si vous ajouter un numéro à un pointeur sur un type incorrect, vous obtiendrez un résultat incorrect.
si je me souviens de rectification, de complément de void* est illégal, mais certains compilateurs ajoute le nombre exact en octets (comme il est de type char*).
`
OriginalL'auteur asaelr
Le C standard ne définit pas le comportement de l'arithmétique de
void *
, si vous avez besoin de jeter votrevoid *
à un autre type de pointeur première avant de faire de l'arithmétique avec elle.Certains compilateurs [comme une extension] traiter de l'arithmétique des pointeurs de
void *
le même quechar *
, de sorte que chaque ‘+1’ ne feront qu'augmenter à l'adresse 1, plutôt que par la taille de la pointe-de objet. Ce n'est pas standardisée, mais si vous ne pouvez pas compter sur ce comportement.ISO/IEC 9899:1999. §6.2.5 ¶19 Le type void comprend un ensemble vide de valeurs; il est incomplet, ce type de ne peut pas être terminée. et ensuite dans le § 20 il ajoute Un pointeur de type peut être dérivé d'un type de fonction, un type d'objet, ou d'un type incomplète ... où un type incomplète n'est clairement pas un type d'objet, de sorte que vous ne peut pas traiter
void *
comme un pointeur vers un type d'objet. §6.5.2 L'additif opérateurs dit De plus, soit les deux opérandes ont arithmétique de type, ou un opérande doit être un pointeur sur un type d'objet et les autres ont de type entier. Si vous ne pouvez pas faire de l'arithmétique survoid *
.Le comportement n'est pas défini par la norme, mais il n'est pas défini explicitement, soit, et c'est généralement les zones où des implémentations C mis dans un tel comportement et de l'appeler une extension.
comme mentionné par @JonathanLeffler plus d'un entier et d'un opérande de
void *
type est une claire violation des contraintes de l'additif de l'opérateur (6.5.6p3). Donc cela nécessite un diagnostic et la mise en œuvre est libre de ne pas traduire le programme.Je ne veux pas dire quoi que ce soit ici, si quoi que ce soit, je suis d'accord avec vous; j'ai dit que certains compilateurs traiter comme une extension. Ce que je veux dire c'est qu'il n'est pas comportement indéfini pour utiliser
void *
en arithmétique, je dis que c'est simplement pas du tout défini (c'est à dire la norme ne définit pas le comportement de l'arithmétique impliquantvoid *
). Il y a une énorme différence entre un comportement indéterminé et quelque chose qui n'est pas défini par la norme.OriginalL'auteur dreamlax