回答:
それはあなたの意図を文書化します-あなたは文字ではなく小さな数字を保存します。
次のような他のtypedef使用している場合も、それはよりよいに見えるuint16_t
かをint32_t
。
unsigned char
またはsigned char
文書化しchar
ます。
unsigned
さunsigned int
れていないのは当然のことだと思いましたか?
char
は文字を意味するようですが、UTF8文字列のコンテキストでは、マルチバイト文字の1バイトにすぎない場合があります。uint8_tを使用すると、すべての位置で文字を期待すべきでないことを明確にすることができます。つまり、文字列/配列の各要素は、意味論的な仮定を行うべきではない任意の整数です。もちろん、すべてのCプログラマはこれを知っていますが、初心者は正しい質問をするように強いられるかもしれません。
見やすくするために、一部のシステムには8ビットタイプがない場合があります。ウィキペディアによると:
N = 8、16、32、または64の正確な幅の整数型を定義するには、要件を満たす型がある場合にのみ、実装が必要です。適切なタイプをサポートしていても、他のNに対してそれらを定義する必要はありません。
そのuint8_t
ため、8ビット= 1バイトのすべてのプラットフォームで存在しますが、存在は保証されていません。一部の組み込みプラットフォームは異なる場合がありますが、それは非常にまれになっています。一部のシステムでは、char
タイプを16ビットとして定義する場合があります。その場合、おそらく8ビットタイプは存在しません。
その(マイナー)問題以外は、@ Mark Ransomの答えが私の意見では最高です。データの使用目的を最も明確に示すものを使用してください。
また、私はあなたがuint8_t
(標準に含まれていないstdint.h
)というよりもuint_8
(ヘッダーに提供されているC99からの標準のtypedef)を意味していると仮定しています
uint8_t
)ことを示しました。これは、8ビットタイプのストレージ表現に未使用のビットが含まれてuint8_t
いるためです。
typedef unsigned integer type uint8_t; // optional
つまり、本質的に、C ++標準準拠ライブラリはuint8_tを定義するためにまったく必要ありません(コメント// optionalを参照) )
重要なのは、実装に依存しないコードを記述することです。unsigned char
8ビット型であるとは限りません。uint8_t
あります(利用可能な場合)。
sizeof(unsigned char)
戻り1
ます。ただし、システムのcharとintが同じサイズ(たとえば、16ビット)の場合sizeof(int)
も返されます1
私の経験では、uint8_tを使用して8ビット(およびuint16_tなど)を意味する場所と、8ビットより小さいフィールドを持つことができる場所が2つあります。どちらの場所もスペースが重要であり、デバッグ時にはデータの生のダンプを調べる必要があり、それが何を表しているのかをすばやく判別できる必要があります。
1つ目はRFプロトコル、特に狭帯域システムです。この環境では、1つのメッセージにできるだけ多くの情報を詰め込む必要がある場合があります。2番目は、非常に限られたスペース(組み込みシステムなど)のフラッシュストレージです。どちらの場合も、コンパイラーがパックとアンパックを処理するパックされたデータ構造を使用できます。
#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()
どちらの方法を使用するかは、コンパイラによって異なります。同じヘッダーファイルで複数の異なるコンパイラをサポートする必要がある場合もあります。これは、デバイスとサーバーが完全に異なる組み込みシステムで発生します。たとえば、x86 Linuxサーバーと通信するARMデバイスがある場合があります。
パック構造を使用する際の注意点がいくつかあります。最大の落とし穴は、メンバーのアドレスを逆参照しないことです。マルチバイトで整列された単語を持つシステムでは、これにより、整列不良の例外とコアダンプが発生する可能性があります。
一部の人々はパフォーマンスについても心配し、これらのパックされた構造を使用するとシステムの速度が低下すると主張します。裏で、コンパイラーが非整列データメンバーにアクセスするためのコードを追加するのは事実です。IDEのアセンブリコードを見るとわかります。
ただし、パック構造は通信とデータストレージに最も有用であるため、データをメモリで操作するときに、データを非パック表現に抽出できます。通常は、メモリ内のデータパケット全体を処理する必要はありません。
ここにいくつかの関連する議論があります:
プラグマpack(1)も__attribute__((aligned(1)))も機能
gccの__attribute __((packed))/ #pragma packは安全ではありませんか?
http://solidsmoke.blogspot.ca/2010/07/woes-of-structure-packing-pragma-pack.html
少ししかありません。移植性の観点からは、char
8ビットより小さくすることはできず、それより小さくすることはできませんchar
。そのため、特定のC実装に符号なし8ビット整数型がある場合、それはになりますchar
。または、1つもまったくない場合があり、その時点ではtypedef
トリックは無効です。
そこに8ビットのバイトが必要で、他には何も必要ないことが明らかであるという意味で、コードをより適切に文書化するために使用できます。しかし実際には、これは事実上どこでも妥当な期待です(それが真実ではないDSPプラットフォームがありますが、そこで実行されるコードの可能性はわずかであり、プログラムの上部で静的アサートを使用してエラーを発生させることもできますそのようなプラットフォーム)。
unsigned char
0から255までの値を保持できる必要があります。4ビットでそれを実行できる場合、私には不便です。
uint8_t
実装に追加します。16ビット文字を使用したDSP用のコンパイラーはuint8_t
、通常、を実装するのか、しないのか。
#include <stdint.h>
、かつ使用することをuint8_t
。プラットフォームにそれがある場合、それはあなたにそれを与えます。プラットフォームにない場合、プログラムはコンパイルされず、理由は明確で簡単です。
ほとんどすべてのシステムでuint8_t == unsigned charに出会いましたが、これはC標準では保証されていません。ポータブルコードを記述しようとしていて、メモリのサイズが正確に重要な場合は、uint8_tを使用します。それ以外の場合は、unsigned charを使用します。
uint8_t
が8ビットのunsigned char
場合、常に範囲とサイズ、およびパディング(なし)に一致しますunsigned char
。ときはunsigned char
8ビットではなく、uint8_t
存在しません。
unsigned char
が8ビットの場合uint8_t
、typedef
そのでありtypedef
、拡張された符号なし整数型ではないことが保証されますか?
unsigned char/signed char/char
8ビット以上の最小タイプと同様に、簡単に推測できます。 unsigned char
パディングはありません。ためuint8_t
であること、それは8ビット、パディングなしでなければならない、なぜなら実装設け整数型で存在する:最小限の要件に合致しますunsigned char
。"... typedefであることが保証されている..."については、投稿するのに適した質問のようです。