-8
votes

Quel type doit être utilisé pour boucle via un tableau?

Avoir ce tableau: xxx pré>

et je veux boucler à travers elle (et un autre son dernier élément): p>

char *x;

for (i = 0; i <= sizeof(arr); i++)
        x = &arr[i];


25 commentaires

Le type le plus adéquat pour l'indexation du tableau est size_t si vous devez demander, mais en utilisant tout autre type d'entier capable de représenter toute la plage n'est pas rare aussi. Vous avez d'autres problèmes dans l'extrait de publication si ...


Et vous voulez i , pas <= .


@Eugene je sais que c'est censé être supposé être Taille_T dans Standard C, mais clairement, cet extrait valide prouve que si j'avais utilisé ce type, j'aurais un problème, un problème infiniment durable :). La norme C est cassée pour cette raison, et c'est la raison pour laquelle j'accepte POSIX pour cela (qui est également cassé, à la manière).


@MaximeGorushkin non, je veux i <= Tailleof (Arr) , et c'est la raison pour laquelle j'ai mentionné explicitement un après le dernier élément. Et c'est le gros problème de la question.


Je ne comprends pas ton commentaire. Si vous avez l'intention d'indexer le tableau avec i à l'intérieur de la boucle, vous aurez un accès hors limites. Votre question est-elle sur quel type à utiliser dans ce cas particulier où vous ne accédez pas à l'élément d'extrémité unique?


standard c est cassé pour cette raison Si vous allez faire une réclamation comme celle-ci, vous allez devoir le sauvegarder avec beaucoup plus que des hands à handser et de ranter sur taille_t < / code>.


@Eugenesh. N ° C permet d'avoir un pointeur sur un dernier élément un tableau, tant que vous ne la déréférez pas.


Il n'y a pas de pointeurs dans votre code. Montrez votre cas d'utilisation spécifique.


@Andrewhenle My Simple Snippet le montre. Les types non signés en général sont cassés pour des boucles (ou vous devez être très prudent et ajouter des contrôles avant la boucle).


Ils ne sont pas cassés, ils sont limités comme un outil à leur utilisation. Le compilateur donnera un avertissement sur "la condition est toujours vrai". Oui, vous devez faire attention lorsque vous marchez sur le bord et ce code est là.


Utilisez __ int128 ou un code long double alors.


Les types non signés en général sont cassés pour des boucles Comment sont-ils "en général" cassé?


@Andrewhenle avez-vous lu la question et voyez la boucle infinie? C'est la raison.


Mineur - dans votre édition - & arr [i] est la déséroférance (c'est équivalent à & (* (Arr + i)) ), donc non, ce code n'est pas valide , mais obtenez votre point.


@Eugenesh. Le problème est que si je n'utilise pas ce cas simple avec taille_max , mais un cas où la taille est donnée par une variable taille_t , le compilateur acceptera le code, et le programme va se casser au moment de l'exécution.


@Eugenesh. n'est pas & * considéré comme équivalent à ne rien faire? Je devrais regarder cette partie de la norme à nouveau.


Avez-vous lu la question et voyez la boucle infinie? Donc, parce que vous pouvez contenir une boucle infinie, vous affirmez que c est cassé? Si vous écrire un mauvais code, c'est sur vous.


@Cacahuetefrito Ensuite, vous devriez prétendre que tout type d'entier est cassé, car il pourrait trop déborder dans le temps d'exécution. Je ne comprends pas votre raisonnement. En tant que programmeur, vous devez connaître les limitations et éviter ces problèmes ..


@Christiangibbbures qui est une question d'avocat intéressante. D'une part avec * avec un pointeur non valide est UB. D'autre part - ce que vous avez dit.


Je ne comprends pas pourquoi la possibilité d'écrire une boucle infinie impliquant une variable d'itération non signée permet d'utiliser une variable d'itération signée. Vous pouvez vous mettre au moins autant de problèmes avec une variable d'itération signée, exactement de la même manière.


Avec des types signés, je peux inverser: pour (i = Tailleof (arr); i> = 0; i -) (si le contexte le permet)


Mais dans ce cas, la seule option de boucle à travers ce qui est une taille valide, semblerait un type de 128 bits (ou double long ) comme le dit Maxim.


Mais vous êtes pas itération en sens inverse. De plus, même si l'ordre d'itération n'a pas d'importance, vous ne pouvez que itération en sens inverse si le type (signé) de i peut représenter la taille de la matrice, ce qui est peu probable pour la taille de la matrice présentée dans l'exemple. Et s'il y a était un tel type signé, son type non signé correspondant conviendrait parfaitement au type de i dans une itération en avant.


@Johnbollinger ouais, c'est pourquoi j'ai demandé à l'autre question d'abord :)


Comme vous l'avez démontré dans la question, il est tout à fait possible de vous tirer au pied à l'aide d'un type non signé comme indexeur. De même, cependant, il est tout à fait possible de vous tirer au pied en utilisant un type signé comme indexeur en raison des règles de promotion en entiers automatiques de la langue. Lorsque vous essayez de utiliser cet index, et il est implicitement converti en un boom non signé. Donc, en résumé, le langage C vous donne beaucoup de façons de vous tirer dessus au pied. Envisagez d'utiliser un pointeur comme indexeur si vous souhaitez réellement un pointeur.


3 Réponses :


1
votes

taille_t Votre ami est dans ce cas. Il vous garantit un accès à tout indice de réseau.


1 commentaires

Non, ce n'est pas mon ami. Je l'éviterais comme l'enfer et la raison est l'extrait de ma question.



1
votes

hmm, cas intéressant. Vous voulez être capable de boucler, appelons-le hypothétiquement le plus grand nombre possible et, donc enveloppant plutôt que jamais, le retour de la comparaison fausse. Quelque chose comme ça pourrait faire l'astuce: xxx

Parce qu'un processus est toujours effectué la première itération, nous pouvons mettre une condition de telle sorte que la boucle se termine lorsque i == 0 , et cela ne se produira que lors de l'enveloppe sur 0 plutôt que sur la première itération. Ajoutez une autre condition pour i <= Tailleof (arr) pour prendre soin des cas où nous n'avons pas d'emballage.


0 commentaires

2
votes

Avoir ce tableau: P>

char arr[NOT_SURE_HOW_LARGE_BUT_LESS_THAN_SIZE_MAX];

0 commentaires