C程序奇怪的输出和错误的输出
C program strange output and wrong output
晚上好。我试图让下面的程序给我平均值和平均值。到目前为止,我有以下内容。
当使用 <math.h>
的 round
函数时,它 returns 一个零。是的,我尝试使用 -std=99
、-lm
和 -fno-builtin
进行编译。 None 其中似乎很重要。它仍然 returns 为零。
应该使用ComputeAverage
给出的ave
。这是我得到奇怪输出的地方。当平均值为 运行 时,有时会显示为 148.28
(这应该是正确的)。
但是我注意到如果我 运行 它接近之前的 运行 我得到以下例子:2303125649788529278976.00
, -31360458752.00
, -319407486092479668309433442631680.00
,和 2618000384.00
。
另请注意,我仍在添加代码,但已尝试确保删除对当前情况无用的任何内容。
代码如下。
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define _ISOC99_SOURCE
#define N 8
typedef struct _Matrix {
double element[N][N];
} Matrix;
void PrintMatrix(Matrix a)
{
int i;
int j;
for (i=0; i<N; i++)
{
for (j=0; j<N; j++)
{
printf("%g ", a.element[i][j]);
}//Inner for
printf("\n");
}//Outer For
}// printMatrix
float ComputeAverage(Matrix a)
{
float sum;
float average;
int i;
int j;
for (i=0; i<N; i++)
{
for (j=0; j<N; j++)
{
sum += a.element[i][j];
}//inner for
average = sum / 64;
}//for
//a.element[i][j];
printf("Average = %.2f",average);
printf("\n");
// printf ("Testing Sum = %f", sum);
// printf("\n");
}// ComputeAverage
Matrix Q50 = {{16, 11, 10, 16, 24, 40, 51, 61,
12, 12, 14, 19, 26, 58, 60, 55,
14, 13, 16, 24, 40, 57, 69, 56,
14, 17, 22, 29, 51, 87, 80, 62,
18, 22, 37, 56, 68,109,103, 77,
24, 35, 55, 64, 81,104,113, 92,
49, 64, 78, 87,103,121,120,101,
72, 92, 95, 98,112,100,103, 99}
};
int main(int argc, const char * argv[])
{
Matrix M = {{154, 123, 123, 123, 123, 123, 123, 136,
192, 180, 136, 154, 154, 154, 136, 110,
254, 198, 154, 154, 180, 154, 123, 123,
239, 180, 136, 180, 180, 166, 123, 123,
180, 154, 136, 167, 166, 149, 136, 136,
128, 136, 123, 136, 154, 180, 198, 154,
123, 105, 110, 149, 136, 136, 180, 166,
110, 136, 123, 123, 123, 136, 154, 136}};
// need to implement PrintMatrix
PrintMatrix(M);
// need to implement ComputeAverage
float ave = ComputeAverage(M);
// need to implement round
int dc = round(ave);
//printf("Ave = %d\n",dc);
return EXIT_SUCCESS;
}
您在 float ave = ComputeAverage(M);
中使用 float ComputeAverage(Matrix a)
的 return(return 没有值)调用 未定义行为
您通过使用 sum += a.element[i][j];
中未初始化的 sum
在上述 未定义行为 中调用 未定义行为
您通过将 float
传递给 round(ave)
来在上述两个 Undefined Behavior 中调用 Undefined Behavior,其中round
期望 double
.
解决方案 -- 使 ComputeAverage(Matrix a)
键入 double
和 return average;
(并清除有关 Missing Braces 的警告 在你的 Matrix
初始值设定项中),例如
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define _ISOC99_SOURCE
#define N 8
typedef struct _Matrix {
double element[N][N];
} Matrix;
void PrintMatrix (Matrix a)
{
int i;
int j;
for (i=0; i<N; i++) {
for (j=0; j<N; j++)
printf (" %3g", a.element[i][j]);
putchar ('\n');
}
}
double ComputeAverage(Matrix a)
{
double sum = 0;
double average;
int i;
int j;
for (i = 0; i < N; i++) {
for (j=0; j<N; j++)
sum += a.element[i][j];
average = sum / 64.0;
}
return average;
}
Matrix Q50 = {{{ 16, 11, 10, 16, 24, 40, 51, 61 },
{ 12, 12, 14, 19, 26, 58, 60, 55 },
{ 14, 13, 16, 24, 40, 57, 69, 56 },
{ 14, 17, 22, 29, 51, 87, 80, 62 },
{ 18, 22, 37, 56, 68,109,103, 77 },
{ 24, 35, 55, 64, 81,104,113, 92 },
{ 49, 64, 78, 87,103,121,120,101 },
{ 72, 92, 95, 98,112,100,103, 99 }}};
int main (void)
{
Matrix M = {{{ 154, 123, 123, 123, 123, 123, 123, 136 },
{ 192, 180, 136, 154, 154, 154, 136, 110 },
{ 254, 198, 154, 154, 180, 154, 123, 123 },
{ 239, 180, 136, 180, 180, 166, 123, 123 },
{ 180, 154, 136, 167, 166, 149, 136, 136 },
{ 128, 136, 123, 136, 154, 180, 198, 154 },
{ 123, 105, 110, 149, 136, 136, 180, 166 },
{ 110, 136, 123, 123, 123, 136, 154, 136 }}};
PrintMatrix (M);
double ave = ComputeAverage(M);
printf ("ave: %g\n", ave);
int dc = round(ave);
printf ("dc : %d\n", dc);
return EXIT_SUCCESS;
}
例子Use/Output
$ ./bin/computeavg
154 123 123 123 123 123 123 136
192 180 136 154 154 154 136 110
254 198 154 154 180 154 123 123
239 180 136 180 180 166 123 123
180 154 136 167 166 149 136 136
128 136 123 136 154 180 198 154
123 105 110 149 136 136 180 166
110 136 123 123 123 136 154 136
ave: 148.281
dc : 148
启用编译器警告
始终在启用警告的情况下编译,并且不要接受代码,直到它在没有警告的情况下干净地编译.要启用警告,请将 -Wall -Wextra
添加到 gcc
或 clang
编译字符串。 (添加 -pedantic
以获得几个额外的警告)。对于 clang
,您可以使用 -Weverything
(但这包括许多无关的警告)。对于gcc/clang,推荐:
-Wall -Wextra -pedantic -Wshadow
对于VS(cl.exe
on windoze),添加/W3
(或者使用/Wall
但是你会得到很多无关的非-代码相关的警告)。
阅读并理解每个警告。他们将确定任何问题,以及问题发生的确切路线。通过聆听编译器告诉您的内容,您可以学到很多东西。
如果您还有其他问题,请告诉我。
晚上好。我试图让下面的程序给我平均值和平均值。到目前为止,我有以下内容。
当使用 <math.h>
的 round
函数时,它 returns 一个零。是的,我尝试使用 -std=99
、-lm
和 -fno-builtin
进行编译。 None 其中似乎很重要。它仍然 returns 为零。
应该使用ComputeAverage
给出的ave
。这是我得到奇怪输出的地方。当平均值为 运行 时,有时会显示为 148.28
(这应该是正确的)。
但是我注意到如果我 运行 它接近之前的 运行 我得到以下例子:2303125649788529278976.00
, -31360458752.00
, -319407486092479668309433442631680.00
,和 2618000384.00
。
另请注意,我仍在添加代码,但已尝试确保删除对当前情况无用的任何内容。 代码如下。
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define _ISOC99_SOURCE
#define N 8
typedef struct _Matrix {
double element[N][N];
} Matrix;
void PrintMatrix(Matrix a)
{
int i;
int j;
for (i=0; i<N; i++)
{
for (j=0; j<N; j++)
{
printf("%g ", a.element[i][j]);
}//Inner for
printf("\n");
}//Outer For
}// printMatrix
float ComputeAverage(Matrix a)
{
float sum;
float average;
int i;
int j;
for (i=0; i<N; i++)
{
for (j=0; j<N; j++)
{
sum += a.element[i][j];
}//inner for
average = sum / 64;
}//for
//a.element[i][j];
printf("Average = %.2f",average);
printf("\n");
// printf ("Testing Sum = %f", sum);
// printf("\n");
}// ComputeAverage
Matrix Q50 = {{16, 11, 10, 16, 24, 40, 51, 61,
12, 12, 14, 19, 26, 58, 60, 55,
14, 13, 16, 24, 40, 57, 69, 56,
14, 17, 22, 29, 51, 87, 80, 62,
18, 22, 37, 56, 68,109,103, 77,
24, 35, 55, 64, 81,104,113, 92,
49, 64, 78, 87,103,121,120,101,
72, 92, 95, 98,112,100,103, 99}
};
int main(int argc, const char * argv[])
{
Matrix M = {{154, 123, 123, 123, 123, 123, 123, 136,
192, 180, 136, 154, 154, 154, 136, 110,
254, 198, 154, 154, 180, 154, 123, 123,
239, 180, 136, 180, 180, 166, 123, 123,
180, 154, 136, 167, 166, 149, 136, 136,
128, 136, 123, 136, 154, 180, 198, 154,
123, 105, 110, 149, 136, 136, 180, 166,
110, 136, 123, 123, 123, 136, 154, 136}};
// need to implement PrintMatrix
PrintMatrix(M);
// need to implement ComputeAverage
float ave = ComputeAverage(M);
// need to implement round
int dc = round(ave);
//printf("Ave = %d\n",dc);
return EXIT_SUCCESS;
}
您在 float ave = ComputeAverage(M);
中使用 float ComputeAverage(Matrix a)
的 return(return 没有值)调用 未定义行为
您通过使用 sum += a.element[i][j];
中未初始化的 sum
在上述 未定义行为 中调用 未定义行为
您通过将 float
传递给 round(ave)
来在上述两个 Undefined Behavior 中调用 Undefined Behavior,其中round
期望 double
.
解决方案 -- 使 ComputeAverage(Matrix a)
键入 double
和 return average;
(并清除有关 Missing Braces 的警告 在你的 Matrix
初始值设定项中),例如
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define _ISOC99_SOURCE
#define N 8
typedef struct _Matrix {
double element[N][N];
} Matrix;
void PrintMatrix (Matrix a)
{
int i;
int j;
for (i=0; i<N; i++) {
for (j=0; j<N; j++)
printf (" %3g", a.element[i][j]);
putchar ('\n');
}
}
double ComputeAverage(Matrix a)
{
double sum = 0;
double average;
int i;
int j;
for (i = 0; i < N; i++) {
for (j=0; j<N; j++)
sum += a.element[i][j];
average = sum / 64.0;
}
return average;
}
Matrix Q50 = {{{ 16, 11, 10, 16, 24, 40, 51, 61 },
{ 12, 12, 14, 19, 26, 58, 60, 55 },
{ 14, 13, 16, 24, 40, 57, 69, 56 },
{ 14, 17, 22, 29, 51, 87, 80, 62 },
{ 18, 22, 37, 56, 68,109,103, 77 },
{ 24, 35, 55, 64, 81,104,113, 92 },
{ 49, 64, 78, 87,103,121,120,101 },
{ 72, 92, 95, 98,112,100,103, 99 }}};
int main (void)
{
Matrix M = {{{ 154, 123, 123, 123, 123, 123, 123, 136 },
{ 192, 180, 136, 154, 154, 154, 136, 110 },
{ 254, 198, 154, 154, 180, 154, 123, 123 },
{ 239, 180, 136, 180, 180, 166, 123, 123 },
{ 180, 154, 136, 167, 166, 149, 136, 136 },
{ 128, 136, 123, 136, 154, 180, 198, 154 },
{ 123, 105, 110, 149, 136, 136, 180, 166 },
{ 110, 136, 123, 123, 123, 136, 154, 136 }}};
PrintMatrix (M);
double ave = ComputeAverage(M);
printf ("ave: %g\n", ave);
int dc = round(ave);
printf ("dc : %d\n", dc);
return EXIT_SUCCESS;
}
例子Use/Output
$ ./bin/computeavg
154 123 123 123 123 123 123 136
192 180 136 154 154 154 136 110
254 198 154 154 180 154 123 123
239 180 136 180 180 166 123 123
180 154 136 167 166 149 136 136
128 136 123 136 154 180 198 154
123 105 110 149 136 136 180 166
110 136 123 123 123 136 154 136
ave: 148.281
dc : 148
启用编译器警告
始终在启用警告的情况下编译,并且不要接受代码,直到它在没有警告的情况下干净地编译.要启用警告,请将 -Wall -Wextra
添加到 gcc
或 clang
编译字符串。 (添加 -pedantic
以获得几个额外的警告)。对于 clang
,您可以使用 -Weverything
(但这包括许多无关的警告)。对于gcc/clang,推荐:
-Wall -Wextra -pedantic -Wshadow
对于VS(cl.exe
on windoze),添加/W3
(或者使用/Wall
但是你会得到很多无关的非-代码相关的警告)。
阅读并理解每个警告。他们将确定任何问题,以及问题发生的确切路线。通过聆听编译器告诉您的内容,您可以学到很多东西。
如果您还有其他问题,请告诉我。