2013-04-22 110 views
0

处理一个程序,它将从几个文件中读取数据,将其扫描到数组中,并最终在屏幕上打印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中,等等;以便它们可以平均出来并存储。

回答

1

你的二维数组传递给一个函数,你必须写函数定义,就像我注意到这个

void avg(int score[][4], float *average); 
1

第一件事情就是你的缓冲区溢出。为我和j循环溢出一个。

2

&&scores&average在调用avg

avg(scores, average); 

更改原型avg

和改变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的N元素数组”的表达式被转换(“decays”)为类型的表达式“指向T ”。由于在avg调用中的scores的类型是“由12个元素组成的4个元素数组的12个元素数组”int“,传递给该函数的表达式将具有类型”指向4个元素的数组int“或int (*)[4]

类似地,表达“平均值”的类型将从“float的13元素阵列”转换为“指向float”的指针。

&scores的类型将是“指向由12个元素组成的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]隐含地解引用指针。

请注意,在您的代码中,您的平均值将最终被截断为较低的整数值;一个整数除以一个整数得到一个整数结果,所以一个表达式如5/4将产生1,而3/4将产生0.如果你想得到一个小数值,你需要使其中一个操作数为float:

average[i] = total/4.0; 

最后,你不会将结果平均值写入average数组;你只需创建并分配一些变量,这些变量对于avg函数是本地的;一旦函数退出,那些变量就会消失。在上面的代码中,我简单地用average数组的元素替换了avgN变量。

任何时候,你发现自己创造了一堆的变量,如avg1avg2avg3,退后一步,并意识到你真正想在这里是一个数组。同样,当你发现自己写之类的语句

avg1 = total1/4.0; 
avg2 = total2/4.0; 
avg3 = total3/4.0; 

真正想在这里是一个循环:

for (i = 0; i < N; i++) 
    avg[i] = total[i]/4.0; 

唯一真正剩余的缺陷就是avg函数假定总是会有每个阵列中有13个元素,这限制了它的效用。最好通过行数作为一个单独的参数:

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

当然,列在scores数量仍固定在4,如果你想支持分数与任意数量的列,那么你将不得不做一些不同的事情。但是,我们将在未来保留这一点。

相关问题