7
votes

Utilisation du pointeur vide sur un tableau

J'essayais simplement d'utiliser un pointeur vide vers un tableau entier, j'ai essayé de voir si je peux imprimer le tableau en revenant dans l'int. Mais cela me donne une valeur aléatoire. Pouvez-vous me dire où je vais mal? XXX PRE>

Sortie est: P>

133554432131072512


2 commentaires

Vous pouvez améliorer la sortie en mettant une nouvelle ligne dans la chaîne de format imprimant les numéros: printf ("% d \ n", x); .


Yupp.i ne s'est pas concentré sur le formatage car j'ai écrit cela pour m'aider à tester cette fonctionnalité pour un autre programme.


4 Réponses :


15
votes

Vous devez lancer Art avant Ajout j . Voici une solution minimale: xxx

mais je pense qu'il est plus clair d'écrire: xxx


3 commentaires

Travaillé comme un charme. Merci beaucoup.


Je me demandais pourquoi * (int *) (arr + j) est faux? Pouvez-vous s'il vous plaît expliquer moi?


@Anushapapachunuri: S'il vous plaît voir ma réponse, mais pour résumer, c'est faux, car vous ne pouvez pas ajouter de chiffres à Void * , vous devez convertir le vide * Premier puis ajouter des chiffres à cela.



1
votes

Vous ne devez pas ajouter de chiffres à des pointeurs annulés. jeté avant. ( x = * ((int *) arr + j); )

Lorsque vous ajoutez un numéro à un pointeur, le compilateur Multipliez ce numéro avec la taille du type pointu, de sorte que si vous ajoutez un numéro à un pointeur sur le type incorrect, vous aurez un résultat erroné.

Si je me souviens bien, ajoutez-le à vide * est illégal, mais certains compilateurs ajoute le nombre exact en octets (comme il est char *). `


0 commentaires

6
votes

Vous faites du pointeur arithmétique sur vide * qui n'est pas valide en c.

dans GNU C (C avec des extensions GCC), il est réellement autorisé et le taille de (void) est considéré comme 1.

http://gcc.gnu.org/onlinedocs/gcc/pointer- Arith.html

"Les opérations d'addition et de soustraction sont prises en charge sur des pointeurs à vide et sur des pointeurs sur des fonctions. Ceci est fait en traitant la taille d'un nul ou d'une fonction comme 1. "


1 commentaires

+1: Pour indiquer que l'arithmétique sur void * est une extension GCC.



2
votes

La norme C ne définit pas le comportement pour l'arithmétique de Void * , vous devez donc lancer votre Void * à un autre type de pointeur premier avant de faire de l'arithmétique avec elle.

Certains compilateurs [comme poste d'extension] Treat Treater Arithmétique de Void * identique à Char * , chaque "+1" n'augmentera que l'adresse de 1, plutôt que par la taille de l'objet pointu à l'autre. Ce n'est pas normalisé, cependant, vous ne pouvez pas compter sur ce comportement.


5 commentaires

Oh, tu veux dire que l'arithmétique du pointeur n'est pas applicable pour les pointeurs Void *. Eh bien, je vois le point. Merci pour une grande explication.


ISO / CEI 9899: 1999. §6.2.5 ¶19 Le type vide comprend un ensemble de valeurs vide; C'est un type incomplet qui ne peut pas être complété. dans ¶20 Il ajoute Un type de pointeur peut être dérivé d'un type de fonction, d'un type d'objet ou d'un type incomplet ... Lorsqu'un type incomplet n'est clairement pas un type d'objet, vous ne pouvez donc pas traiter void * en tant que pointeur sur un type d'objet. §6.5.2 Les opérateurs additifs indiquent Pour plus d'addition, soit des deux opérandes doivent avoir un type arithmétique, ou un opérande doit être un pointeur à un type d'objet et que l'autre doit avoir de type entier. Vous ne pouvez pas faire de l'arithmétique sur void * .


@JonathanLeffler: Le comportement n'est pas défini par la norme C, mais il n'est pas explicitement indéfini non plus non plus, et ce sont généralement ces zones dans lesquelles des implémentations cort dans ce comportement et l'appelent une extension.


@DeMlax comme mentionné par @jonathanLeffler ajout d'un entier et un opérande de type Void * est une violation claire des contraintes de l'opérateur additif (6.5.6P3). Cela nécessite donc un diagnostic et la mise en œuvre est libre de ne pas traduire le programme.


@ouah: Je ne discute rien ici, si quelque chose que je suis d'accord avec vous; J'ai dit que certains compilateurs le traitent comme une extension. Ce que je dis, c'est que ce n'est pas comportement indéfini d'utiliser vide * en arithmétique, je dis que cela n'est tout simplement pas défini du tout (c'est-à-dire que la norme ne fait pas Définissez tout comportement pour l'arithmétique impliquant void * ). Il existe une différence massive entre le comportement non défini et quelque chose qui n'est pas défini par la norme C.