Question Qu'est-ce que size_t en C?


Je suis confus avec size_t en C. Je sais qu'il est retourné par le sizeof opérateur. mais qu'est ce que c'est exactement? Est-ce un type de données?

Disons que j'ai un for boucle:

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

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


465
2018-03-31 05:51


origine


Réponses:


De Wikipedia:

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

size_test un type de données non signé   défini par plusieurs normes C / C ++,   par exemple. la norme C99 ISO / IEC 9899,   cela est défini dans stddef.h.1 Ça peut   être importé en outre par inclusion de    stdlib.h comme ce fichier sous-interne   inclut stddef.h.

Ce type est utilisé pour représenter le   taille d'un objet. Fonctions de bibliothèque   qui prennent ou retournent des tailles les attendent   être de type ou avoir le type de retour   de size_t. En outre, le plus   basé sur un compilateur fréquemment utilisé   l'opérateur sizeof devrait évaluer à un   valeur constante compatible avec    size_t.

Comme implication, size_t est un type garanti pour contenir n'importe quel index de tableau.


363
2018-03-31 05:56



size_t est un type non signé. Donc, il ne peut représenter aucune valeur négative (<0). Vous l'utilisez lorsque vous comptez quelque chose et êtes sûr qu'il ne peut pas être négatif. Par exemple, strlen() retourne un size_t parce que la longueur d'une chaîne doit être au moins 0.

Dans votre exemple, si votre index de boucle va toujours être supérieur à 0, il peut être judicieux d’utiliser size_tou tout autre type de données non signé.

Lorsque vous utilisez un size_t object, vous devez vous assurer que dans tous les contextes utilisés, y compris l'arithmétique, vous voulez des 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. Tu ne peux pas faire:

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

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

Certaines fonctions de C / POSIX peuvent / devraient utiliser size_t, mais pas pour des raisons historiques. Par exemple, le deuxième paramètre à fgets devrait idéalement être size_t, mais est int.


177
2018-03-31 09:11



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

Selon l'implémentation, 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;

58
2018-02-25 18:32



Si vous êtes du type empirique

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

Sortie pour Ubuntu 14.04 64 bits GCC 4.8:

typedef long unsigned int size_t;

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

Apparitions C99 intéressantes

  • malloc prend size_t en tant qu'argument, il détermine donc la taille maximale qui peut être allouée.

    Et comme il est également retourné par sizeof, Je pense que cela limite la taille maximale d'un tableau.

    Voir également: La taille maximale d'un tableau en C


46
2018-06-14 21:07



La page de manuel pour types.h dit:

size_t doit être un type entier non signé


16
2018-03-31 05:56



Comme personne ne l’a encore mentionné, la signification linguistique primaire de size_t est-ce le sizeof L'opérateur renvoie une valeur de ce type. De même, la signification première 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 car elles permettent à ces fonctions de fonctionner avec des objets dont la taille dépasse UINT_MAX sur les systèmes où de tels objets peuvent exister, sans forcer les appelants à passer du code supérieur à "unsigned int" suffirait pour tous les objets possibles.


11
2017-10-05 19:46



size_t et int ne sont pas interchangeables. Par exemple sur Linux 64 bits size_t a une taille de 64 bits (c.-à-d. sizeof(void*)) mais int est de 32 bits.

Notez également que size_t est non signé. Si vous avez besoin d'une version signée, il y a ssize_t sur certaines plates-formes et cela 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 n'utiliser que size_t/ssize_t quand il y a un besoin spécifique (avec mmap() par exemple).


5
2017-10-30 03:03



En général, si vous commencez à 0 et que vous montez, utilisez toujours un type non signé pour éviter un débordement qui vous amènera dans une situation de valeur négative. Ceci est extrêmement important, car si les limites de votre tableau sont inférieures au maximum de votre boucle, mais que votre boucle maximale est supérieure à la valeur maximale de votre type, vous obtiendrez un résultat négatif et erreur de segmentation (SIGSEGV). Donc, en général, n'utilisez jamais int pour une boucle commençant à 0 et allant vers le haut. Utilisez un non signé.


3
2017-11-09 17:34



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


0
2017-08-12 05:56



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

Quand on utilise un size_t objet, 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
2018-05-15 18:10



De ma compréhension, size_t est un unsigned entier dont la taille de bit est assez grande pour contenir un pointeur de l'architecture native.

Alors:

sizeof(size_t) >= sizeof(void*)

-5
2018-03-07 21:48