5
#include<stdio.h>
int main(void)
{
  char c = 0x80;
  printf("%d\n", c << 1);
  return 0;
}

この場合、出力は-256です。私が書くc << 0と、出力は-128です。

このコードの背後にあるロジックがわかりません。

4

5 に答える 5

18

charプラットフォームで署名されている可能性があります。この場合、0x80-128を表します(2の補数を想定)。

acharを演算子のオペランドとして使用すると、(まだ-128)<<にプロモートされます。intしたがって、左シフトを適用すると、-256になります。技術的には、負の値のシフトは実装定義の未定義ですが、表示されるのは典型的な動作です。

于 2010-10-22T23:29:43.250 に答える
6

すでにあなたの出発点は問題があります:

char c = 0x80;

(あなたの場合のように)符号付き型の場合、最大値を保持することが保証されている型にchar整数定数を割り当てています。次に、コンパイラは、実装で定義された値(あなたの場合は私が推測する)を提供するか、範囲エラーを発行するかを選択できます。128127-128

次に、その負の値を左シフトします。これにより、未定義の動作が発生します。合計すると、いくつかの実装定義の選択肢と、結果を決定する未定義の動作があります。

  • の署名char
  • に変換する方法の128選択signed char
  • の幅char
  • の符号表現int(3つの可能性があります)
  • 負の左シフトを実装する(またはしない)方法の選択int

これらすべてのケースを調べて、さまざまな結果がどうなるかを確認することは、良い練習になるかもしれません。

要約すると、いくつかの推奨事項:

  • 適切な定数を選択して変数を初期化します
  • プレーンで算術をしないでくださいchar
  • 署名されたタイプでは左シフトを行わないでください
于 2010-10-23T08:59:36.983 に答える
3

cが割り当てられ0x80ます。8ビットバイトを想定すると、バイナリ表現でのその値はです10000000。どうやら、あなたのプラットフォームでcharは、署名されたタイプです。したがって、0x80(つまり10000000)は-128に対応します。

が値に<<適用されると、charに昇格されint、符号が保持されます。したがって、32ビット整数で左に1回シフトすると、11111111111111111111111100000000(2の補数)は-256になります。

于 2010-10-22T23:35:03.820 に答える
1

補足です。ボトムアップの観点から、ビット単位のシフト(およびマスキング)は、アーキテクチャのワード長(ビットで表される)に基づいています。単語の長さは、アーキテクチャごとに異なります。

アーキテクチャ別の単語の長さについては、このWikiページを参照してください

ターゲットアーキテクチャのワード長がわかっている場合は、ビットシフトを使用して、オペランドを使用するよりも高速に乗算および除算(場合によっては)を行うことができます。

ビットシフトの興味深い図については、このWikiページを参照してください。

ビットシフトされたコードはアーキテクチャに依存するため、ビットシフトされたコードの特定の部分がアーキテクチャ間で同じように機能するとは限りません。ただし、アーキテクチャごとに単語の長さを変えるという考え方に慣れると、ビットシフトは不思議ではなくなり、予測しやすくなります。

ありがたいことに、今日では、8、16、32、および64ビットのワード長と、8ビットの文字長のみがあります。古代のコンピューティングの時代には、アーキテクチャは12、15、または23ビットのワード長(たとえば、悪意のあるもの)を持っている可能性があります。

于 2010-10-23T02:36:51.343 に答える
0

なぜあなたのコンパイラは0x80がcharに適合しないという警告で文句を言わないのだろうか。それはあなたのプラットフォームでは-0x80から0x7Fまでの値しか表すことができない。

このコードを試してください:

 #include <stdio.h>
 #include <limits.h>
 #include <stdlib.h>

 int main() {
      printf("char can represent values from %d to %d.\n", CHAR_MIN, CHAR_MAX);
      return EXIT_SUCCESS;
 }

あなたの状況はオーバーフローと呼ばれます。

于 2010-10-23T00:46:32.923 に答える