Різниця між size_t та неподписаним int?


107

Я так розгублений size_t. Я шукав в Інтернеті і всюди згадував, що size_tце неподписаний тип, тому він може представляти лише негативні значення.

Перше моє запитання: якщо він використовується для представлення лише негативних значень, чому б ми не використовували його unsigned intзамість size_t?

Мій друге питання полягає в наступному : size_tі unsigned intвзаємозамінні чи ні? Якщо ні, то чому?

І може хтось надати мені хороший приклад size_tі коротко його роботи?


5
typedef /*This part is implementation dependent */ size_t;
P0W

5
можливий дублікат непідписаного int vs. size_t

Відповіді:


87

якщо це використовується для представлення негативного значення, то чому б ми не використовували його unsigned intзамістьsize_t

Тому що unsigned intце не єдиний цілочисельний тип без підпису. size_tможе бути будь-який з unsigned char, unsigned short, unsigned int, unsigned longабо unsigned long long, в залежності від реалізації.

Друге питання - це size_tі unsigned intє взаємозамінними чи ні, і якщо ні, то чому?

Вони не взаємозамінні з причини, поясненої вище ^^.

І чи може хтось надати мені хороший приклад size_t та його короткої роботи?

Я не зовсім розумію, що ви маєте на увазі під "його короткою роботою". Він працює як і будь-який інший непідписаний тип (зокрема, як тип, на який він введений). Вам рекомендується використовувати, size_tколи ви описуєте розмір об'єкта. Зокрема, sizeofоператор і різні стандартні функції бібліотеки, такі як strlen(), повертаються size_t.

Бонус: ось хороша стаття про size_t(і тісно пов'язаний ptrdiff_tтип). Це дуже добре пояснює, чому ви повинні використовувати його.


1
Як саме можна size_tбути unsigned char? Це в стандарті це дозволено? Я маю на увазі під цією ідеєю, як від когось можна очікувати використання calloc()(і сім'ї) strlen()тощо? Це мені здається абсурдним.
Прифтан

Я думаю size_t, що визначено в стандарті як "цілий цілий без підпису", але не вимагає, щоб він був таким, як будь-який unsigned {char, short, int, long, long long}.
Пол Ханкін

80

У С є 5 стандартних цілих цілей без підпису:

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

з різними вимогами до їх розмірів та діапазонів (коротко, діапазон кожного типу є підмножиною діапазону наступного типу, але деякі з них можуть мати той самий діапазон).

size_tє typedef(тобто псевдонімом) для деякого неподписаного типу (ймовірно, одного з перерахованих вище, але, можливо, розширеного неподписаного цілого числа , хоча це малоймовірно). Це тип, отриманий sizeofоператором.

В одній системі це може мати сенс використовувати unsigned intдля представлення розмірів; з іншого, це може мати більше сенсу використовувати unsigned longабо unsigned long long. ( size_tнавряд чи це буде unsigned charабо unsigned short, але це дозволено).

Мета size_t- позбавити програміста від турботи про те, який із заздалегідь визначених типів використовується для представлення розмірів.

Код, який передбачає, що sizeofприбутковість unsigned intне є портативною. Код, який передбачає, що він дає a size_t, швидше за все є портативним.


6
Я думаю, це має бути прийнятою відповіддю, оскільки це пояснює, чому слід використовувати size_t
kuchi

@ keith-thompson, значить, це означає, що конкретний тип (тобто unsigned int, unsigned longтощо), який size_tвідповідає, залежить від машини, на якій виконується код? тобто на одній машинній архітектурі вона відповідає, unsigned intа на іншій архітектурі вона відповідатиме unsigned longтощо?
Річі Томас

1
@RichieThomas: Це залежить від реалізації C. Два різних компіляторів на тій же архітектурі , може вибрати різні типи для size_t, особливо якщо, наприклад, unsigned longі unsigned long longмають однаковий розмір.
Кіт Томпсон

@RichieThomas Це теж частина цього. Тобто сказати , що макс long, і long longт.д. дійсно залежить від системи: Якщо ви подивіться на limits.hвас, по крайней мере , під Юнікс видно , що максимальне значення для Інтс залежить від розміру слова системи.
Прифтан

1
@Pryftan Погляньте на серію Motorola 68000, також старіші серії Intel x86 (повертаючись до 8086 та 8088).
Кіт Томпсон

10

size_t має специфічне обмеження.

Цитування з http://www.cplusplus.com/reference/cstring/size_t/ :

Псевдонім одного з основних цілочислених неподписаних типів.

Це тип, здатний представляти розмір будь-якого об'єкта в байтах : size_t - тип, повернений оператором sizeof і широко використовується в стандартній бібліотеці для представлення розмірів і підрахунків.

Він не взаємозамінний, unsigned intоскільки розмір intвизначається моделлю даних. Наприклад, LLP64 використовує 32-розрядний, intа ILP64 - 64-розрядний int.


5
Звідки ця цитата? (Це не від стандарту С.)
Кіт Томпсон,

2
Питання позначено тегом c . Стандарт C ++ не має
стосунку

7

size_t використовується для зберігання розмірів об'єктів даних і гарантовано зможе утримувати розмір будь-якого об'єкта даних, який може створити конкретна реалізація C. Цей тип даних може бути меншим (за кількістю біт), більшим або точно таким же, як неподписаний int.


4

Крім інших відповідей, він також документує код і повідомляє людям, що ви говорите про розмір об'єктів у пам'яті


Гарна думка. appleЦе яблуко , А size_tце розмір ...
dom_beau

2

type size_t - це базовий цілий цільовий тип мови C / C ++. Це тип результату, що повертається оператором sizeof. Розмір типу обраний таким чином, щоб він міг зберігати максимальний розмір теоретично можливого масиву будь-якого типу. Для 32-розрядної системи розмір_t візьме 32 біти, на 64-розрядної - 64 біта. Іншими словами, змінна типу size_t може безпечно зберігати покажчик. Виняток становлять вказівники на функції класу, але це особливий випадок. Хоча size_t може зберігати вказівник, краще використовувати інший цілий цілий тип uintptr_t для цієї мети (його назва відображає його можливості). Типи size_t та uintptr_t є синонімами. Тип size_t зазвичай використовується для лічильників циклу, індексації масивів та арифметики адрес. Максимально можливе значення типу size_t є постійним SIZE_MAX.


1
size_tможе зберігати розмір будь-якого одного об’єкта. Вказівник може вказувати на будь-який байт будь-якого об’єкта. Ви можете мати систему з, наприклад, 64-бітовим адресним простором, який обмежує розмір будь-якого одного об’єкта до 2 ** 32-1 байт. Немає жодних гарантій, що вони size_tі uintptr_tтого ж типу.
Кіт Томпсон

1

Простими словами size_t залежить від платформи, а також від реалізації, тоді як неподписаний int залежить лише від платформи.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.