2016-10-25 15 views
0

私は画像を撮る関数get_picture()を持っています。 uint8_t型(pcitureが格納されている)のポインタを返し、ピクチャの長さを格納する変数 へのポインタをとります。は、ポインタを符号付きまたは符号なしにする必要があります。

私はそれを呼び出すここで
uint8_t * get_picture(int *piclength) 

main()中: - address becuase(正)のアドレスを記憶している私は実際にそれを定義する必要があり

unsigned int address, value; 
address = (unsigned int)get_picture((int*)& value); 

私の質問はここで

は宣言です intとして

+5

なぜポインタ値を 'int'に格納していますか? –

+1

ポインターはその型を指している必要があります。 'int *'は 'int'を指し、' unsigned int * 'は' unsigned int'を指し、 'uint8_t *'は 'uint8_t'を指し、' struct myCoolStruct * 'は' struct myCoolStruct'を指すはずです。例外は 'void *'と 'char *'ですが、他の型に別名を付けることができます。 – yano

+1

_Itはuint8_t_型のポインタを返します。そうでなければ、ポインタ__to__ uint8_tを返します。 –

答えて

10

私はあなたがポインタを理解しているかどうかは分かりません。

関数がuint8_t *を返した場合は、intでないuint8_t *に格納する必要があります。一例として、

uint8_t* get_picture(int* piclength); 

int piclength; 
uint8_t* address; 
address = get_picture(&piclength); 
+0

あなたの例でOPが混乱している場合に備えて、おそらく 'int * piclength'パラメータと一致する変数を追加することができます。 –

+0

@IanAbbott有効なポイント - 書き留められ、更新されました。 :) –

2

あなたが本当に整数にデータポインタを変換したい場合は、代わりにいくつかのランダムな(そしておそらく小さすぎる)タイプの専用のtypedefを使用します。
uintptr_t/intptr_t<stdint.h>のオプションのtypedef)

まだ、必要性は稀であり、私はここでそれを見ません。

0

あなたが実際に何をしているかによって異なります。あなたのコードは、その絵がどこに住んでいるかのアドレスをアドレスに含めるようにしたい場合と同じです。同様に、ビットはビットであり、intはunsigned intと同じ数のビットであり、アドレスを消費するものはそれらのビットを与えることができるので、intを使用できます。これは、人間がアドレスを符号なしと考えるより意味がありますが、コンパイラとハードウェアは気にしません。ビットはビットです。

しかし、あなたがしていることに応じて、既に述べたように、このアドレスは同じタイプのポインタを使用して保存してください。ドラガンの答えを参照してください。

アドレスを "見たい"場合は、それを見たい方法に依存し、それをunsigned intに変換するのは簡単で一般的な方法です。

はい、これは非常にシステムに依存し、intのサイズはツールチェーンとターゲットによって異なり、そのシステムのアドレスを完全に保持する場合もあれば、そうでない場合もあるため、その変数のコンシューマによってはいくつかのマスクが必要な場合があります。

あなたのコードは問題ありませんので、私はその質問を理解していると思います。署名されているか署名されていないかは、特定の操作のために署名されていないか、または署名されているだけです。アドレス自体は符号付きでも符号なしでもなく、アドレスバス上のビットです。普通のコンパイラでは、unsigned intとintは同じサイズですが、このコンパイラが少なくともこのコンパイラがポインタ用に使用するアドレスのサイズとして定義する限り、同じビット数を格納します。これはintでうまく動作しますまたは符号なしint。 intは少し間違っていると感じ、unsigned intは正しいと感じますが、それは人間の感情です。ハードウェアは、ビットがアドレスバスに行く途中で変化しない限り、気にしません。もし何らかの理由で私たちが見ていないコードがこの変数を10進数として表示するならば、printf( "%d \ n"、address); (なぜあなたはマイクロコントローラでprintfを書いていますか?)それは人間には不思議に見えるかもしれませんが、アドレスよりもビットパターンの正しい小数の解釈になります。 printf( "0x%X \ n"、アドレス);より理にかなってより一般的になります。もしあなたのprintfがそれをサポートしていれば、printf( "%p"、address); Dragans uint8_t *アドレス宣言を使用しています。これは、多くの人々が古典的なCの訓練に基づいて考えているのでしょう。ビットはビットであり、使用するまでハードウェアには何の意味もなく、そのユースケースに対してのみ、アドレスはアドレスバス上のアドレスであり、それを計算して別のアドレスを計算するときはアドレスではない符号付きか符号なしかは、演算に依存するかもしれません(加算と減算は符号なし、乗算と除算から符号付きではありません)。

uint8_t *アドレスを宣言として使用しないことを選択した場合、unsigned intは、 "コンパイル時に"(符号なし)intを格納するのに十分なビットがある場合、最初の場所のアドレス)。署名付きintは少し間違っていると感じますが、技術的にはうまくいくはずです。私のルールは、特に署名が必要な場合にのみ使用されます。それ以外の場合は署名されていないものが使用され、多くのバグが保存されます。残念なことに、伝統的にCライブラリはそれを逆にして、stdint.hの要素が出てくる前に大きな混乱を招いています。

関連する問題