2016-09-05 2 views
1

私はUbuntuを搭載したノートパソコンの小さな仕事のためのプログラムを書いています。私はプログラムを書くときに何の問題もありませんでした。それは完璧にうまくいって、必要なものすべてをやった。しかし、私はそれを私のWindows PCに移したとき、それは私にいくつかの非常に奇妙な値を与えました、そして、私はそれが何が間違っているか把握するように思われます。 UbuntuとWindowsの両方で、同じIDE、CodeBlocks 16.01を使用します。私は数時間この問題を解決しようとしていたが、私は本当にいくつかの助けに感謝するつもりです。Cプログラムは、Windowsで奇妙な値を与える動作していますが、Ubuntuでうまく動作します。

たとえば、すべてのプロンプトで値50を入力すると、50 + 50 + 50 + 50が200に等しいので、whileループの後に両方のprintfメソッドで200の結果が得られます。しかし私はtotal_weightで240、total_heightで100を得ます。これは私には意味がありません。これの原因は何ですか?あなたのコードで

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

int main() 
{ 
int weights[3], heights[3], i = 0; 
int total_weight, total_height; 

while (i <= 3) 
{ 
    printf("Person %d, enter your weight (kg): ",i+1); 
    scanf("%d",&weights[i]); 
    printf("Person %d, enter your height (cm): ",i+1); 
    scanf("%d", &heights[i]); 

    //Calculations for total weight and total length of all the people 
    total_weight = total_weight + weights[i]; 
    total_height = total_height + heights[i]; 

    printf("\n\tPerson %d's weight and height: %dkg, %dcm\n\n", i+1, weights[i], heights[i]); 
    i++; 
} 

//Printing the results of the earlier calculations 
printf("\tTotal weight of everyone: %d\n", total_weight); 
printf("\tTotal height of everyone: %d\n", total_height); 

return 0; 

}

+0

'int型total_weight、total_heightにコードを変更することができます;' - あなたはtotal_weightとtotal_heightの値は、この行の後は何だと思いますか? – immibis

答えて

2

、あなたがoff-by-oneを行っている

while (i <= 3) 

を言って。これにより、境界外のメモリアクセスに対して、undefined behaviorが呼び出されます。

詳細を述べると、C配列は0から始まるインデックスを持っています。したがって、次元が3の配列の場合、0から2までの有効なインデックスを持ちます。

だから、あなたが境界内に滞在する

while (i < 3) 

を使用する必要があります。

あなたのコードでは、total_weighttotal_heightは自動ローカル変数であり、未初期化で使用されています。したがって、それらには不確定値が含まれており、それらを使用するとUBが再び発生します。明示的に0に初期化する必要があります。

+0

最初は使っていないうちに使った(私は<4)。それは同じ不正確な値を与える。 – mmollle

+0

@ mmollle: 'weights [3]'という表現では、 '3'は最後のインデックスではなく要素の数を指定します。 3つの要素は、インデックスが0から2になることを意味します。 – IInspectable

+0

@IInspectable詳細をお寄せいただきありがとうございます。それにもかかわらず、私はその点についてはっきりしていると思った。 :) –

3

あなたの配列があふれています。各買いには3つのスペースしか割り当てない4つの値を入力しています。

+0

私は配列でより多くのスペースを割り当てようとしましたが、私は受け取った値がまだtotal_heightから240であり、total_height intで6899064です。そして、割り当てられた3つのスペースを持つ配列は、私のUbuntuでまだ動作しています、どうすれば可能ですか? – mmollle

+0

コンパイラが、特に最適化していないときに、デバッグやその他の情報のために余分なスペースをローカル変数に埋め込むことがあることが時々あります。しかし、他の人が指摘しているように、これはあなたが持っている問題には実際には関係しません。これは初期化されていないtotal_weightとtotal_height変数です。 –

3

あなたが初期化されていないtotal_heighttotal_weightを使用している:

int total_weight, total_height; 

/* ... */ 
total_weight = total_weight + weights[i]; 
total_height = total_height + heights[i]; 

彼らはゼロで初期化する必要があります。

int total_weight = 0, total_height = 0; 

またi == 3あなたはweights/heights配列のうちのメモリにアクセスしようとしているとき。次の2つの方法でそれを解決することができます

  1. は条件補正を経由して第四の要素にアクセスもを許可しない:while(i < 3) {
  2. 宣言より有能な配列がint weights[4], heights[4];
  3. のLinux(UbuntuのようなベースのDebian、)上のあなたのコードをコンパイルする
2

:次の警告で

gcc-4.9 -O3 -g3 -W -Wall -Wextra -std=c11 stackover.c -o stackover 

結果に念頭に置いたものと

stackover.c: In function ‘main’: 
stackover.c:12:5: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result [-Wunused-result] 
    scanf("%d",&weights[i]); 
    ^
stackover.c:14:5: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result [-Wunused-result] 
    scanf("%d", &heights[i]); 
    ^
stackover.c:17:42: warning: iteration 3u invokes undefined behavior [-Waggressive-loop-optimizations] 
    total_weight = total_weight + weights[i]; 
             ^
stackover.c:9:7: note: containing loop 
while (i <= 3) 
    ^
stackover.c:18:18: warning: ‘total_height’ may be used uninitialized in this function [-Wmaybe-uninitialized] 
    total_height = total_height + heights[i]; 
       ^
stackover.c:17:18: warning: ‘total_weight’ may be used uninitialized in this function [-Wmaybe-uninitialized] 
    total_weight = total_weight + weights[i]; 

は、我々は

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

int main() 
{ 
    int weights[4], heights[4], i = 0; 
    int total_weight = 0, total_height = 0; 
    int res; 
    // four persons 
    while (i <= 3) { 
    printf("Person %d, enter your weight (kg): ", i + 1); 
    res = scanf("%d", &weights[i]); 
    if(res != 1){ 
     fprintf(stderr,"Only one person, thank you\n"); 
     exit(EXIT_FAILURE); 
    } 
    printf("Person %d, enter your height (cm): ", i + 1); 
    res = scanf("%d", &heights[i]); 
    if(res != 1){ 
     fprintf(stderr,"Only one person, thank you\n"); 
     exit(EXIT_FAILURE); 
    } 
    //Calculations for total weight and total length of all the people 
    total_weight = total_weight + weights[i]; 
    total_height = total_height + heights[i]; 

    printf("\n\tPerson %d's weight and height: %dkg, %dcm\n\n", i + 1, 
      weights[i], heights[i]); 
    i++; 
    } 

    //Printing the results of the earlier calculations 
    printf("\tTotal weight of everyone: %d\n", total_weight); 
    printf("\tTotal height of everyone: %d\n", total_height); 

    exit(EXIT_SUCCESS); 
} 
関連する問題