Saya menggunakan int unsigned di mana-mana, dan saya tidak yakin apakah saya harus melakukannya. Ini bisa dari basis data kolom id kunci utama ke penghitung, dll. Jika suatu angka tidak boleh negatif, maka saya akan selalu menggunakan int yang tidak ditandatangani.
Namun saya perhatikan dari kode lain bahwa tidak ada orang lain yang melakukan hal ini. Apakah ada sesuatu yang penting yang saya abaikan?
Sunting: Karena pertanyaan ini, saya juga memperhatikan bahwa di C, mengembalikan nilai negatif untuk kesalahan lebih umum daripada melemparkan pengecualian seperti pada C ++.
c++
c
programming-practices
wting
sumber
sumber
for(unsigned int n = 10; n >= 0; n --)
(loop tak terhingga)Jawaban:
Ketika perhitungan melibatkan tipe yang ditandatangani dan tidak ditandatangani serta ukuran yang berbeda, aturan untuk promosi tipe dapat menjadi rumit dan mengarah pada perilaku yang tidak terduga .
Saya percaya ini adalah alasan utama mengapa Java menghilangkan tipe int yang tidak ditandatangani.
sumber
int
akan menimbulkan kesulitan seperti itu (karena perhitungan apa pun akan dipromosikan keint
); Saya tidak ada yang baik untuk dikatakan tentang kurangnya tipe byte yang tidak ditandatangani.Saya pikir Michael memiliki poin yang valid, tetapi IMO alasan mengapa semua orang menggunakan int sepanjang waktu (terutama di
for (int i = 0; i < max, i++
) adalah bahwa kami mempelajarinya seperti itu. Ketika setiap contoh dalam buku ' bagaimana belajar pemrograman ' digunakanint
dalam satufor
lingkaran, sangat sedikit yang akan mempertanyakan praktik itu.Alasan lainnya
int
adalah 25% lebih pendek dari ituuint
, dan kita semua malas ... ;-)sumber
++
ketika menambahkan, meskipun fakta bahwa perilakunya yang jarang diperlukan dan bahkan mungkin mengarah pada pengulangan yang tidak berguna atas salinan jika indeks loop adalah iterator atau tipe non-fundamental lainnya (atau kompiler sangat padat) .Pengkodean informasi jangkauan ke dalam tipe adalah A Good Thing. Ini berlaku dengan menggunakan angka yang masuk akal pada waktu kompilasi.
Banyak arsitektur tampaknya memiliki instruksi khusus untuk menangani
int
->float
konversi. Konversi dariunsigned
bisa lebih lambat (sedikit) .sumber
Mencampur jenis yang ditandatangani dan tidak ditandatangani dapat membawa Anda ke dunia kesakitan. Dan Anda tidak dapat menggunakan semua tipe yang tidak ditandatangani karena Anda akan menemukan hal-hal yang memiliki rentang valid yang menyertakan angka negatif atau membutuhkan nilai untuk menunjukkan kesalahan dan -1 yang paling alami. Jadi hasil akhirnya adalah banyak programmer menggunakan semua tipe integer yang telah ditandatangani.
sumber
Bagi saya jenis banyak tentang komunikasi. Dengan menggunakan int yang tidak ditandatangani, Anda memberi tahu saya bahwa nilai yang ditandatangani bukan nilai yang valid. Ini memungkinkan saya untuk menambahkan beberapa informasi saat membaca kode Anda di samping nama variabel. Idealnya saya tipe non anonim akan memberi tahu saya lebih banyak, tetapi itu memberi saya lebih banyak informasi daripada jika Anda telah menggunakan int di mana-mana.
Sayangnya tidak semua orang sangat sadar tentang apa yang dikomunikasikan kode mereka, dan itu mungkin alasan Anda melihat int di mana-mana meskipun nilai setidaknya tidak ditandatangani.
sumber
Saya menggunakan
unsigned int
C ++ untuk indeks array, sebagian besar, dan untuk setiap penghitung yang dimulai dari 0. Saya pikir itu baik untuk mengatakan secara eksplisit "variabel ini tidak boleh negatif".sumber
Anda harus peduli tentang ini ketika Anda berurusan dengan integer yang mungkin benar-benar mendekati atau melebihi batas int yang ditandatangani. Karena maksimum positif integer 32 bit adalah 2.147.483.647 maka Anda harus menggunakan int yang tidak ditandatangani jika Anda tahu itu akan a) tidak pernah negatif dan b) mungkin mencapai 2.147.483.648. Dalam kebanyakan kasus, termasuk kunci basis data dan penghitung, saya bahkan tidak akan pernah mendekati angka-angka seperti ini jadi saya tidak repot-repot mengkhawatirkan diri saya sendiri apakah bit tanda digunakan untuk nilai numerik atau untuk menunjukkan tanda.
Saya akan mengatakan: gunakan int kecuali Anda tahu Anda membutuhkan int unsigned.
sumber
Ini merupakan tradeoff antara kesederhanaan dan keandalan. Semakin banyak bug yang dapat ditangkap pada waktu kompilasi, semakin dapat diandalkan perangkat lunaknya. Orang dan organisasi yang berbeda berada pada titik yang berbeda di sepanjang spektrum itu.
Jika Anda pernah melakukan pemrograman keandalan tinggi di Ada, Anda bahkan menggunakan tipe berbeda untuk variabel seperti jarak berjalan kaki vs jarak dalam meter, dan kompiler menandainya jika Anda secara tidak sengaja menetapkan satu ke yang lain. Itu sempurna untuk memprogram rudal yang dipandu, tetapi pembunuhan berlebihan (yang dimaksudkan) jika Anda memvalidasi formulir web. Tidak ada yang salah dengan cara apa pun asalkan sesuai dengan persyaratan.
sumber
Saya cenderung setuju dengan alasan Joel Etherton, tetapi sampai pada kesimpulan yang berlawanan. Cara saya melihatnya, bahkan jika Anda tahu bahwa angka tidak akan pernah mendekati batas jenis yang ditandatangani, jika Anda tahu bahwa angka negatif tidak akan terjadi, maka ada sangat sedikit alasan untuk menggunakan varian yang ditandatangani dari suatu jenis.
Untuk alasan yang sama mengapa saya miliki, dalam beberapa contoh pilih, digunakan
BIGINT
(integer 64 bit) daripadaINTEGER
(integer 32-bit) dalam tabel SQL Server. Probabilitas bahwa data akan mencapai batas 32-bit dalam jumlah waktu yang wajar adalah sangat kecil, tetapi jika itu terjadi, konsekuensi dalam beberapa situasi bisa sangat menghancurkan. Pastikan untuk memetakan jenis antar bahasa dengan benar, atau Anda akan berakhir dengan keanehan menarik di ujung jalan ...Yang mengatakan, untuk beberapa hal, seperti nilai kunci primer basis data, ditandatangani atau tidak ditandatangani benar-benar tidak masalah, karena kecuali jika Anda secara manual memperbaiki data yang rusak atau sesuatu di sepanjang garis itu, Anda tidak akan pernah berurusan dengan nilai secara langsung; itu adalah pengidentifikasi, tidak lebih. Dalam kasus-kasus itu, konsistensi mungkin lebih penting daripada pemilihan ketepatan yang tepat. Jika tidak, Anda berakhir dengan beberapa kolom kunci asing yang ditandatangani dan yang lainnya tidak ditandatangani, tanpa pola yang jelas - atau keanehan yang menarik lagi.
sumber
Saya akan merekomendasikan bahwa di luar penyimpanan data yang dibatasi ruang dan konteks pertukaran data, seseorang harus menggunakan tipe yang ditandatangani. Dalam kebanyakan kasus di mana integer bertanda 32-bit akan terlalu kecil tetapi nilai unsigned 32-bit sudah cukup untuk hari ini, tidak akan lama sebelum nilai unsigned 32-bit juga tidak cukup besar.
Waktu utama seseorang harus menggunakan tipe yang tidak ditandatangani adalah ketika seseorang mengumpulkan nilai-nilai ganda menjadi yang lebih besar (misalnya, mengubah empat byte menjadi angka 32-bit) atau mendekomposisi nilai yang lebih besar menjadi yang lebih kecil (misalnya menyimpan angka 32-bit sebagai empat byte) ), atau ketika seseorang memiliki kuantitas yang diharapkan "berguling" secara berkala dan orang perlu menghadapinya (pikirkan meter utilitas perumahan; kebanyakan dari mereka memiliki angka yang cukup untuk memastikan bahwa mereka tidak akan mungkin berguling di antara pembacaan jika mereka dibaca tiga kali setahun, tetapi tidak cukup untuk memastikan mereka tidak terguling dalam masa manfaat meteran). Jenis yang tidak ditandatangani sering memiliki 'keanehan' yang cukup sehingga hanya boleh digunakan dalam kasus-kasus di mana semantik mereka diperlukan.
sumber
size_t
tidak ditandatangani danptrdiff_t
ditandatangani.Saya menggunakan int unsigned untuk membuat kode dan maksud saya lebih jelas. Satu hal yang saya lakukan untuk menjaga terhadap konversi tersirat yang tidak terduga ketika melakukan aritmatika dengan kedua tipe bertanda tangan dan tidak bertanda adalah menggunakan short unsigned (biasanya 2 byte) untuk variabel unsigned saya. Ini efektif karena beberapa alasan:
Prinsip umum adalah bahwa jenis variabel tidak bertanda tangan Anda harus memiliki peringkat lebih rendah dari jenis variabel yang ditandatangani untuk memastikan promosi ke jenis yang ditandatangani. Maka Anda tidak akan memiliki perilaku luapan yang tidak terduga. Jelas Anda tidak bisa memastikan ini setiap saat, tetapi (kebanyakan) seringkali layak untuk memastikan hal ini.
Sebagai contoh, baru-baru ini saya memiliki sesuatu untuk loop seperti ini:
Huruf '2' adalah tipe int. Jika saya adalah unsigned int bukannya short unsigned, maka dalam sub-ekspresi (i-2), 2 akan dipromosikan menjadi int unsigned (karena int unsigned memiliki prioritas lebih tinggi daripada int yang ditandatangani). Jika i = 0, maka sub-ekspresi sama dengan (0u-2u) = beberapa nilai besar karena melimpah. Gagasan yang sama dengan i = 1. Namun, karena saya adalah kependekan dari unsigned, maka dipromosikan ke jenis yang sama dengan literal '2', yang ditandatangani int, dan semuanya berfungsi dengan baik.
Untuk keamanan tambahan: dalam kasus yang jarang di mana arsitektur yang Anda laksanakan pada penyebab int menjadi 2 byte, ini dapat menyebabkan kedua operan dalam ekspresi aritmatika dipromosikan menjadi int tidak bertanda dalam kasus di mana variabel pendek yang tidak ditandai tidak cocok ke dalam int 2-byte yang ditandatangani, yang terakhir memiliki nilai maksimum 32.767 <65.535. (Lihat https://stackoverflow.com/questions/17832815/c-implicit-conversion-signed-unsigned untuk lebih jelasnya). Untuk mencegah hal ini, Anda cukup menambahkan static_assert ke program Anda sebagai berikut:
dan itu tidak akan dikompilasi pada arsitektur di mana int adalah 2 byte.
sumber