Чи розмір C "int" становить 2 байти або 4 байти?


168

Чи займає змінна Integer в C 2 байти або 4 байти? Від яких факторів це залежить?

Більшість підручників кажуть, що цілі змінні займають 2 байти. Але коли я запускаю програму, друкуючи послідовні адреси масиву цілих чисел, вона показує різницю в 4.



1
intє лише одним із кількох цілих типів. Ви запитували про розмір "ціле число"; ви, ймовірно, мали намір запитати про розмір int.
Кіт Томпсон

3
І вам слід знайти кращі підручники. У підручнику, в якому сказано, що int2 байти (а), ймовірно, посилається на стару систему, і (б) не дає зрозуміти, що розмір буде змінюватися від однієї системи до іншої. Найкраща книга на C - "Мова програмування на C" Керніган та Річі, хоча вона передбачає певний досвід програмування. Дивіться також питання 18.10 про comp.lang.c FAQ .
Кіт Томпсон

2
Спробуйте #define int int64_tна 64-бітній платформі, так що ні. Просто використовуйте sizeof. ;-)
netcoder

Відповіді:


183

Я знаю, що це дорівнює sizeof(int). Розмір intсправді залежить від компілятора. Ще в той день, коли процесорів було 16 біт, а intбуло 2 байти. На сьогодні це найчастіше 4 байти як в 32-бітових, так і в 64-бітних системах.

Однак використання sizeof(int)найкращого способу отримати розмір цілого числа для конкретної системи, на якій виконується програма.

EDIT: виправлено неправильне твердження, що intстановить 8 байт у більшості 64-бітних систем. Наприклад, це 4 байти на 64-бітній GCC.


31
@RajivPrathap: Ну, це залежить від компілятора, але компілятор вирішує, чи це також залежить від машини. :)
користувач541686

2
Якщо вам потрібен розмір для препроцесора, ви можете перевірити заздалегідь задані макроси, такі як INT_MAX. Якщо значення не таке, яке очікується вашим кодом, то розмір байта int відрізняється від поточної компіляції / комбінації платформи.
Walt Sellers

3
Не тільки від машини залежить, це також залежить від операційної системи, яка працює на машині. Наприклад, у Win64 довгий 4 байти, а в Linux64 - 8 байт.
Джем Кальйонку

9
неправильно. у більшості 64-розрядних систем int все ще 4 байти en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models
phuclv

7
sizeof(int)може мати будь-яке значення 1. Байт не повинен бути 8 біт, а деякі машини не мають 8-бітової адресируемой одиниці (що в основному є визначенням байта в стандарті). Без додаткової інформації відповідь не правильна.
занадто чесний для цього сайту

102

Це один із пунктів у C, який спочатку може бути заплутаним, але стандарт C визначає лише мінімальний діапазон для цілих типів, який гарантовано підтримується. intгарантовано зможе утримувати від -32767 до 32767, що вимагає 16 біт. У цьому випадку int, це 2 байти. Однак реалізація вільна вийти за межі цього мінімуму, оскільки ви побачите, що багато сучасних компіляторів роблять int32-бітові (що також означає 4 байти досить всюди).

Причина, у якій у вашій книжці є 2 байти, швидше за все, у тому, що вона стара. Свого часу це було нормою. Загалом, ви завжди повинні використовувати sizeofоператор, якщо вам потрібно дізнатися, скільки байтів він знаходиться на платформі, яку ви використовуєте.

Для вирішення цього питання C99 додав нові типи, де ви можете чітко запитати певне розмірне ціле число, наприклад, int16_tабо int32_t. До цього не існувало універсального способу отримання цілого числа певної ширини (хоча більшість платформ надавали подібні типи на основі платформи).


7
@nevanking: На машині для доповнення двох (яка є кожною машиною, яку я знаю ...), так. Але, C не гарантує, що так буде.
FatalError

@nevanking Я абсолютно новий в C, але чи не це 32767, бо в іншому випадку він би використовував ще один біт | байт? Уявіть, я можу вмістити 3 цифри (0 або 1), тому я можу перейти від 000 до 111 (що становить десятковий 7). 7 прямо перед показником 2. Якщо я міг би пройти до 8 (1000), я міг би використовувати ці 4 цифри аж до 15! Наприклад, 32767 знаходиться прямо перед показником 2, вичерпуючи всі наявні у ньому біти.
RGS

