代碼的運行與我預期的不同,我認為*(score i*n j)有問題,也可能是其他地方的問題,我不太確定,但我不知道如何修改它。
#include <stdio.h>
#define STUD 30 // Maximum number of students possible
#define COURSE 5 // The maximum number of possible exam subjects
void Total(int *score, int sum[], float aver[], int m, int n);
void Print(int *score, int sum[], float aver[], int m, int n);
int main(void)
{
int i, j, m, n, score[STUD][COURSE], sum[STUD];
float aver[STUD];
printf("Enter the total number of students and courses:\n");
scanf("%d %d",&m,&n);
printf("Enter score:\n");
for (i = 0; i < m; i )
{
for (j = 0; j < n; j )
{
scanf("%d", &score[i][j]);
}
}
Total(*score, sum, aver, m, n);
Print(*score, sum, aver, m, n);
return 0;
}
void Total(int *score, int sum[], float aver[], int m, int n)
{
int i, j;
for (i = 0; i < m; i )
{
sum[i] = 0;
for (j = 0; j < n; j )
{
sum[i] = sum[i] *(score i * n j);
}
aver[i] = (float) sum[i] / n;
}
}
void Print(int *score, int sum[], float aver[], int m, int n)
{
int i, j;
printf("Result:\n");
for (i = 0; i < m; i )
{
for (j = 0; j < n; j )
{
printf("M\t", *(score i * n j));
}
printf("]\t%6.1f\n", sum[i], aver[i]);
}
}
運行程式示例:
Enter the total number of students and courses:
2 3↙
Enter score:
90↙
95↙
97↙
82↙
73↙
69↙
Result:
90 95 97 282 94.0
82 73 69 224 74.7
uj5u.com熱心網友回復:
編譯程式不會產生警告或錯誤。使用您提供的示例輸入運行它會產生:
Enter the total number of students and courses:
2 3
Enter score:
90
95
97
82
73
69
Result:
90 95 97 282 94.0
404780 0 82 404862 134954.0
這對第一組分數是正確的,但不是第二組。正如您的直覺,這意味著您通過指標數學訪問陣列的數學可能是錯誤的。
考慮一下您的陣列在記憶體中的實際外觀。您已經在堆疊上分配了一個如下所示的陣列:
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
| | | | | |
--- --- --- --- ---
您的示例輸入已填充如下:
--- --- --- --- ---
| 90| 95| 97| | |
--- --- --- --- ---
| 82| 73| 69| | |
--- --- --- --- ---
...
如果要訪問第二行的第一個元素,則需要偏移量,i * 5而不是i * 3使用i * n. 這一點5我們可以從你的常數中得到COURSE。
*(score i * COURSE j)
當您使用不同的偏移量時,您會得到尚未初始化的資料,這就是您看到垃圾值的原因。如果將陣列中的所有值初始化為0,但保持代碼不變,則可以看到這一點。
int i, j, m, n, score[STUD][COURSE] = {0}, sum[STUD];
Enter the total number of students and courses:
2 3
Enter score:
90
95
97
82
73
69
Result:
90 95 97 282 94.0
0 0 82 82 27.3
uj5u.com熱心網友回復:
正如您所注意到的,問題是您的陣列訪問——您score[i][j]在 main 中使用來填充陣列,然后*(score i * n j)在您的TotalandPrint函式中嘗試訪問它,這些是不同的且不兼容的。最簡單的修復可能只是修復宣告Total并Print匹配score您正在使用的:
void Total(int score[][COURSE], int sum[], float aver[], int m, int n);
void Print(int score[][COURSE], int sum[], float aver[], int m, int n);
然后你可以score[i][j]在它們中使用,一切都應該作業。你也會通過scoreas justscore而不是*score.
或者,在 main 中更改scoreto的宣告score[STUD*COURSE]并使用
*(score i * n j)(或score[i*n j])來訪問它,就像在Totaland中一樣Print。
uj5u.com熱心網友回復:
OP 不清楚為什么代碼用于#defines定義陣列的行和列的值score,然后繼續使用scanf()輸入可能與 沖突或不沖突的新值,#defines甚至溢位陣列記憶體。任何一種方法都有效,但同時使用這兩種方法會使事情變得混亂。選擇一個或另一個。
另外:如果需要動態大小的陣列,則可以將其創建為指標,或指向已分配記憶體的指標,或使用VLA
例如:使用具有動態記憶體分配的用戶輸入來創建大小適合當前需要的陣列的簡短示例:
注意:以下方法允許您使用普通陣串列示法來分配值:
score[i][j] = someValue://easy to use and readable
//as opposed to
*(score i*n j) = someValue;// cumbersome to use and read
例子:
int student, course;//using descriptive variables
printf("Enter the total number of students and courses:\n");
scanf("%d %d",&student,&course);
int (*score)[course] = create_arr_2d (student, course);
if(score)
{ //use score
...
free(score);
}
在哪里create_arr_2d(...)定義:
void * create_arr_2d (size_t x, size_t y)
{
int (*ptr_2)[x] = malloc( sizeof (int *[y]) ); //allocate a true 2D array
if(ptr_2)
{
memset(ptr_2, 0, sizeof **ptr_2);
}
return ptr_2;
}
(方法的功勞)
按原樣處理您的代碼。首先,以下創建變數,但不初始化任何變數:
int i, j, m, n, score[STUD][COURSE], sum[STUD];
float aver[STUD];
要消除您可能會看到的一些問題,請初始化:
int i=0, j=0, m=0, n=0, score[STUD][COURSE]={{0}}, sum[STUD]={0};
float aver[STUD]={0};
在給定代碼的函式原型中:
Total(int *score, int sum[], float aver[], int m, int n)
int *score
建議傳遞一個指向一維陣列的指標,但如果它用于表示score[STUD][COURSE],那么它應該作為`score[m][n] 傳遞,原型更改為:
Total(int m, int n, int score[m][n], int sum[m], float aver[m]);
然后稱為:
Total(STUD, COURSE, score[STUD][COURSE], sum[STUD], aver[STUD]){...}
注意,這種安排使用了VLA 型別的函式 argumentmnts
另請注意,一個陣列,例如:(從您的值中縮短以便于查看)
int m = 5;
int n = 4
int array[m][n] = {{0}}
創建一個連續的記憶體塊,可以想象在記憶體中看起來像這樣:
`|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|...`
0 5 10 15 20
可以在 for 回圈中訪問所有元素,如下所示:
for(int i=0; i<m; i
for(int j=0;j<n;j )
*(array i*n j);
...
...
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/483986.html
上一篇:在鏈表函式末尾插入不起作用
下一篇:為什么這會發生在C指標上?
