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?
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?
Jawaban:
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
atau signed char
mendokumentasikan maksudnya juga, karena tanpa hiasan char
adalah apa yang menunjukkan Anda bekerja dengan karakter.
unsigned
adalah unsigned 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 :
Implementasi diperlukan untuk menentukan tipe integer lebar-tepat untuk N = 8, 16, 32, atau 64 jika dan hanya jika memiliki tipe apa saja yang memenuhi persyaratan. Tidak diperlukan untuk menentukan mereka untuk N lain, bahkan jika itu mendukung jenis yang sesuai.
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 mendefinisikan char
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 di stdint.h
header) daripada uint_8
(bukan bagian dari standar apa pun).
uint8_t
(atau mengetikkannya untuk itu). Ini karena tipe 8bit akan memiliki bit yang tidak digunakan dalam representasi penyimpanan, yang uint8_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).
sizeof(unsigned char)
akan kembali 1
selama 1 byte. tetapi jika sistem char dan int berukuran sama, misalnya, 16-bit maka sizeof(int)
juga akan kembali1
Seperti yang Anda katakan, " hampir setiap sistem".
char
mungkin salah satu yang kurang mungkin berubah, tetapi begitu Anda mulai menggunakan uint16_t
dan berteman, menggunakan uint8_t
campuran lebih baik, dan bahkan mungkin menjadi bagian dari standar pengkodean.
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:
#pragma pack(1)
typedef struct {
uint8_t flag1:1;
uint8_t flag2:1;
padding1 reserved:6; /* not necessary but makes this struct more readable */
uint32_t sequence_no;
uint8_t data[8];
uint32_t crc32;
} s_mypacket __attribute__((packed));
#pragma pack()
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
Ada sedikit. Dari sudut pandang portabilitas, char
tidak boleh lebih kecil dari 8 bit, dan tidak ada yang lebih kecil dari itu char
, jadi jika implementasi C yang diberikan memiliki tipe integer 8-bit yang tidak ditandatangani, itu akan menjadi char
. Atau, mungkin tidak ada sama sekali, di mana setiap typedef
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).
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 diterapkan uint8_t
, atau tidak?
#include <stdint.h>
, dan gunakan uint8_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.
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.
uint8_t
selalu cocok dengan kisaran dan ukuran unsigned char
dan bantalan (tidak ada) saat unsigned char
8-bit. Ketika unsigned char
tidak 8-bit, uint8_t
tidak ada.
unsigned char
adalah 8-bit, yang uint8_t
dijamin menjadi typedef
daripadanya dan bukan typedef
dari tipe integer unsigned diperpanjang ?
unsigned char/signed char/char
jenis terkecil - tidak lebih kecil dari 8 bit. unsigned char
tidak memiliki bantalan. Untuk uint8_t
menjadi, itu harus 8-bit, tidak ada bantalan, ada karena implementasi yang diberikan tipe integer: cocok dengan persyaratan minimal unsigned char
. Mengenai "... dijamin menjadi typedef ..." sepertinya pertanyaan yang bagus untuk dikirim.