Apakah ukuran C "int" 2 byte atau 4 byte?


169

Apakah variabel Integer dalam C menempati 2 byte atau 4 byte? Apa faktor yang menjadi sandarannya?

Sebagian besar buku teks mengatakan variabel integer menempati 2 byte. Tetapi ketika saya menjalankan program mencetak alamat berturut-turut dari array bilangan bulat itu menunjukkan perbedaan 4.



1
inthanyalah salah satu dari beberapa tipe integer . Anda bertanya tentang ukuran "integer"; Anda mungkin bermaksud bertanya tentang ukuran int.
Keith Thompson

3
Dan Anda harus menemukan buku pelajaran yang lebih baik. Buku teks yang mengatakan a intadalah 2 byte (a) mungkin merujuk pada sistem lama, dan (b) gagal menjelaskan bahwa ukurannya akan bervariasi dari satu sistem ke sistem lainnya. Buku terbaik tentang C adalah "Bahasa Pemrograman C" oleh Kernighan dan Ritchie, meskipun mengasumsikan beberapa pengalaman pemrograman. Lihat juga mempertanyakan 18,10 dari comp.lang.c FAQ .
Keith Thompson

2
Coba #define int int64_tpada platform 64-bit, begitu juga keduanya. Gunakan saja sizeof. ;-)
netcoder

Jawaban:


183

Saya tahu itu setara dengan sizeof(int). Ukuran suatu intkompiler benar-benar tergantung. Kembali pada hari itu, ketika prosesor 16 bit, intadalah 2 byte. Saat ini, ini paling sering 4 byte pada sistem 32-bit dan 64-bit.

Tetap saja, menggunakan sizeof(int)adalah cara terbaik untuk mendapatkan ukuran bilangan bulat untuk sistem tertentu yang dijalankan oleh program.

EDIT: Memperbaiki pernyataan salah yang int8 byte pada kebanyakan sistem 64-bit. Misalnya, 4 byte pada GCC 64-bit.


31
@RajivPrathap: Ya, itu bergantung pada kompiler, tetapi kompiler memutuskan apakah itu juga bergantung pada mesin. :)
user541686

2
Jika Anda membutuhkan ukuran untuk preproksi, Anda dapat memeriksa makro yang telah ditentukan sebelumnya seperti INT_MAX. Jika nilainya bukan yang diharapkan oleh kode Anda, maka ukuran byte int berbeda dengan kombinasi kompiler / platform saat ini.
Penjual Walt

3
Bukan hanya ketergantungan mesin, itu juga tergantung pada sistem operasi yang berjalan pada mesin. Misalnya panjang di Win64 adalah 4 byte sedangkan panjang di Linux64 adalah 8 byte.
Cem Kalyoncu

9
salah. pada sebagian besar sistem 64-bit int masih 4 byte en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models
phuclv

7
sizeof(int)dapat berupa nilai apa pun dari 1. Byte tidak harus 8 bit dan beberapa mesin tidak memiliki unit addressable 8 bit (yang pada dasarnya adalah definisi byte dalam standar). Jawabannya tidak benar tanpa informasi lebih lanjut.
terlalu jujur ​​untuk situs ini

103

Ini adalah salah satu poin dalam C yang dapat membingungkan pada awalnya, tetapi standar C hanya menentukan rentang minimum untuk tipe integer yang dijamin akan didukung. intdijamin dapat menahan -32767 hingga 32767, yang membutuhkan 16 bit. Dalam hal ini int,, adalah 2 byte. Namun, implementasi bebas untuk melampaui batas minimum tersebut, karena Anda akan melihat bahwa banyak kompiler modern membuatint 32-bit (yang juga berarti 4 byte dengan cukup di mana-mana).

Alasan buku Anda mengatakan 2 byte kemungkinan besar karena sudah tua. Pada suatu waktu, ini adalah norma. Secara umum, Anda harus selalu menggunakansizeof operator jika Anda perlu mengetahui berapa byte pada platform yang Anda gunakan.

