Apa keuntungan menggunakan uint8_t
lebih dari unsigned char
dalam C?
Saya tahu bahwa pada hampir setiap sistem uint8_t
hanyalah sebuah typedef untuk unsigned char
, jadi mengapa menggunakannya?
Ini mendokumentasikan maksud Anda - Anda akan menyimpan sejumlah kecil, bukan karakter.
Juga terlihat lebih bagus jika Anda menggunakan typedef lain seperti uint16_t
atau int32_t
.
unsigned char
atausigned char
mendokumentasikan maksudnya juga, karena tanpa hiasanchar
adalah apa yang menunjukkan Anda bekerja dengan karakter.unsigned
adalahunsigned int
definisi?char
tampaknya menyiratkan karakter, sedangkan dalam konteks string UTF8, mungkin hanya satu byte karakter multibyte. Menggunakan uint8_t dapat memperjelas bahwa seseorang tidak seharusnya mengharapkan karakter di setiap posisi - dengan kata lain bahwa setiap elemen dari string / array adalah bilangan bulat sembarang yang tidak boleh dibuatkan asumsi semantik apa pun. Tentu saja semua programmer C mengetahui hal ini, tetapi mungkin mendorong pemula untuk mengajukan pertanyaan yang tepat.Hanya untuk menjadi bertele-tele, beberapa sistem mungkin tidak memiliki tipe 8 bit. Menurut Wikipedia :
Jadi
uint8_t
tidak dijamin ada, meskipun akan untuk semua platform di mana 8 bit = 1 byte. Beberapa platform yang disematkan mungkin berbeda, tetapi semakin jarang. Beberapa sistem dapat mendefinisikanchar
jenis menjadi 16 bit, dalam hal ini mungkin tidak akan ada jenis 8-bit dalam bentuk apa pun.Selain masalah (kecil) itu, jawaban @Mark Ransom adalah yang terbaik menurut saya. Gunakan yang paling jelas menunjukkan untuk apa Anda menggunakan data.
Juga, saya berasumsi Anda maksudkan
uint8_t
(typedef standar dari C99 disediakan distdint.h
header) daripadauint_8
(bukan bagian dari standar apa pun).sumber
uint8_t
(atau mengetikkannya untuk itu). Ini karena tipe 8bit akan memiliki bit yang tidak digunakan dalam representasi penyimpanan, yanguint8_t
tidak harus dimiliki.typedef unsigned integer type uint8_t; // optional
Jadi, pada dasarnya, sebuah perpustakaan yang memenuhi standar C ++ tidak diperlukan untuk mendefinisikan uint8_t sama sekali (lihat komentar // opsional )Intinya adalah untuk menulis kode implementasi-independen.
unsigned char
tidak dijamin menjadi tipe 8-bit.uint8_t
adalah (jika tersedia).sumber
sizeof(unsigned char)
akan kembali1
selama 1 byte. tetapi jika sistem char dan int berukuran sama, misalnya, 16-bit makasizeof(int)
juga akan kembali1
Seperti yang Anda katakan, " hampir setiap sistem".
char
mungkin salah satu yang kurang mungkin berubah, tetapi begitu Anda mulai menggunakanuint16_t
dan berteman, menggunakanuint8_t
campuran lebih baik, dan bahkan mungkin menjadi bagian dari standar pengkodean.sumber
Dalam pengalaman saya ada dua tempat di mana kami ingin menggunakan uint8_t yang berarti 8 bit (dan uint16_t, dll) dan di mana kami dapat memiliki bidang yang lebih kecil dari 8 bit. Kedua tempat adalah tempat ruang penting dan kita sering perlu melihat dump data mentah ketika debugging dan harus dapat dengan cepat menentukan apa yang diwakilinya.
Yang pertama adalah dalam protokol RF, terutama dalam sistem pita sempit. Dalam lingkungan ini kita mungkin perlu mengemas informasi sebanyak mungkin ke dalam satu pesan. Yang kedua adalah dalam penyimpanan flash di mana kita mungkin memiliki ruang yang sangat terbatas (seperti pada sistem embedded). Dalam kedua kasus tersebut, kita dapat menggunakan struktur data dikemas di mana kompiler akan mengurus pengepakan dan membongkar untuk kita:
Metode mana yang Anda gunakan tergantung pada kompiler Anda. Anda mungkin juga perlu mendukung beberapa kompiler berbeda dengan file header yang sama. Ini terjadi pada sistem tertanam di mana perangkat dan server bisa sangat berbeda - misalnya Anda mungkin memiliki perangkat ARM yang berkomunikasi dengan server Linux x86.
Ada beberapa peringatan dengan menggunakan struktur yang dikemas. Gotcha terbesar adalah bahwa Anda harus menghindari dereferencing alamat anggota. Pada sistem dengan kata-kata selaras mutibyte, ini dapat menghasilkan pengecualian yang tidak selaras - dan coredump.
Beberapa orang juga akan khawatir tentang kinerja dan berpendapat bahwa menggunakan struktur yang dikemas ini akan memperlambat sistem Anda. Memang benar bahwa, di balik layar, kompiler menambahkan kode untuk mengakses anggota data yang tidak selaras. Anda dapat melihatnya dengan melihat kode assembly di IDE Anda.
Tetapi karena struktur yang dikemas paling berguna untuk komunikasi dan penyimpanan data maka data dapat diekstraksi menjadi representasi yang tidak dikemas ketika bekerja dengannya dalam memori. Biasanya kita tidak perlu bekerja dengan seluruh paket data dalam memori.
Berikut ini beberapa diskusi yang relevan:
paket pragma (1) atau __attribute__ ((sejajar (1)))) berfungsi
Apakah __attribute __ ((dikemas)) / #pragma paket gcc tidak aman?
http://solidsmoke.blogspot.ca/2010/07/woes-of-structure-packing-pragma-pack.html
sumber
Ada sedikit. Dari sudut pandang portabilitas,
char
tidak boleh lebih kecil dari 8 bit, dan tidak ada yang lebih kecil dari ituchar
, jadi jika implementasi C yang diberikan memiliki tipe integer 8-bit yang tidak ditandatangani, itu akan menjadichar
. Atau, mungkin tidak ada sama sekali, di mana setiaptypedef
trik diperdebatkan.Ini dapat digunakan untuk mendokumentasikan kode Anda dengan lebih baik dalam arti bahwa Anda memerlukan 8-bit byte di sana dan tidak ada yang lain. Tetapi dalam praktiknya itu adalah ekspektasi yang wajar hampir di mana saja (ada platform DSP yang tidak benar, tetapi kemungkinan kode Anda berjalan di sana tipis, dan Anda bisa juga salah menggunakan statik statik di bagian atas program Anda pada platform seperti itu).
sumber
unsigned char
untuk dapat menyimpan nilai antara 0 dan 255. Jika Anda dapat melakukannya dalam 4 bit, topiku tidak cocok untuk Anda.uint8_t
implementasi. Saya bertanya-tanya, apakah kompiler untuk DSP dengan karakter 16bit biasanya diterapkanuint8_t
, atau tidak?#include <stdint.h>
, dan gunakanuint8_t
. Jika platform memilikinya, itu akan memberikannya kepada Anda. Jika platform tidak memilikinya, program Anda tidak akan dikompilasi, dan alasannya akan jelas dan langsung.Itu sangat penting misalnya ketika Anda menulis penganalisa jaringan. header paket didefinisikan oleh spesifikasi protokol, bukan dengan cara kompiler C platform tertentu bekerja.
sumber
Pada hampir setiap sistem saya telah bertemu char uint8_t == unsigned, tetapi ini tidak dijamin oleh standar C. Jika Anda mencoba menulis kode portabel dan ukurannya persis sama dengan ukuran memori, gunakan uint8_t. Kalau tidak, gunakan char yang tidak ditandatangani.
sumber
uint8_t
selalu cocok dengan kisaran dan ukuranunsigned char
dan bantalan (tidak ada) saatunsigned char
8-bit. Ketikaunsigned char
tidak 8-bit,uint8_t
tidak ada.unsigned char
adalah 8-bit, yanguint8_t
dijamin menjaditypedef
daripadanya dan bukantypedef
dari tipe integer unsigned diperpanjang ?unsigned char/signed char/char
jenis terkecil - tidak lebih kecil dari 8 bit.unsigned char
tidak memiliki bantalan. Untukuint8_t
menjadi, itu harus 8-bit, tidak ada bantalan, ada karena implementasi yang diberikan tipe integer: cocok dengan persyaratan minimalunsigned char
. Mengenai "... dijamin menjadi typedef ..." sepertinya pertanyaan yang bagus untuk dikirim.