处理一个程序,该程序将从几个文件中读取数据,将其扫描到数组中,最后在屏幕上打印13个名称,每个名称旁边有4个数字,并且在这些数字之后写一个字母图表。
但是我遇到了一个我正在使用的功能之一的问题,其目的是计算平均值。它将一个学生测试的所有分数组合成一个值,然后将其除以4以找到平均值,然后将该平均值存储到不同数组的一个元素中。
函数调用是:
avg(&scores, &average);
分数和平均值的定义如下:
int scores[13][4];
float average[13];
并使用此循环填充了分数:
for(i=0; i<=13; i++)
{
for(j=0; j<=4; j++)
{
fscanf(score, "%d", &scores[i][j]);
}
}
fclose(score);
作为参考,使用的文件打开语句是:
FILE *student, *score;
score = fopen("scores.dat", "r");
该功能本身如下:
void avg(int *scores, float *average)
{
int total1 = scores[0][0] + scores[0][1] + scores[0][2] + scores[0][3];
int total2 = scores[1][0] + scores[1][1] + scores[1][2] + scores[1][3];
int total3 = scores[2][0] + scores[2][1] + scores[2][2] + scores[2][3];
int total4 = scores[3][0] + scores[3][1] + scores[3][2] + scores[3][3];
int total5 = scores[4][0] + scores[4][1] + scores[4][2] + scores[4][3];
int total6 = scores[5][0] + scores[5][1] + scores[5][2] + scores[5][3];
int total7 = scores[6][0] + scores[6][1] + scores[6][2] + scores[6][3];
int total8 = scores[7][0] + scores[7][1] + scores[7][2] + scores[7][3];
int total9 = scores[8][0] + scores[8][1] + scores[8][2] + scores[8][3];
int total10 = scores[9][0] + scores[9][1] + scores[9][2] + scores[9][3];
int total11 = scores[10][0] + scores[10][1] + scores[10][2] + scores[10][3];
int total12 = scores[11][0] + scores[11][1] + scores[11][2] + scores[11][3];
int total13= scores[12][0] + scores[12][1] + scores[12][2] + scores[12][3];
float avg1 = total1 / 4;
float avg2 = total2 / 4;
float avg3 = total3 / 4;
float avg4 = total4 / 4;
float avg5 = total5 / 4;
float avg6 = total6 / 4;
float avg7 = total7 / 4;
float avg8 = total8 / 4;
float avg9 = total9 / 4;
float avg10 = total10 / 4;
float avg11 = total11 / 4;
float avg12 = total12 / 4;
float avg13 = total13 / 4;
return;
}
这还不完整,我还是要告诉函数将avg1-avg13分配给数组。但是一旦我解决了这个错误,我就会继续努力。
尝试按原样运行程序会给我带来很多错误,所有错误基本相同:
ghp11.c: In function 'avg':
ghp11.c:127: error: subscripted value is neither array nor pointer
我不确定如何修复它以使其正常工作。我正在尝试将4个数组值组合成一个整数值并将其存储在total1等中;这样它们就可以被平均并存储起来。
答案 0 :(得分:2)
将&
&scores
从&average
和avg
放入avg( scores, average );
的来电中
avg
将void avg( int (*scores)[4], float *average ) // or int scores[][4]
的原型更改为
avg
并将{
int i = 0;
for ( i = 0; i < 13; i++ )
{
// you could write another loop for summing your total,
// but for just 4 elements writing it out isn't a big deal.
int total = scores[i][0] + scores[i][1] + scores[i][2] + scores[i][3];
average[i] = total / 4.0;
}
}
的正文更改为
sizeof
为什么会这样:除非它是_Alignof
,&
或一元T
运算符的操作数,否则表达式为“{-1}的N元素数组“转换(”衰减“)到”指向T
的指针“类型的表达式。由于scores
调用中avg
的类型是“{元素{1}}的4元素数组的13元素数组”,因此传递给函数的表达式将具有类型“指针”到int
“或int
的4元素数组。
类似地,表达式“average”的类型将从“int (*)[4]
的13个元素数组”转换为“指向float
的指针”。
float
的类型是“指向&scores
”或int
的4元素数组的13元素数组的指针。您可以这样做,但您必须在int (*)[14][3]
函数中明确取消引用scores
才能下标,例如
avg
但是,由于我们将其作为int total = {*scores)[0][0] + (*scores)[0][1] + ...;
传递,我们可以写
int (*scores)[4]
因为下标操作int total = scores[0][0] + scores[0][1] + ...;
隐式取消引用指针。
请注意,在您的代码中,您的平均值最终会被截断为较低的整数值;整数除以整数得到整数结果,因此像scores[0]
这样的表达式会产生1,而5/4
会产生0.如果你想得到一个小数值,你需要制作一个操作数浮动:
3/4
最后,您没有将结果平均值写入average[i] = total / 4.0;
数组;你只是创建和分配一组average
函数本地的变量;一旦函数退出,那些avg
变量就会消失。在上面的代码中,我只是将avgN
变量替换为avgN
数组的元素。
每当你发现自己创建了一堆变量,如average
,avg1
,avg2
时,请退后一步,意识到你真正想要的东西在这里是一个数组。同样,当你发现自己编写像
avg3
你真正想要的是一个循环:
avg1 = total1 / 4.0;
avg2 = total2 / 4.0;
avg3 = total3 / 4.0;
唯一真正存在的缺陷是for ( i = 0; i < N; i++ )
avg[i] = total[i] / 4.0;
函数假定每个数组中总会有13个元素,这限制了它的实用性。最好将行数作为单独的参数传递:
avg
并将其命名为
void average( int (*scores)[4], int *average, size_t rows )
{
size_t i;
for ( i = 0; i < rows; i++ )
{
int total = scores[i][0] + scores[i][1] + scores[i][2] + scores[i][3];
average[i] = total / 4.0;
}
}
当然,size_t rows = sizeof scores / sizeof scores[0]; // divides the total number of bytes
// in the array by the number of bytes
// in a single element, giving the
// number of elements in the array
avg( scores, average, rows );
中的列数仍然固定为4.如果您想支持具有任意列数的分数,那么您将不得不做一些不同的事情。但是,我们将把它留给未来。
答案 1 :(得分:1)
将2D数组传递给函数,你必须像这样编写函数定义
void avg( int score[][4], float *average );
答案 2 :(得分:1)
我注意到的第一件事是你的缓冲区溢出。对于i和j循环溢出一个。