Diferença entre size_t e unsigned int?

107

Estou tão confuso size_t. Pesquisei na internet e em todos os lugares mencionei que size_té um tipo sem sinal, então, pode representar apenas valores não negativos.

Minha primeira pergunta é: se ele é usado para representar apenas valores não negativos, por que não usamos em unsigned intvez de size_t?

Minha segunda pergunta é: size_te são unsigned intintercambiáveis ​​ou não? Se não, por quê?

E alguém pode me dar um bom exemplo size_te resumidamente de seu funcionamento?

Vikas Verma
fonte
5
typedef /*This part is implementation dependent */ size_t;
P0W 01 de
5
possível duplicata de unsigned int vs. size_t

Respostas:

87

se for usado para representar um valor não negativo, então por que não usamos em unsigned intvez desize_t

Porque unsigned intnão é o único tipo inteiro sem sinal. size_tpoderia ser qualquer um unsigned char, unsigned short, unsigned int, unsigned longou unsigned long long, dependendo da implementação.

A segunda pergunta é essa size_te unsigned intsão intercambiáveis ​​ou não e se não, por quê?

Eles não são intercambiáveis, pelo motivo explicado acima ^^.

E alguém pode me dar um bom exemplo de size_t e seu breve funcionamento?

Eu não entendo muito bem o que você quer dizer com "seu breve trabalho". Funciona como qualquer outro tipo sem sinal (em particular, como o tipo para o qual é typedeffed). Você é encorajado a usar size_tquando estiver descrevendo o tamanho de um objeto. Em particular, o sizeofoperador e várias funções de biblioteca padrão, como strlen()retorno size_t.

Bônus: aqui está um bom artigo sobre size_t(e o ptrdiff_ttipo intimamente relacionado ). Ele raciocina muito bem por que você deve usá-lo.

Santhosh Kumar
fonte
1
Como exatamente pode size_tser um unsigned char? Isso está no padrão permitido? Quero dizer, com essa ideia, como se poderia esperar que alguém usasse calloc()(e sua família), strlen()etc.? Isso me parece um absurdo.
Pryftan de
Acho que size_té definido no padrão como um "tipo inteiro sem sinal", mas não exige que seja o mesmo que qualquer um unsigned {char, short, int, long, long long}.
Paul Hankin
80

Existem 5 tipos de inteiros sem sinal padrão em C:

  • unsigned char
  • unsigned short
  • unsigned int
  • unsigned long
  • unsigned long long

com vários requisitos para seus tamanhos e intervalos (resumidamente, o intervalo de cada tipo é um subconjunto do intervalo do próximo tipo, mas alguns deles podem ter o mesmo intervalo).

size_té um typedef(ou seja, um alias) para algum tipo sem sinal (provavelmente um dos acima, mas possivelmente um tipo inteiro sem sinal estendido , embora isso seja improvável). É o tipo fornecido pelo sizeofoperador.

Em um sistema, pode fazer sentido usar unsigned intpara representar tamanhos; em outro, pode fazer mais sentido usar unsigned longou unsigned long long. ( size_té improvável que seja unsigned charou unsigned short, mas isso é permitido).

O objetivo de size_té aliviar o programador de ter que se preocupar com qual dos tipos predefinidos é usado para representar os tamanhos.

O código que assume que sizeofproduz um unsigned intnão seria portátil. O código que assume que produz um size_ttem mais probabilidade de ser portátil.

Keith Thompson
fonte
6
Acho que essa deve ser a resposta aceita porque explica por que você deve usar size_t
kuchi
@ Keith-Thompson Então, isso significa que o tipo específico (isto é unsigned int, unsigned long, etc.) que size_tcorresponde ao depende da máquina na qual o código é executado? ou seja, em uma arquitetura de máquina, ele corresponde, unsigned intmas em outra arquitetura ele corresponderá unsigned long, etc?
Richie Thomas
1
@RichieThomas: Depende da implementação em C. Dois compiladores diferentes na mesma arquitetura podem escolher tipos diferentes para size_t, especialmente se, por exemplo, unsigned longe unsigned long longforem do mesmo tamanho.
Keith Thompson
@RichieThomas Isso também faz parte. Isso quer dizer que o máximo de long, long longetc. depende do sistema: Se você der uma olhada, limits.hverá pelo menos no Unices que o valor máximo para ints depende do tamanho da palavra do sistema.
Pryftan de
1
@Pryftan Dê uma olhada na série 68000 da Motorola, também a série Intel x86 mais antiga (voltando para 8086 e 8088).
Keith Thompson
10

size_t tem uma restrição específica.

Citando de http://www.cplusplus.com/reference/cstring/size_t/ :

Alias ​​de um dos tipos de inteiro sem sinal fundamentais.

É um tipo capaz de representar o tamanho de qualquer objeto em bytes : size_t é o tipo retornado pelo operador sizeof e é amplamente utilizado na biblioteca padrão para representar tamanhos e contagens.

Não é intercambiável unsigned intporque o tamanho de inté especificado pelo modelo de dados. Por exemplo, LLP64 usa um de 32 bits inte ILP64 usa um de 64 bits int.

DrYap
fonte
5
De onde vem essa citação? (Não é do padrão C.)
Keith Thompson
2
A pergunta está marcada c . O padrão C ++ não tem relação com C.
IInspeitável,
7

size_t é usado para armazenar tamanhos de objetos de dados e é garantido ser capaz de manter o tamanho de qualquer objeto de dados que a implementação de C específica pode criar. Este tipo de dados pode ser menor (em número de bits), maior ou exatamente igual a unsigned int.

Thomas Padron-McCarthy
fonte
4

Além das outras respostas, também documenta o código e diz às pessoas que você está falando sobre o tamanho dos objetos na memória

Ed Heal
fonte
Bom ponto. Um appleé uma maçã , um size_té um tamanho ...
dom_beau
2

size_t type é um tipo de inteiro não assinado de base da linguagem C / C ++. É o tipo de resultado retornado pelo operador sizeof. O tamanho do tipo é escolhido de forma que possa armazenar o tamanho máximo de um array teoricamente possível de qualquer tipo. Em um sistema de 32 bits size_t levará 32 bits, em um de 64 bits 64 bits. Em outras palavras, uma variável do tipo size_t pode armazenar com segurança um ponteiro. A exceção são os ponteiros para funções de classe, mas este é um caso especial. Embora size_t possa armazenar um ponteiro, é melhor usar outro tipo inteiro sem sinal uintptr_t para esse propósito (seu nome reflete sua capacidade). Os tipos size_t e uintptr_t são sinônimos. O tipo size_t é geralmente usado para contadores de loop, indexação de array e aritmética de endereço. O valor máximo possível do tipo size_t é constante SIZE_MAX.

user2873459
fonte
1
size_tpode armazenar o tamanho de qualquer objeto único. Um ponteiro pode apontar para qualquer byte de qualquer objeto. Você pode ter um sistema com, por exemplo, um espaço de endereço de 64 bits que limita o tamanho de qualquer objeto a 2 ** 32-1 bytes. Não há garantia de que size_te uintptr_tsejam do mesmo tipo.
Keith Thompson
1

Em palavras simples, size_t é dependente da plataforma e também da implementação, ao passo que o unsigned int depende apenas da plataforma.

Kaushal Billore
fonte