Untuk mengatasinya, C99 menambahkan jenis baru di mana Anda dapat secara eksplisit meminta bilangan bulat berukuran tertentu, misalnya int16_tatau int32_t. Sebelum itu, tidak ada cara universal untuk mendapatkan bilangan bulat dengan lebar tertentu (meskipun sebagian besar platform menyediakan tipe yang serupa pada basis per-platform).


7
@nevanking: Pada mesin pelengkap dua (yang setiap mesin saya tahu ...), ya. Tapi, C tidak menjamin hal itu terjadi.
FatalError

@nevanking Saya benar-benar baru ke C, tapi bukan 32767 karena kalau tidak akan menggunakan bit | byte lain? Bayangkan, saya bisa memegang 3 digit (0 atau 1), jadi saya bisa beralih dari 000 menjadi 111 (yang merupakan desimal 7). 7 tepat sebelum eksponen 2. Jika saya bisa pergi sampai 8 (1000) maka saya bisa menggunakan 4 digit hingga 15! Seperti 32767 tepat sebelum eksponen 2, melelahkan semua bit | byte yang telah tersedia.
RGS

3
@Rerrao Saya bukan ahli C juga tetapi AFAIK untuk angka positif itu kurang satu dari angka negatif maksimum. Jadi -8 hingga 7, -256 hingga 255 dan seterusnya. Angka negatif tidak harus menghitung nol.
raja nevan

1
"16 bit. Dalam hal ini, int, adalah 2 byte" dapat salah, jika CHAR_BIT adalah 16, sizeof (int) dapat menjadi 1 byte (atau char).
12431234123412341234123

6
@nevanking: hanya jika Anda menganggap representasi pelengkap 2 untuk ditandatangani int. C tidak membuat asumsi itu. Sistem komplemen dan sign-magnitude 1 tidak dapat mewakili -32768dalam 16 bit; sebaliknya, mereka memiliki dua representasi untuk nol (positif dan negatif). Itu sebabnya kisaran minimum untuk intadalah [-32767..32767].
John Bode

33

Tidak ada jawaban spesifik. Itu tergantung pada platform. Ini adalah implementasi yang ditentukan. Itu bisa 2, 4 atau yang lainnya.

Gagasan di belakang intadalah bahwa itu seharusnya cocok dengan ukuran "kata" alami pada platform yang diberikan: 16 bit pada platform 16-bit, 32 bit pada platform 32-bit, 64 bit pada platform 64-bit, Anda mendapatkan idenya. Namun, untuk tujuan kompatibilitas ke belakang, beberapa kompiler lebih suka tetap menggunakan 32-bit intbahkan pada platform 64-bit.

Waktu 2-byte intsudah lama hilang (platform 16-bit?) Kecuali Anda menggunakan platform tertanam dengan ukuran kata 16-bit. Buku teks Anda mungkin sudah sangat tua.


2
The idea behind int was that it was supposed to match the natural "word" size on the given platform- Ini yang saya cari. Adakah yang tahu alasannya? Di dunia bebas, int bisa menempati sejumlah byte berturut-turut dalam memori bukan? 8, 16 terserah
bholagabbar

19

