[英]Wrong values inside of array
我是一名新的C語言學習者,面臨2個問題。 (寫在同一頁上,因為我認為這是兩者的根本原因)
int mrr [2][3];
for (int r=0;r<2;r++)
{
for (int c=0; c<3; c++)
printf("[%d],[%d]:%d\n",r,c,mrr[r][c]);
}
我讀到,如果我們不為新創建的數組提供值,則它在其所有單元格內的默認值為0。 但是當我打印結果時,它顯示:
[0],[0]:0
[0],[1]:4201072
[0],[2]:6422224
[1],[0]:6422280
[1],[1]:6422476
[1],[2]:1977208000
其次,以下代碼返回完全意外的值(平均值)431374336.000000
double getAverage(int arr[], int size) {
int i;
double avg;
double sum = 0;
for (i = 0; i < size; ++i) {
sum += arr[i];
}
avg = sum / size;
return avg;
}
double balance[5] = {1000, 2, 7, 17, 50};
double avg = getAverage(balance, 5 );
printf( "Average value is: %f ", avg );
在函數內部定義的,沒有static
或_Thread_local
對象不會自動初始化,並且具有不確定的值。 為了確保初始化數組mrr
,請使用int mrr[2][3] = { 0 };
定義它int mrr[2][3] = { 0 };
,它將初始化為全零。
第二個問題中的代碼不完整,但是,大概是在調用函數中定義了數組,並且未初始化,因此其值是不確定的。
默認情況下,在函數內部定義的數組(即本地數組)的[值]是不確定的。 另一方面,全局(即靜態)變量默認情況下初始化為0。 參見相關文章: C中int數組的初始值
要解決您的問題,只需手動初始化數組即可,例如
for (int r=0;r<2;r++)
{
for (int c=0; c<3; c++) {
mrr[r][c] = 0;
printf("[%d],[%d]:%d\n",r,c,mrr[r][c]);
}
}
您對未初始化變量的問題已被注釋和其他答案很好地涵蓋了。 這個答案是您的第二個問題,關於getAverage()
的意外輸出。
您將balance
定義為double
數組,但是getAverage()
期望使用int
數組。 當我改變時:
double getAverage(int arr[], int size) { ... }
至:
double getAverage(double arr[], int size) { ... }
我得到了預期的結果:215.2。 原始代碼中的隱式類型轉換[1]導致意外行為。
另外,我不知道您使用的是什么編譯器,但是當我編譯原始代碼[2]時, gcc
發出了以下警告:
warning: incompatible pointer types passing 'double [5]' to parameter of type 'int *'
...這是麻煩正在醞釀中的死胡同。 如果您的編譯器沒有生成此警告,或者您取消了警告,或者如果警告已記錄到文件或您未查看的內容中,則建議再次使它們可見。 注意編譯器警告為我節省了無盡的痛苦。
[1]“類型轉換”可能不是此處的最佳術語; 即使存在一些陷阱,類型轉換通常也是良性的; 這里發生的是,將組成double
值的字節讀為int
,並且這兩種數據類型的字節結構非常不同; 這就是為什么原始代碼的輸出看起來好像在處理如此瘋狂的數字:例如,當作為int
讀取時,用於將“ 17”表示為雙精度字符的字節變得非常不同。 更糟糕的是,逐步遍歷組成double
值數組的字節,就好像它是一個int
值數組一樣,它甚至可能根本不在適當的元素邊界處查看該數組元素。 簡而言之,類型差異會造成嚴重破壞。
[2]“原始代碼”是指您的代碼具有足夠的開銷代碼來進行編譯,例如include
pragma和main()
主體; 我總體上同意關於提供完整的最小示例的其他評論。
這個補充性回答是針對OP對我先前的回答的評論。 防御者問:
“我還有一些問題。如果期望一個int類型的數組,並且我發送了為什么會在360度范圍內更改結果的信息,我發送了兩次。我仍然沒有得到答案。”
用short int
和int
之間的類型沖突更容易說明這一點,但是相同的想法適用於int
與double
。
看一下這段代碼:
#include <stdlib.h>
#include <stdio.h>
void functionA(short int[], int size);
int main(void) {
printf("sizeof short int : %lu\n", sizeof(short int));
printf("sizeof int : %lu\n", sizeof(int));
printf("\n\n");
printf("==== sending short int to functionA() ====\n");
short int shortdata[4] = {10, 20, 50, 100};
functionA(shortdata, 4);
printf("==== sending int to functionA() ====\n");
int intdata[4] = {10, 20, 50, 100};
functionA(intdata, 4);
}
void functionA(short int arr[], int size) {
int i;
char* ptr;
for (i = 0; i < size; ++i) {
ptr = &arr[i];
printf("bytes of 'arr[%d]' : %x %x\n", i, *ptr, *(ptr+1));
printf("value of 'arr[%d]' : %d\n", i, arr[i]);
printf("\n");
}
}
產生以下輸出:
sizeof short int : 2
sizeof int : 4
==== sending short int to functionA() ====
bytes of 'arr[0]' : a 0
value of 'arr[0]' : 10
bytes of 'arr[1]' : 14 0
value of 'arr[1]' : 20
bytes of 'arr[2]' : 32 0
value of 'arr[2]' : 50
bytes of 'arr[3]' : 64 0
value of 'arr[3]' : 100
==== sending int to functionA() ====
bytes of 'arr[0]' : a 0
value of 'arr[0]' : 10
bytes of 'arr[1]' : 0 0
value of 'arr[1]' : 0
bytes of 'arr[2]' : 14 0
value of 'arr[2]' : 20
bytes of 'arr[3]' : 0 0
value of 'arr[3]' : 0
輸出的前兩行表明,在我的機器上, short int
占用2個字節的內存,而int
占用4個字節。
functionA()
期望一個short int
數組,當我發送一個short int[]
,我們看到了期望的輸出。 組成數組第一個元素的字節為0x0a 0x00
,十進制為“ 10”; 組成數組第二個元素的字節為0x14 0x00
,十進制為“ 20”; 等等。
但是,當我向int[]
發送functionA()
,每個元素發送4個字節,因此,當它遍歷數組時,不會正確看到元素。 它對第一個元素還可以,但這僅是因為它很小。 當它尋找第二個元素時,實際上是在尋找第一個元素的最后兩個字節,因此它看到0x00 0x00
或“ 0”; 當它尋找第三個元素時,它正在尋找第二個元素的前兩個字節,並且看到0x14 0x00
或“ 20”; 等等。
另一種顯示方式是shortdata
的字節是這樣的:
0a 00 14 00 32 00 64 00
和intdata
的字節是這樣的:
0a 00 00 00 14 00 00 00 32 00 00 00 64 00 00 00
因為functionA()
期望一個short int[]
,所以它intdata
這種方式對待intdata
-每個元素兩個字節-並視為其元素:
arr[0] : 0a 00
arr[1] : 00 00
arr[2] : 14 00
arr[3] : 00 00
這與您的代碼類似。 您的getAverage()
期望的是int[]
,因此當您將其發送為double[]
,它不會按照您的預期方式看到字節。
( int
和double
之間的沖突比short int
和int
之間的沖突更為激烈;這是因為除了大小不同(在大多數現代計算機上, int
是4個字節, double
是8個字節)之外,還存儲了浮點數作為指數和尾數-因此字節值的含義完全不同。)
希望以上說明對您有所幫助,並鼓勵您嘗試上面的代碼,並閱讀C內存的內部知識,因為它與分配和處理變量有關。 作為新的C程序員,您將深入了解可以繼續使用C進行編程的基礎知識。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.