3
@RSerrao Я не є експертом з C, але AFAIK для позитивних цифр - це менше, ніж максимальне від’ємне число. Так -8 до 7, -256 до 255 тощо. Негативні числа не повинні рахувати нуль.
король Неван

1
"16 біт. У цьому випадку int - 2 байти" може бути помилковим, якщо CHAR_BIT дорівнює 16, sizeof (int) може бути 1 байт (або char).
12431234123412341234123

6
@nevanking: лише якщо ви вважаєте, що представлення додатка 2 для підписаного int. C не робить цього припущення. Системи доповнення та значення значень 1 не можуть представляти -3276816 біт; скоріше, вони мають два уявлення про нуль (позитивне та негативне). Тому мінімальний діапазон для intце [-32767..32767].
Джон Боде

33

Конкретної відповіді немає. Це залежить від платформи. Це визначено реалізацією. Це може бути 2, 4 або щось інше.

Ідея intполягала в тому, що він повинен відповідати натуральному розміру слова на даній платформі: 16 біт на 16-бітних платформах, 32 біт на 32-бітних платформах, 64 біт на 64-бітних платформах, ви отримуєте ідею. Однак для зворотної сумісності деякі компілятори вважають за краще дотримуватися 32-розрядних даних intнавіть на 64-бітних платформах.

Час 2-байтового intчасу давно минув (16-бітні платформи?), Якщо ви не використовуєте якусь вбудовану платформу з 16-бітовим розміром слова. Ваші підручники, мабуть, дуже старі.


2
The idea behind int was that it was supposed to match the natural "word" size on the given platform- Це те, що я шукав. Будь-яка ідея, в чому може бути причина? У вільному світі int може займати будь-яку кількість послідовних байтів у пам'яті, правда? 8, 16 що завгодно
благаббар

19

Відповідь на це питання залежить від того, яку платформу ви використовуєте.
Але незалежно від платформи, ви можете надійно припустити наступні типи:

 [8-bit] signed char: -127 to 127
 [8-bit] unsigned char: 0 to 255
 [16-bit]signed short: -32767 to 32767
 [16-bit]unsigned short: 0 to 65535
 [32-bit]signed long: -2147483647 to 2147483647
 [32-bit]unsigned long: 0 to 4294967295
 [64-bit]signed long long: -9223372036854775807 to 9223372036854775807
 [64-bit]unsigned long long: 0 to 18446744073709551615

3
Хтось відредагував вашу публікацію, щоб "виправити" діапазони, але я не впевнений, чи відповідає ваша редакція адекватно вашим наміром. Він передбачає реалізацію комплексу двох, що в більшості випадків буде правдою , але не у всіх. Оскільки ваша відповідь конкретно вказує на залежність від реалізації, я думаю, що редагування, ймовірно, невірно. Якщо ви згодні, будь ласка, скасуйте зміни.
Коді Грей

1
@ k06a ваша редакція була неправильною . Ви спеціально змінили початкові діапазони на 2-доповнювальні діапазони - це не ті, які вказані у стандарті C.
Антті Хаапала

@CodyGray це коливається вперед і назад, будучи доповненням 1 для останніх 3 років, і ОП нічого не говорив, тому я повернув редагування, яке змінило його на додаток 2 на "виправити діапазони", оскільки в ньому сказано, що "ви можете надійно припустити" , що все ще не зовсім так.
Антті Хаапала

13

Чи займає змінна Integer в C 2 байти або 4 байти?

Це залежить від платформи, яку ви використовуєте, а також від налаштування компілятора. Єдина авторитетна відповідь - використовувати sizeofоператор, щоб побачити, наскільки велике ціле число у вашій конкретній ситуації.


Від яких факторів це залежить?

Діапазон, можливо, найкраще розглядати, а не розмір . І те й інше буде відрізнятись на практиці, хоча набагато більш дурним є вибір змінних типів за діапазоном, ніж розмір, як ми побачимо. Важливо також зазначити, що стандарт спонукає нас розглянути вибір цілих типів на основі діапазону, а не розміру , але поки що ігноруємо стандартну практику , і дозвольмо нашій цікавості вивчити sizeof, байти CHAR_BITта ціле представлення ... давайте поринемо кроляча нора і переконаємося в цьому ...


sizeof, байти та CHAR_BIT