Jawaban untuk pertanyaan ini tergantung pada platform yang Anda gunakan.
Namun terlepas dari platform, Anda dapat dengan andal berasumsi tipe-tipe berikut:

 [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
Seseorang mengedit posting Anda untuk "memperbaiki" rentang, tetapi saya tidak yakin apakah hasil edit Anda mencerminkan niat Anda secara memadai. Ini mengasumsikan implementasi komplemen dua, yang akan benar dalam banyak kasus, tetapi tidak semua. Karena jawaban Anda secara khusus menunjukkan ketergantungan implementasi, saya pikir hasil edit mungkin salah. Jika Anda setuju, pastikan untuk mengembalikan hasil edit.
Cody Gray

1
@ k06a hasil edit Anda salah . Anda telah secara khusus mengubah rentang asli menjadi rentang 2-pelengkap - ini bukan yang ditentukan dalam standar C.
Antti Haapala

@CodyGray ini telah berfluktuasi bolak-balik, telah sesuai dengan komplemen 1 untuk 3 tahun terakhir dan OP tidak mengatakan apa-apa jadi saya mengembalikan suntingan yang mengubahnya menjadi komplemen 2 dengan "memperbaiki rentang", karena dikatakan "Anda dapat dengan andal berasumsi" , yang masih belum sepenuhnya benar.
Antti Haapala

13

Apakah variabel Integer dalam C menempati 2 byte atau 4 byte?

Itu tergantung pada platform yang Anda gunakan, serta bagaimana kompiler Anda dikonfigurasi. Satu-satunya jawaban yang berwenang adalah menggunakan sizeofoperator untuk melihat seberapa besar bilangan bulat dalam situasi spesifik Anda.


Apa faktor yang menjadi sandarannya?

Rentang mungkin lebih baik dipertimbangkan, daripada ukuran . Keduanya akan bervariasi dalam praktiknya, meskipun jauh lebih mudah untuk memilih tipe variabel berdasarkan rentang daripada ukuran seperti yang akan kita lihat. Penting juga untuk dicatat bahwa standar mendorong kita untuk mempertimbangkan memilih tipe integer kita berdasarkan rentang daripada ukuran , tetapi untuk sekarang mari kita abaikan praktik standar , dan biarkan rasa ingin tahu kita mengeksplorasi sizeof, byte dan CHAR_BIT, dan representasi integer ... mari kita menggali lebih dalam lubang kelinci dan lihat sendiri ...


sizeof, byte dan CHAR_BIT

Pernyataan berikut, diambil dari standar C (terkait dengan di atas), menjelaskan hal ini dengan kata-kata yang menurut saya tidak dapat diperbaiki.

Itu sizeof Operator menghasilkan ukuran (dalam bytes) dari operan, yang mungkin merupakan ekspresi atau nama kurung dari tipe. Ukurannya ditentukan dari jenis operan.

Dengan asumsi pemahaman yang jelas akan membawa kita ke diskusi tentang byte . Biasanya diasumsikan bahwa byte adalah delapan bit, padahal sebenarnya CHAR_BITmemberitahu Anda berapa banyak bit dalam satu byte . Itu hanya salah satu dari nuansa yang tidak dipertimbangkan ketika berbicara tentang dua (atau empat) byte integer yang umum .

Mari kita selesaikan sejauh ini:

  • sizeof => ukuran dalam byte, dan
  • CHAR_BIT => jumlah bit dalam byte

Dengan demikian, Tergantung pada sistem Anda, sizeof (unsigned int)bisa saja nilai lebih besar dari nol (tidak hanya 2 atau 4), seolah-olah CHAR_BITadalah 16, maka satu (enam belas-bit) byte memiliki bit cukup di dalamnya untuk mewakili enam belas bit integer dijelaskan oleh standar (dikutip di bawah). Itu belum tentu informasi yang berguna, bukan? Mari kita selami lebih dalam ...


Representasi integer

Standar C menentukan presisi / kisaran minimum untuk semua jenis integer standar (dan CHAR_BIT, juga, fwiw) di sini . Dari ini, kita dapat memperoleh minimum untuk berapa banyak bit yang diperlukan untuk menyimpan nilai , tetapi kita mungkin juga hanya memilih variabel berdasarkan rentang . Meskipun demikian, sebagian besar detail yang diperlukan untuk jawaban ini ada di sini. Misalnya, berikut ini yang unsigned intmembutuhkan standar (setidaknya) enam belas bit penyimpanan:

UINT_MAX                                65535 // 2¹⁶ - 1

Dengan demikian kita dapat melihat bahwa unsigned intmemerlukan ( setidaknya ) 16 bit , yang mana Anda mendapatkan dua byte (dengan asumsi CHAR_BIT8 byte ) ... dan kemudian ketika batas itu meningkat menjadi 2³² - 1, orang-orang yang menyatakan 4 byte. Ini menjelaskan fenomena yang telah Anda amati:

Sebagian besar buku teks mengatakan variabel integer menempati 2 byte. Tetapi ketika saya menjalankan program mencetak alamat berturut-turut dari array bilangan bulat itu menunjukkan perbedaan 4.

Anda menggunakan buku teks dan kompiler kuno yang mengajarkan Anda non-portable C; penulis yang menulis buku teks Anda mungkin tidak menyadarinya CHAR_BIT. Anda harus memutakhirkan buku teks (dan kompiler) Anda, dan berusaha untuk mengingat bahwa TI adalah bidang yang terus berkembang sehingga Anda harus tetap terdepan untuk bersaing ... Cukup tentang itu, meskipun; mari kita lihat apa rahasia non-portable lainnya yang disimpan oleh integer bytes ...

Bit nilai adalah apa yang keliru dipahami oleh kesalahpahaman umum. Contoh di atas menggunakan unsignedtipe integer yang biasanya hanya berisi bit nilai, sehingga mudah untuk melewatkan iblis secara detail.

Tanda bit ... Pada contoh di atas saya kutip UINT_MAXsebagai batas atas unsigned intkarena ini adalah contoh sepele untuk mengekstrak nilai 16dari komentar. Untuk tipe yang ditandatangani, untuk membedakan antara nilai positif dan negatif (itu tandanya), kita juga perlu memasukkan bit tanda.

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

Padding bits ... Meskipun tidak umum untuk menjumpai komputer yang memiliki bit padding dalam bilangan bulat, standar C memungkinkan hal itu terjadi; beberapa mesin (yaitu yang ini ) mengimplementasikan tipe integer yang lebih besar dengan menggabungkan dua nilai integer yang lebih kecil (ditandatangani) ... dan ketika Anda menggabungkan integer yang ditandatangani, Anda mendapatkan bit tanda yang terbuang. Bit yang terbuang tersebut dianggap sebagai padding dalam C. Contoh lain dari bit padding mungkin termasuk bit paritas dan bit trap .


Seperti yang Anda lihat, standar tampaknya mendorong rentang pertimbangan seperti INT_MIN.. INT_MAXdan nilai minimum / maksimum lainnya dari standar saat memilih jenis bilangan bulat, dan mencegah bergantung pada ukuran karena ada faktor halus lainnya yang mungkin dilupakan seperti CHAR_BITdan bit bantalan yang mungkin mempengaruhi nilai sizeof (int)(miskonsepsi umum bilangan bulat dua-byte dan empat-byte mengabaikan detail-detail ini).


13

C99 N1256 draft standar

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

Ukuran intdan semua tipe integer lainnya adalah implementasi yang ditentukan, C99 hanya menentukan:

  • jaminan ukuran minimum
  • ukuran relatif antara jenis

5.2.4.2.1 "Ukuran tipe integer <limits.h>" memberikan ukuran minimum:

1 [...] Nilai yang ditentukan implementasi harus sama atau lebih besar dalam besarnya (nilai absolut) dari yang ditunjukkan [...]

  • 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 "Jenis" lalu mengatakan:

8 Untuk setiap dua tipe bilangan bulat dengan keabsahan yang sama dan peringkat konversi integer yang berbeda (lihat 6.3.1.1), kisaran nilai dari tipe dengan peringkat konversi integer yang lebih kecil adalah subrange dari nilai-nilai dari tipe lainnya.

dan 6.3.1.1 "Boolean, karakter, dan bilangan bulat" menentukan peringkat konversi relatif:

1 Setiap tipe integer memiliki peringkat konversi integer yang didefinisikan sebagai berikut:

  • Pangkat long panjang int harus lebih besar dari pangkat panjang int, yang harus lebih besar dari pangkat int, yang harus lebih besar dari pangkat int pendek, yang akan lebih besar dari pangkat char yang ditandatangani.
  • Peringkat dari tipe integer yang tidak ditandatangani harus sama dengan peringkat dari tipe integer yang ditandatangani, jika ada.
  • Untuk semua tipe integer T1, T2, dan T3, jika T1 memiliki peringkat lebih besar dari T2 dan T2 memiliki peringkat lebih besar dari T3, maka T1 memiliki peringkat lebih besar dari T3

8

Satu-satunya jaminan adalah yang charharus memiliki lebar minimal 8 bit, shortdan intharus memiliki lebar setidaknya 16 bit, dan longharus memiliki lebar setidaknya 32 bit, dan itu sizeof (char)<= sizeof (short)<= sizeof (int)<=sizeof (long) (sama juga berlaku untuk versi yang tidak ditandatangani dari tipe-tipe tersebut. ).

int mungkin di mana saja dari 16 hingga 64 bit lebar tergantung pada platform.


6

Apakah ukuran C "int" 2 byte atau 4 byte?

Jawabannya adalah "ya" / "tidak" / "mungkin" / "mungkin tidak".

Bahasa pemrograman C menentukan yang berikut: unit terkecil yang dapat dialamatkan, dikenal oleh chardan juga disebut "byte" , adalah CHAR_BITbit lebar, di manaCHAR_BIT setidaknya 8.

Jadi, satu byte dalam C belum tentu merupakan oktet , yaitu 8 bit. Di masa lalu salah satu platform pertama untuk menjalankan kode C (dan Unix) memiliki 4-byte int- tetapi secara total intmemiliki 36 bit, karena CHAR_BIT9!

intseharusnya merupakan ukuran integer alami untuk platform yang memiliki jangkauan setidaknya-32767 ... 32767 . Anda bisa mendapatkan ukuran intdalam byte platform dengan sizeof(int); ketika Anda mengalikan nilai ini dengan CHAR_BITAnda akan tahu seberapa lebar itu dalam bit.


Sementara mesin 36-bit sebagian besar mati, masih ada platform dengan byte non-8-bit. Baru kemarin ada pertanyaan tentang MCU Texas Instruments dengan byte 16-bit , yang memiliki compiler C99, C11-compliant.

Pada TMS320C28x tampaknya char, shortdan intyang semua 16 bit yang luas, dan karenanya satu byte. long intadalah 2 byte dan long long int4 byte. Keindahan C adalah seseorang masih dapat menulis program yang efisien untuk platform seperti ini, dan bahkan melakukannya dengan cara yang portabel!


"Karena CHAR_BIT berusia 9!" - Mereka memiliki komputasi 362880 bit saat itu !? Impresif.
Josh Desmond

5

Sebagian besar tergantung pada platform yang Anda gunakan. Itu tergantung dari kompiler ke kompiler. Saat ini di sebagian besar kompiler int adalah dari 4 byte . Jika Anda ingin memeriksa apa yang digunakan kompiler, Anda dapat menggunakannya sizeof(int).

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

Satu-satunya hal yang menjanjikan kompiler c adalah ukuran pendek harus sama atau kurang dari int dan ukuran panjang harus sama atau lebih dari int. Jadi jika ukuran int adalah 4, maka ukuran pendek mungkin 2 atau 4 tetapi tidak lebih besar dari itu. Hal yang sama berlaku untuk lama dan int. Ia juga mengatakan bahwa ukuran pendek dan panjang tidak bisa sama.


1
Menggunakan %duntuk size_tparameter adalah UB.
Paul R

3

Ini tergantung pada implementasi, tetapi biasanya pada x86 dan arsitektur populer lainnya seperti ARM intmengambil 4 byte. Anda selalu dapat memeriksa pada waktu kompilasi menggunakan sizeof(int)atau jenis apa pun yang ingin Anda periksa.

Jika Anda ingin memastikan Anda menggunakan jenis ukuran tertentu, gunakan jenis dalam <stdint.h>


2
#include <stdio.h>

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

Ini mengembalikan 4, tapi itu mungkin tergantung mesin.


1

Apakah ukuran C "int" 2 byte atau 4 byte?

Apakah variabel Integer dalam C menempati 2 byte atau 4 byte?

C memungkinkan "byte" menjadi sesuatu selain 8 bit per "byte".

CHAR_BIT jumlah bit untuk objek terkecil yang bukan bidang-bit (byte) C11dr §5.2.4.2.1 1

Nilai dari sesuatu di atas 8 semakin tidak umum. Untuk portabilitas maksimum, gunakan CHAR_BITdaripada 8. Ukuran dari intdalam bit di C adalah sizeof(int) * CHAR_BIT.

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

Apa faktor yang menjadi sandarannya?

The intukuran bit umumnya 32 atau 16 bit. C rentang minimum yang ditentukan :

nilai minimum untuk objek bertipe int INT_MIN-32767
nilai maksimum untuk objek bertipe int INT_MAX+32767
C11dr §5.2.4.2.1 1

The rentang minimum untuk intpasukan ukuran bit menjadi setidaknya 16 - bahkan jika prosesor adalah "8-bit". Ukuran seperti 64 bit terlihat pada prosesor khusus. Nilai-nilai lain seperti 18, 24, 36, dll. Telah terjadi pada platform bersejarah atau setidaknya secara teori dimungkinkan. Pengkodean modern jarang khawatir tentang non-power-of-2int ukuran bit .

Prosesor dan arsitektur komputer menggerakkan int pemilihan ukuran bit.

Namun bahkan dengan prosesor 64-bit, intukuran kompiler mungkin 32-bit untuk alasan kompatibilitas karena basis kode besar bergantung pada int32-bit (atau 32/16).


-1

Ini adalah sumber yang bagus untuk menjawab pertanyaan ini.

Tetapi pertanyaan ini adalah semacam jawaban yang selalu benar, "Ya. Keduanya."

Tergantung pada arsitektur Anda. Jika Anda akan bekerja pada mesin 16-bit atau kurang, itu tidak bisa 4 byte (= 32 bit). Jika Anda bekerja pada mesin 32-bit atau lebih baik, panjangnya 32-bit.

Untuk mencari tahu, siapkan program Anda untuk menampilkan sesuatu yang dapat dibaca dan gunakan fungsi "sizeof". Itu mengembalikan ukuran dalam byte dari tipe data yang Anda nyatakan. Tapi hati-hati menggunakan ini dengan array.

Jika Anda mendeklarasikannya int t[12];akan mengembalikan 12 * 4 byte. Untuk mendapatkan panjang array ini, cukup gunakan sizeof(t)/sizeof(t[0]). Jika Anda akan membangun sebuah fungsi, yang seharusnya menghitung ukuran array pengiriman, ingatlah bahwa jika

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. 
}

Jadi ini bahkan tidak akan mengembalikan sesuatu yang berbeda. Jika Anda mendefinisikan array dan mencoba mendapatkan panjangnya setelah itu, gunakan sizeof. Jika Anda mengirim array ke suatu fungsi, ingat nilai kirim hanyalah sebuah pointer pada elemen pertama. Tetapi dalam kasus satu, Anda selalu tahu, berapa ukuran array Anda. Kasus dua dapat dipecahkan dengan mendefinisikan dua fungsi dan melewatkan beberapa kinerja. Tentukan fungsi (array t) dan tentukan function2 (array t, int size_of_t). Call "function (t)" mengukur panjang dengan beberapa copy-work dan mengirimkan hasilnya ke function2, di mana Anda dapat melakukan apa pun yang Anda inginkan pada ukuran array variabel.


Tautan yang disediakan adalah sumber informasi yang buruk karena mengasumsikan hal-hal yang tidak selalu benar (mis. charSelalu signed)
Andrei Damian-Fekete
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.