2

私は数十年前にいくつかのCプログラミングをしました。私は言語を再学習しようとしています。私はこれを書きました。思いがけないことがある。「short int」を「int」に変更すると、うまくいくようです。誰でも私のコードを見て、何か問題があるかどうか、またはこれがコンパイラの問題かどうかを確認できますか? Linuxでgccを使用しています。

#include <stdio.h>

int main(void) {

    short int age = 0;
    short int num_1_yr_olds = 0;
    short int num_2_and_3_yr_olds = 0;
    short int num_above_3_yr_olds = 0;

    while(1) {

        printf ("Enter age: ");
        scanf ("%d", &age);

        if (age < 1) {
            break;
        }

        switch (age) {
            case 1:
                ++num_1_yr_olds;
                break;
            case 2:
            case 3:
                ++num_2_and_3_yr_olds;
                break;
            default:
                ++num_above_3_yr_olds;
                break;
        }
    }
    printf ("Number of 1 year olds = %d\n", num_1_yr_olds);
    printf ("Number of 2 and 3  year olds = %d\n", num_2_and_3_yr_olds);
    printf ("Number above 3 year olds = %d\n", num_above_3_yr_olds);
}

入力

Enter age: 1
Enter age: 1
Enter age: 1
Enter age: -1

出力

Number of 1 year olds = -1
Number of 2 and 3  year olds = 0
Number above 3 year olds = 0

num_1_yr_olds 値が台無しになっています。私は 3 を期待していましたが、-1 を取得します。num_1_yr_olds の値は、入力に関係なく -1 になります。

4

2 に答える 2

9

あなたの問題はここにあります:

short int age = 0;
:
scanf ("%d", &age);

データ型がフォーマット文字列と一致していることを確認する必要があります。a の正しい書式指定子short int%hdではなく%dです。

一部のコンパイラは実際にこれをチェックして警告します。

発生する可能性が高いのは、データとフォーマット文字列のずれが原因でshort int「間違った」値になり、カウントが台無しになっていることです。


より詳細には、x86 のような 2 の補数のリトル エンディアン アーキテクチャの場合、anintを aにスキャンすると、short最下位半分がaageに、最上位半分が(メモリ内でnum_1_year_olds隣接している場合) 挿入される場合があります。age

グラフ的には、次のように考えるとわかりやすいかもしれません。

                         shorts in memory
                     +-----------------------+
What scanf("%hd") =< |          age          | \
  will write to.     +-----------------------+  = What scanf("%d")
                     |    num_1_year_olds    | /    will write to.
                     +-----------------------+
                     | num_2_and_3_year_olds |
                     +-----------------------+
                     | num_above_3_year_olds |
                     +-----------------------+

したがって、 と入力すると1、 にageなり1、 にnum_1_year_oldsなり0ます。

そうするたびに増えnum_1_year_oldsていきageますが、次回の入力1で上書きされます。scanf

最後に-1(2 の補数ですべて 1 ビット) を入力すると、ageとなり-1ますnum_1_year_olds

次に、ageは 1 未満であるため、ループが中断され、値は次のようになります{-1, 0, 0}

于 2012-09-24T05:15:29.877 に答える
2

試す

scanf ("%hd", &age);

age は short int 型なので。

于 2012-09-24T05:15:44.433 に答える