Наступне твердження, взяте зі стандарту С (пов'язане з вище), описує це словами, які, на мою думку, не можуть бути покращені.

sizeofОператор дає розмір (в байтах) свого операнда, який може бути вираз в дужках або ім'я типу. Розмір визначається від типу операнду.

Якщо припустити чітке розуміння, це призведе нас до дискусії про байти . Зазвичай прийнято вважати, що байт - це вісім біт, коли насправді CHAR_BITговорить про те, скільки бітів у байті . Це лише один з тих нюансів, який не враховується, коли йдеться про загальні два (або чотири) байтові цілі числа .

Давайте закінчимо речі поки що:

  • sizeof => розмір у байтах та
  • CHAR_BIT => кількість бітів у байтах

Таким чином, залежно від вашої системи sizeof (unsigned int)може бути будь-яке значення, що перевищує нуль (не лише 2 або 4), як якщо б CHAR_BITце 16, то в одному (шістнадцять бітовому) байті є достатньо бітів у ньому, щоб представляти шістнадцять бітових цілих чисел, описаних стандарти (цитується нижче). Це не обов'язково корисна інформація, чи не так? Давайте поглибимося глибше ...


Представлення цілого числа

Стандарт C визначає мінімальну точність / діапазон для всіх стандартних цілих типів (і CHAR_BIT, також, fwiw) тут . Виходячи з цього, ми можемо отримати мінімум для того, скільки бітів потрібно для зберігання значення , але ми можемо просто вибрати наші змінні на основі діапазонів . Тим не менш, величезна частина деталей, необхідних для цієї відповіді, знаходиться тут. Наприклад, наступне, що стандарт unsigned intвимагає (принаймні) шістнадцяти біт зберігання:

UINT_MAX                                65535 // 2¹⁶ - 1

Таким чином, ми можемо бачити, що unsigned intпотрібно ( принаймні ) 16 біт , саме там ви отримуєте два байти (якщо вважати, що CHAR_BITце 8) ... і пізніше, коли ця межа зросла до 2³² - 1, люди замість цього заявляли 4 байти. Це пояснює явища, які ви спостерігали:

Більшість підручників кажуть, що цілі змінні займають 2 байти. Але коли я запускаю програму, друкуючи послідовні адреси масиву цілих чисел, вона показує різницю в 4.

Ви використовуєте стародавній підручник та компілятор, який навчає вас портативному C; автор, який написав ваш підручник, може навіть не усвідомлювати CHAR_BIT. Вам слід оновити підручник (і компілятор) і прагнути пам’ятати, що ІТ - це постійно розвивається сфера, яку вам потрібно випереджати, щоб конкурувати… Хоча про це хоч і; давайте подивимося, які ще непереносимі секрети зберігаються в основі цілих цілих байтів ...

Біти цінності - це те, що, як видається, вважають поширеними помилками. У наведеному вище прикладі використовується unsignedцілий тип, який, як правило, містить лише біти значення, тому диявола легко пропустити в деталях.

Підпишіть біти ... У наведеному вище прикладі я наводив UINT_MAXверхню межу, unsigned intоскільки це тривіальний приклад для отримання значення 16з коментаря. Для підписаних типів, щоб розрізняти позитивні та негативні значення (це знак), нам також потрібно включити біт знаків.

INT_MIN                                -32768 // -(2¹⁵)
INT_MAX                                +32767 // 2¹⁵ - 1

Біт прокладки ... Хоча не часто зустрічаються комп’ютери, які мають цілі біти в цілих числах, стандарт C дозволяє це робити; деякі машини (тобто ця ) реалізують великі цілі типи, комбінуючи два менших (підписаних) цілих числа разом ... і коли ви поєднаєте підписані цілі числа, ви отримаєте марно розрядний знак. Цей витрачений біт вважається забиттям у C. Інші приклади бітів оббивки можуть включати біти парності та біти ловушки .


Як бачимо, стандарт здається, що він заохочує враховувати діапазони на зразок INT_MIN.. INT_MAXта інші мінімальні / максимальні значення від стандарту при виборі цілих чисел, і не відштовхується від розміру, оскільки існують й інші найтонші фактори, які, можливо, будуть забуті, такі як CHAR_BITбіт підкладки, який може вплинути на значення sizeof (int)(тобто загальні помилкові уявлення про двобайтові та чотирибайтні цілі числа нехтують цими деталями).


13

C99 N1256 стандартна тяга

http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

Розмір intта всі цілі типи визначено реалізацією, C99 визначає лише:

  • гарантії мінімального розміру
  • відносні розміри між типами

5.2.4.2.1 "Розміри цілих типів <limits.h>" дають мінімальні розміри:

1 [...] Значення, визначені їх реалізацією, повинні бути рівними або більшими за величиною (абсолютною величиною) значенням, показаним [...]

  • UCHAR_MAX 255 // 2 8 - 1
  • USHRT_MAX 65535 // 2 16 - 1
  • UINT_MAX 65535 // 2 16 - 1
  • ULONG_MAX 4294967295 // 2 32 - 1
  • ULLONG_MAX 18446744073709551615 // 2 64 - 1

6.2.5 "Типи" потім говорить:

8 Для будь-яких двох цілочисельних типів з однаковою підписаністю та різним цілим числом перетворення (див. 6.3.1.1) діапазон значень типу з меншим цілочисловим рангом перетворення є піддіапазоном значень іншого типу.

та 6.3.1.1 "Булеві символи та цілі числа" визначає відносні ранги перетворення:

1 Кожен тип цілого числа має цілочисельний ранг перетворення, визначений таким чином:

  • Ранг long long int повинен бути більшим, ніж ранг long int, який буде більшим, ніж ранг int, який буде більшим, ніж ранг короткого int, який повинен бути більшим за ранг підписаних знаків.
  • Ранг будь-якого непідписаного цілого числа повинен дорівнювати рангу відповідного підписаного цілого числа, якщо такий є.
  • Для всіх цілих типів T1, T2 і T3, якщо T1 має більший ранг, ніж T2 і T2 має більший ранг, ніж T3, то T1 має більший ранг, ніж T3

8

Єдині гарантії полягають у тому, що вони charповинні бути принаймні 8 біт шириною shortі intповинні бути принаймні 16 біт шириною, а longтакож принаймні 32 біти шириною, і що sizeof (char)<= sizeof (short)<= sizeof (int)<= sizeof (long)(те ж саме стосується і безпідписаних версій цих типів ).

int може бути від 16 до 64 біт шириною, залежно від платформи.


6

Чи розмір C "int" становить 2 байти або 4 байти?

Відповідь "так" / "ні" / "можливо" / "може бути, ні".

Мова програмування на C визначає наступне: найменша адресна одиниця, відома charі також називається "байт" , є точно CHAR_BITбітами в ширину, деCHAR_BIT не менше 8.

Отже, один байт у C не обов'язково є октетом , тобто 8 біт. Раніше одна з перших платформ для запуску коду С (і Unix) мала 4-байт int- але в цілому intбуло 36 біт, тому що CHAR_BITбуло 9!

intповинен бути натуральним цілим розміром для платформи, яка має принаймні-32767 ... 32767 діапазон . Ви можете отримати розмір intбайтів платформи за допомогою sizeof(int); коли ви помножите це значення на то, CHAR_BITви дізнаєтесь, наскільки воно широке в бітах.


Хоча 36-бітні машини в основному мертві, все ще є платформи з не-8-бітовими байтами. Лише вчора виникло запитання про MCU Texas Instruments з 16-бітовими байтами , який має компілятор, сумісний з C99, C11.

На TMS320C28x , здається , що char, shortі intє всі 16 біт, і , отже , один байт. long intстановить 2 байти і long long intстановить 4 байти. Краса C полягає в тому, що можна все-таки написати ефективну програму для такої платформи та навіть зробити це портативно!


"тому що CHAR_BIT був 9!" - У них тоді було 362880 бітових обчислень !? Вражає.
Джош Десмонд

5

Переважно це залежить від платформи, яку ви використовуєте. Це залежить від компілятора до компілятора. Зараз у більшості компіляторів int становить 4 байти . Якщо ви хочете перевірити, що використовує ваш компілятор, ви можете використовувати sizeof(int).

main()
{
    printf("%d",sizeof(int));
    printf("%d",sizeof(short));
    printf("%d",sizeof(long));
}

Єдине, що обіцяє компілятор c - це те, що розмір короткого повинен бути рівним або меншим, ніж int, а розмір long повинен бути рівним або більшим, ніж int. Так, якщо розмір int дорівнює 4, то розмір короткого може бути 2 або 4, але не більший ніж це. Ім'я справедливо для довгого і внутрішнього. Це також говорить, що розмір коротких і довгих не може бути однаковим.


1
Використання %dдля size_tпараметра - UB.
Пол Р

3

Це залежить від реалізації, але зазвичай x86 та інші популярні архітектури, такі як ARM int, беруть 4 байти. Ви завжди можете перевірити час компіляції, використовуючи sizeof(int)або будь-який інший тип, який ви хочете перевірити.

Якщо ви хочете переконатися, що ви використовуєте тип певного розміру, використовуйте типи в <stdint.h>


2
#include <stdio.h>

int main(void) {
    printf("size of int: %d", (int)sizeof(int));
    return 0;
}

Це повертає 4, але це, мабуть, залежить від машини.


1

Чи розмір C "int" становить 2 байти або 4 байти?

Чи займає змінна Integer в C 2 байти або 4 байти?

C дозволяє "байтам" бути чимось іншим, ніж 8 біт на "байт".

CHAR_BIT кількість біт для найменшого об’єкта, який не є бітовим полем (байтом) C11dr §5.2.4.2.1 1

Значення чогось, ніж 8, все частіше зустрічається. Для максимальної портативності використовуйте, CHAR_BITа не 8. Розмір a intв бітах в C дорівнює sizeof(int) * CHAR_BIT.

#include <limits.h>
printf("(int) Bit size %zu\n", sizeof(int) * CHAR_BIT);

Від яких факторів це залежить?

Розмір intбітів зазвичай становить 32 або 16 біт. Зазначені мінімальні діапазони :

мінімальне значення для об'єкта типу int INT_MIN-32767
Максимальне значення для об'єкта типу int INT_MAX+32767
C11dr §5.2.4.2.1 1

Мінімальний діапазон для intсил битого розміру , щоб бути по крайней мере , 16 - навіть якщо процесор був «8-біт». Розмір, як 64 біт, спостерігається в спеціалізованих процесорах. Інші значення, такі як 18, 24, 36 тощо, мали місце на історичних платформах або принаймні теоретично можливі. Сучасне кодування рідко турбується про не-потужність-2int розміри бітів .

Процесор та архітектура комп'ютера керують процесором int вибір розміру бітів.

Але навіть при 64-розрядних процесорах розмір компілятора intможе бути 32-розрядним з міркувань сумісності, оскільки великі бази коду залежать від int32-бітового (або 32/16).


-1

Це хороше джерело для відповіді на це питання.

Але це питання є своєрідною істиною, яка завжди відповідає "Так. І те й інше".

Це залежить від вашої архітектури. Якщо ви збираєтеся працювати на 16-бітній машині або менше, це не може бути 4 байти (= 32 біта). Якщо ви працюєте на 32-бітній або кращій машині, її довжина 32-бітна.

Щоб розібратися, підготуйте програму вивести щось читабельне та скористайтеся функцією "sizeof". Це повертає розмір у байтах заявленого типу даних. Але будьте поважні, використовуючи це з масивами.

Якщо ви заявляєте, int t[12];він поверне 12 * 4 байт. Щоб отримати довжину цього масиву, просто використовуйте sizeof(t)/sizeof(t[0]). Якщо ви збираєтеся збирати функцію, яка повинна обчислювати розмір масиву відправки, пам’ятайте, що якщо

typedef int array[12];
int function(array t){
    int size_of_t = sizeof(t)/sizeof(t[0]);
    return size_of_t;
}
void main(){
    array t = {1,1,1};  //remember: t= [1,1,1,0,...,0]
    int a = function(t);    //remember: sending t is just a pointer and equal to int* t
   print(a);   // output will be 1, since t will be interpreted as an int itselve. 
}

Таким чином, це навіть не поверне щось інше. Якщо ви визначите масив і спробуйте отримати довжину після цього, використовуйте sizeof. Якщо ви надсилаєте масив функції, пам'ятайте, що значення відправлення є лише вказівником на перший елемент. Але у випадку одного, ви завжди знаєте, який розмір має ваш масив. Випадок другий можна з'ясувати, визначивши дві функції та пропустивши деяку продуктивність. Визначте функцію (масив t) та визначте функцію2 (масив t, int size_of_t). Викличте "функцію (t)" - виміряйте довжину деякими копіювальними роботами та надішліть результат функції function2, де ви можете робити все, що завгодно, із змінними розмірами масиву.


Надане посилання є поганим джерелом інформації, оскільки воно передбачає речі, які не завжди є правдивими (наприклад char, завжди signed)
Андрій Даміан-Фекете
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.