3

重複の可能性:
C のマクロ展開と整数演算について混乱して
いる なぞなぞ (C で)

次の C プログラムの出力は、配列内の要素を出力することです。しかし、実際に実行すると、そうはなりません。

  #include<stdio.h>

  #define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
  int array[] = {23,34,12,17,204,99,16};

  int main()
  {
      int d;

      for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
          printf("%d\n",array[d+1]);

      return 0;
  }

何故ですか?

4

7 に答える 7

5

sizeof()を返すunsigned intので、<= 比較でdは に変換されunsigned intます。に変換すると -1unsigned intです0xffffff。以来0xffffff > (7-2)、forループ本体は一度も実行されません。

于 2012-06-05T15:44:42.527 に答える
4

が unsignedsizeofの type の値を返すため、これは失敗します。size_tこれにより、比較によって が-1unsigned に昇格されます。これは一般に非常に大きな値であり、比較が失敗します。

符号の不一致に関する警告が表示されるはずです。

于 2012-06-05T15:43:47.620 に答える
3

ポイントは、sizeof戻り値の型です。

これsize_tは符号なしの型である-1ため、比較のためにその型に変換すると、5 よりもはるかに大きい型の最大値が生成されます。

于 2012-06-05T15:42:46.957 に答える
1
for(d=-1;d <= ((int)TOTAL_ELEMENTS-2);d++)
于 2012-06-05T15:45:59.567 に答える
1

これはより明確だと思います:

for(d = 0; d < TOTAL_ELEMENTS; d++)
   printf("%d\n",array[d]);

そして、size_tケースはもう問題にならないはずです。

于 2012-06-05T15:49:34.263 に答える
0

動作するこのループを記述するより標準的な方法は次のようになります。

for(d = 0; d < TOTAL_ELEMENTS; d++)
   ...

ここですでに他の何人かによって正しく指摘されたように、問題は符号付き/符号なしの値が比較されることにあります。この構成により、問題は回避されたはずです。

于 2012-06-05T15:40:26.857 に答える
0

私が次のことを行うと、元の問題が機能します。

#define TOTAL_ELEMENTS 7
int array[] = {23,34,12,17,204,99,16};

int main()
{
  int d;

  for(d=-1; d <= (TOTAL_ELEMENTS - 2); d++)
      printf("%d\n",array[d+1]);

  return 0;
}

これは、負の数 d=-1 を (TOTAL_ELEMENTS-2) と比較することと関係があります。sizeof かもしれないと思いますが、その理由を調べることは演習として残しておきます。

元の #define をそのままにしておく --

#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))

-- ただし、ゼロベースのインデックスを使用しても機能しました。

元の TOTAL_ELEMENTS 定義が原因でループが印刷されなかった理由がわかりません。

于 2012-06-05T15:52:48.057 に答える