1

I have this character array

char array[] = {1,2,3};     //FL, FH, Size

and I am trying to access it using pointers in such a way that I get FLFH value together, stored in an integer variable.

I did this

int val =0;
val = *(int*)array;
printf("value of p is %d\n",val);

I was expecting the result to be 12, but it was some 8-digit number which I think maybe the address of the value or something. Could anyone tell me what am I doing wrong here?

4

4 に答える 4

4

それはあなたに12を与えることは決してありません。

2つの1バイトの値を取得し、それらが1つの2バイトのエンティティを構成しているように見ています。それらを一緒に見るとき、あなたはそれらの価値を再解釈しています。整数1は、ビットとして次のようになります。 00000001、および次2のようになります00000010。コンパイラはそれらの大きさを認識しているため、個別にアクセスできますが、配列内で順番に、メモリ内で隣り合って配置されています。

2つのバイトを、あたかもそれらがであるかのように一緒に検査します。次のintようになります。0000000100000010、値が12ではない; 513です。

さらに読むために、あなたがしているのは一種の「型のパンニング」です。

于 2013-01-07T03:02:30.290 に答える
3

これは、読みやすさと移植性のために悪い考えです。array[0] * 10 + array[1]それがあなたの言いたいことなら使ってください、そしてそれをスピードアップするためにのぞき穴オプティマイザーを信頼してください。ポインターを介して値にアクセスする必要がある場合は、ポインターを使用してchar書き込みますp[0] * 10 + p[1]。これは、理解しやすく、完全に合法で、移植性があります。

コードが機能しない理由はたくさんあります。これは、あなたがやろうとしていることが馬鹿げていること、または少なくとも頭を抱えていることを強く示唆しています。

1つ目は、バイト範囲が0〜9ではなく0〜255であるため、この手法を使用して機能すると、1 * 10+2ではなく1*256 + 2=258になります。 = 12. 12を取得することは決してありません。コンピューターは、そのようには機能しません。これが、算術演算を実行する前に、のような文字列を数値12にatoi()変換するような関数を呼び出す必要がある理由です。"12"

4バイトのintがある場合は、それが大きな数を取得している理由でもあります。1* 256 + 2を取得していると思いますが、実際には((1 * 256 + 2)* 256 +3を取得しています。 )* 256+???。また、クリスがコメントで言っているように、そのような場合、あなたの配列はとにかく小さすぎます。前の式で。

shortの代わりにを使用してみて、intそれがうまく機能するかどうかを確認できます。ashortは2バイト整数である可能性があります。ただし、これは保証されていないため、shortsが2バイトより長いシステムには移植できません。より良い方法は、2バイト整数に対応するシステム上の実際の型(おそらくshort、おそらく他の何か)を見つけて、その型のようなものをtypedef し、の代わりにINT2使用することです。INT2int

もう1つの潜在的な問題は、システムがリトルエンディアンのバイト順序を使用する可能性があることです。この場合、配列内のバイトは、必要な2バイトのマシン整数を表すために間違った順序になり、トリックは機能しません。自分のマシンで動作させることができたとしても、リトルエンディアンのマシンでコードを実行しなければならない場合は壊れます。(このスレッドの他の場所でのあなたのコメントは、これがまさに起こっていることであることを示唆しています。)

だから、簡単な方法でやってください。

于 2013-01-07T03:01:08.753 に答える
3

You didn't get the result you expected because bytes are laid out on 8 bit boundaries, so adjacent binary byte values are scaled by 25610, not 1010.

Also, if you cast the type of something and dereference it, the compiler will compile it but technically your program is nonconforming.*

One problem is alignment. If you change the type with open code it may not begin at the right boundary, and it may not be big enough. You can fix all that with a union. It's still nonconforming and the result is not specified, but in practice it is reliable and even somewhat portable, if you don't mind different results depending on byte order and int size.

union a {
  char  c[3];
  int   i;
  short s;
} a;

This might also be a good application for <stdint.h>, but that's a topic for another question.


*You might wonder, then, why casts exist ... it's because (A) despite being banned by the standard, type punning is widely used in existing C programs and particularly in operating software, and (B) there are mostly-conforming uses that define generic interfaces but always (or, ahem usually) cast the thing back to the original type before dereferencing it.

于 2013-01-07T03:11:38.943 に答える
-1

maybe try :-

char array[] = {1,2,3};     //FL, FH, Size
int val =0;
val = *(short*)array;
printf("value of p is %X\n",val);

this is assuming you are trying to reinterpret your char array as an int. Though different platforms you may get different results than expected.

于 2013-01-07T02:56:33.477 に答える