Qu'est-ce que la taille t en C?

je me confonds avec size_t en C. Je sais qu'il est retourné par l'opérateur sizeof . Mais qu'en est-il exactement? Est-il un type de données?

disons que j'ai une boucle for :

for(i = 0; i < some_size; i++)

dois-je utiliser int i; ou size_t i; ?

484
demandé sur Peter Mortensen 2010-03-31 09:51:55

11 réponses

De Wikipedia :

selon la norme ISO C de 1999 (C99), size_t est un entier non signé type d'au moins 16 bits (Voir sections 7.17 et 7.18.3).

size_t est un type de données non signé défini par plusieurs normes c / c++ , par exemple, la norme C99 ISO / IEC 9899, qui est défini dans stddef.h . 1 , Il peut être importés par inclusion de stdlib.h comme ce fichier interne sous comprend stddef.h .

ce type est utilisé pour représenter de la taille d'un objet. Les fonctions de la bibliothèque que les tailles de prise ou de retour s'attendent à eux pour être de type ou de retour de type de size_t . En outre, la plupart des compilateur fréquemment utilisé taille de l'opérateur devrait évaluer à un valeur constante compatible avec size_t .

comme une implication, size_t est un type garanti pour contenir n'importe quel indice de tableau.

375
répondu sblom 2016-11-22 10:30:21

size_t est un type non signé. Il ne peut donc pas représenter de valeurs négatives(<0). Vous l'utilisez quand vous comptez quelque chose, et vous êtes sûr qu'il ne peut pas être négatif. Par exemple:, strlen() renvoie un size_t parce que la longueur d'une chaîne doit être au moins 0.

dans votre exemple, si votre indice de boucle est toujours supérieur à 0, Il pourrait être logique d'utiliser size_t , ou tout autre type de données non signé.

Lorsque vous utilisez un size_t objet, vous devez vous assurer que dans tous les contextes, il est utilisé, y compris l'arithmétique, vous voulez valeurs non négatives. Par exemple, disons que vous avez:

size_t s1 = strlen(str1);
size_t s2 = strlen(str2);

et vous voulez trouver la différence des longueurs de str2 et str1 . Vous ne pouvez pas faire:

int diff = s2 - s1; /* bad */

C'est parce que la valeur attribuée à diff est toujours un nombre positif, même quand s2 < s1 , parce que le calcul est fait avec des types non signés. Dans ce cas, selon le cas d'utilisation, il est préférable d'utiliser int (ou long long ) pour s1 et s2 .

il y a certaines fonctions dans C/POSIX qui pourraient/devraient utiliser size_t , mais ne le font pas pour des raisons historiques. Par exemple , le second paramètre de fgets devrait idéalement être size_t , mais est int .

184
répondu Alok Singhal 2018-06-22 08:57:04

size_t est un type qui peut contenir n'importe quel index de tableau.

selon la mise en œuvre, il peut s'agir de:

unsigned char

unsigned short

unsigned int

unsigned long

unsigned long long

Voici comment size_t est défini dans stddef.h de ma machine:

typedef unsigned long size_t;
61
répondu Arjun Sreedharan 2015-03-04 20:48:38

si vous êtes le type empirique

echo | gcc -E -xc -include 'stddef.h' - | grep size_t

Sortie Pour Ubuntu 14.04 64-bit GCC 4.8:

typedef long unsigned int size_t;

noter que stddef.h est fourni par GCC et non glibc sous src/gcc/ginclude/stddef.h dans GCC 4.2.

Intéressant C99 apparences

  • malloc prend size_t comme argument, donc il détermine le maximum taille pouvant être attribuée.

    et puisqu'il est aussi retourné par sizeof , je pense qu'il limite la taille maximale d'un tableau.

    Voir aussi: la taille maximale d'un réseau en C

49

la page de manuel pour les types .h dit:

size_t est un type entier non signé

16
répondu codaddict 2010-03-31 05:56:25

puisque personne ne l'a encore mentionné, la principale signification linguistique de size_t est que l'opérateur sizeof renvoie une valeur de ce type. De même, la signification principale de ptrdiff_t est que soustraire un pointeur d'un autre donnera une valeur de ce type. Les fonctions de bibliothèque qui l'acceptent le font parce qu'elles permettront à ces fonctions de fonctionner avec des objets dont la taille dépasse UINT_MAX sur des systèmes où de tels objets pourraient exister, sans forcer les appelants à code de déchets passant une valeur plus grande que "int non signé" sur les systèmes où le type plus grand suffirait pour tous les objets possibles.

11
répondu supercat 2016-10-05 19:46:30

size_t et int ne sont pas interchangeables. Par exemple, sur Linux 64 bits size_t est de taille 64 bits (i.e. sizeof(void*) ) mais int est de 32 bits.

notez Également que size_t n'est pas signé. Si vous avez besoin de la version signée, alors il y a ssize_t sur certaines plateformes et ce serait plus pertinent pour votre exemple.

en règle générale, je suggère d'utiliser int pour la plupart des cas généraux et seulement l'utilisation size_t / ssize_t lorsqu'il y a un besoin spécifique (avec mmap() par exemple).

5
répondu dtoux 2015-04-09 06:37:33

en général, si vous commencez à 0 et allez vers le haut, toujours utiliser un type non signé pour éviter un débordement vous menant dans une situation de valeur négative. Ceci est d'une importance critique, parce que si les limites de votre tableau sont inférieures au max de votre boucle, mais que le max de votre boucle est supérieur au max de votre type, vous allez vous enrouler autour du négatif et vous pouvez éprouver une faille de segmentation 151920920 "(SIGSEGV). Donc, en général, Ne jamais utiliser int pour une boucle commençant à 0 et vers le haut. Utilisez un non signé.

3
répondu Mark 2013-12-11 11:34:07

size_t est un type de données entier non signé. Sur les systèmes utilisant la bibliothèque GNU C, ceci sera non signé int ou non signé long int. size_t est couramment utilisé pour l'indexation de tableaux et le comptage de boucles.

1
répondu Prince 2017-08-12 05:56:09

size_t ou tout type non signé peut être considéré comme une variable de boucle car les variables de boucle sont généralement supérieures ou égales à 0.

lorsque nous utilisons un objet size_t , nous devons nous assurer que dans tous les contextes où il est utilisé, y compris l'arithmétique, nous ne voulons que des valeurs non négatives. Par exemple, le programme suivant donnerait certainement le résultat inattendu:

// C program to demonstrate that size_t or
// any unsigned int type should be used 
// carefully when used in a loop

#include<stdio.h>
int main()
{
const size_t N = 10;
int a[N];

// This is fine
for (size_t n = 0; n < N; ++n)
a[n] = n;

// But reverse cycles are tricky for unsigned 
// types as can lead to infinite loop
for (size_t n = N-1; n >= 0; --n)
printf("%d ", a[n]);
}

Output
Infinite loop and then segmentation fault
0
répondu bishwas pokharel 2018-05-15 18:10:30

D'après ce que j'ai compris, size_t est un entier unsigned dont la taille de bits est assez grande pour contenir un pointeur de l'architecture native.

:

sizeof(size_t) >= sizeof(void*)
-4
répondu David Zechiel 2013-07-26 08:39:34