「&」演算子を理解する

c c++
「&」演算子を理解する

「&」演算子について知っている限りでは、メモリ内のオペランドのベースアドレスを返します。

次のシナリオを想像してみましょう(私のマシンのように):

  • sizeof(int)= 4バイト

  • sizeof(float)= 4バイト

  • sizeof(char)= 1バイト

さて、次のようなものを書くと:

void main() {
 int i = 5411;
 int *ip = &i;
 char *c = &i;

 printf("%d",*ip);
 printf("%c",*c);
}

最初のprintf()で5411が返されるはずです。 2番目のprintf()について言えば、iのベースアドレスには10101001(上位8ビット= char型ポインターの場合は1バイト)が含まれています。 したがって、* cから169が得られます。これは、%cに変換されたときに無効な文字です。

しかし、コンパイラは「#」または他の有効な出力を提供してくれます。 それはなぜですか? 任意の入力?

編集(回答の1つに対する著者のコメントから取得):

_
実際のマシンから離れていたので、それは単なるダミーのケースでした。 +実際のケースはi = 5411です
_

  5  2


ベストアンサー

整数がメモリにどのように格納されるかを理解するのが難しいようです。 例として5411を取り上げます。

5411 = 1010100100011

ただし、この数値13の2進数は、 `int`が32ビットであるため、32桁にパディングする必要があります

5411 = 00000000 00000000 00010101 00100011

リトルエンディアンマシン(x86、デフォルトではARM)では、最下位バイトがフロントに格納されるため、メモリに次のように格納されます。

00100011   00010101    00000000    00000000
^
c          c + 1       c + 2       c + 3
ip

したがって、 * c`は00100011を返します。 35( ’#')。

24


ASCIIは、最大127文字までを定義します。 それに加えて、あなたが本当にやりたいのは、 * c`の値に対応する数値を出力することです。これも%d`を使用して行われます…​

 printf("%d",*c);

…​should display the number as you expect.

5


まず、プログラムの形式が不適切です。 CもC ++も、 `char *`ポインターを `int *`値で初期化することはできません。 `c`ポインターの初期化には明示的なキャストが必要です。

第二に、元の整数 i`のどのバイト(上位または下位)がその「ベースアドレス」にあるかは、実装定義です。 リトルエンディアンアーキテクチャがあります。下位ではあるが、 `* c(8ビットの` char`マシンでは値が 130`で、 114`ではなく)を通して表示されます。 ビッグエンディアンアーキテクチャがあり、高次ですが、 * c(8ビットの` char`マシンでは 0)を介して表示されます。 したがって、コード 130`の文字またはコード 0`の文字のいずれかが `%c`形式指定子で出力されることを期待する必要があります。

第三に、典型的な実装では、通常「無効な文字コード」のようなものはありません。 どのコードでも、通常は何らかの方法で何かが印刷されます。 コードからの出力としてどのようにして `#`を取得したのかわかりません。 これは実際に実行していたコードですか?

3


  • cのアドレスは、cを&iに割り当てているため、iのアドレスです。 次に、最高値または最低値(エンディアンに応じて)を取得し、その文字を出力します。

1


整数のエンコードについて何かを学ぶには、少し実験して

printf("0x%X, %X|%X|%X|%X\n",
  i,
  i & 0xFF,
  (i >> 8) & 0xFF
  (i >> 16) & 0xFF
  (i >> 24) & 0xFF
  );

次に、 c [0]、 `c [1]`など、および `%c`としての他のフォーマット文字列で同じことを行います。

1


タイトルとURLをコピーしました