C程序在Windows中表现出奇怪的值,但在Ubuntu中运行良好

时间:2016-09-05 20:48:48

标签: c arrays

我在Ubuntu的笔记本电脑上为学校的一项小任务写了一个程序。编写程序时我没遇到任何问题。它工作得很好,做了应有的一切。但当我把它移到我的Windows PC上时,它给了我一些非常奇怪的值,我似乎无法弄清楚它有什么问题。我在Ubuntu和Windows上使用相同的IDE,CodeBlocks 16.01。我一直试图解决这个问题好几个小时但是我坚持了所以我真的很感激一些帮助。

例如,如果我在每个提示符处输入值50,那么在while循环之后的两个printf方法中将得到200的结果,就像它应该是50 + 50 + 50 + 50等于200.然而在Windows中我总共获得240个total_weight和100个total_height,这对我来说没有任何意义。这是什么原因?

#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;

}

4 个答案:

答案 0 :(得分:3)

你的数组溢出了。您在每次购买中输入4个值,仅分配3个空格。

答案 1 :(得分: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数组中的内存时。您可以通过两种方式解决它:

  1. 禁止通过条件更正访问第4个元素:while(i < 3) {
  2. 声明更强大的数组int weights[4], heights[4];

答案 2 :(得分:2)

在您的代码中,通过说

 while (i <= 3)

你要去off-by-one。这会调用undefined behavior,以进行超出范围的内存访问。

详细说明,C数组具有基于0的索引。因此,对于维度为3的数组,将具有0到2(包括0和2)的有效索引。

所以,你应该使用

while (i < 3)

留在界限中。

也就是说,在您的代码中,total_weighttotal_height是自动局部变量,它们是未初始化的。因此,它们包含不确定的值,并且再次使用它们会导致UB。你必须明确地将它们初始化为0。

答案 3 :(得分:2)

使用

在Linux上编译代码(基于Debian,如Ubuntu)
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);   
}