1

stdin から MAC アドレス (標準の 16 進数表記、例: 00:11:22:33:44:55) を読み取り、10 進数として 6 バイトの変数 hw_addr に変換しています。

u8 hw_addr[6];

scanf("%2x:%2x:%2x:%2x:%2x:%2x", &hw_addr[0], &hw_addr[1], &hw_addr[2], &hw_addr[3], &hw_addr[4], &hw_addr[5]);

唯一の問題は、6 つの scanf 警告が表示されることです。

warning: format '%2x' expects type 'unsigned int *', but argument 3 has type 'u8 *'

.....

各フィールドの int を無駄にすることなく、これらの警告を取り除く方法はありますか?

4

4 に答える 4

4

適切なタイプを使用するだけです

数十億バイトの RAM を搭載したマシンを使用していて、そのうちの 6 バイトを節約したいですか?

何百万もの MAC アドレスの配列を保持している場合は、読み取り後にそれらをパック形式に変換する必要があります。ただし、() に正規の int を指定しても害はありませんscanf

さらに言えばhw_addr[]、 がローカル変数である場合、関数が戻った後に他のローカル変数に再利用されるため、事実上スペースをまったく使用しません。

すべてを最適化することはできないため、最適化の努力を本当に重要なことに集中させることが重要です。

于 2010-02-17T04:14:17.083 に答える
4

scanf私のマンページによると、

 hh       Indicates that the conversion will be one of dioux or n
          and the next pointer is a pointer to a char (rather than
          int).

あなたが望んでいるのは"%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx"

于 2010-02-17T04:21:28.583 に答える
2

警告は、重大な問題を示しています。符号なしバイトへのポインターを渡していますが、scanf 関数はそれらのポインターに 32 ビットを書き込みます。最初の 3 つの値については、余分な 24 ビットが hw_addr 配列の一部を上書きしますが、最後の 3 つの値については、スタック上の他の変数を上書きしています。

ひどいクラッシュを避けるには、少なくとも hw_addr をオーバーアロケートする必要があります

u8 hw_addr[6+3];

少なくとも、コードがスタックを破棄するのを防ぎます。しかし、実際には、scanf に正しいサイズの値を使用し、後で int から unsigned バイトに戻す必要があります。

于 2010-02-17T04:22:38.040 に答える
1

unsigned int を char アドレスに読み込んでいますが、これはあまり移植性や安全性に欠ける可能性があります。int配列をバッファとして使用して読み取り、バイト配列にコピーするだけです

于 2010-02-17T04:14:20.517 に答える