2014-09-04 25 views
1

這裏是在C程序和它的輸出我以各種可能的方式嘗試這段代碼,但我找不到爲什麼?

#include <stdio.h> 
#include <conio.h> 

void main() 
{ 
    int i, t[4], s[4]; 

    for(i=0;i<=3;i++) 
    { 
     printf("\n%d",&s[i]); 
     printf(" %d",&t[i]); 
    } 

    for(i=0;i<=3;i++) 
    { 
     printf("\n%d %d",&s[i],&t[i]); 
    } 
} 

輸出:

8600 8608 
8602 8610 
8604 8612 
8606 8614 

8600 8641 
8602 8641 
8604 8641 
8606 8641 

我想知道到底發生了什麼在第二個for循環語句使從第一個for循環不同。

+4

請勿使用'%d'打印指針。使用'%p'。 – 2014-09-04 08:20:57

+0

但在第一個循環中,我得到了我的預期,但在第二個循環中,我得到了其他東西(地址)爲什麼? – vinay 2014-09-04 08:25:39

+0

你打印隨機存儲器的值? – 2014-09-04 08:25:42

回答

4

你的程序中唯一明顯的問題是你傳遞的指針參數對應於printf%d格式。這是未定義的行爲。它可能適用於某些編譯平臺,但不應該指望它。

最有可能的解釋是,用於將指針參數傳遞給可變參數函數(如printf)的ABI在您的平臺上與傳遞int參數的ABI不同。對於我們所知道的,在您的平臺上,指針的寬度與int不一樣。

使用%p格式打印指針。或者更好的是,使用printf("%p", (void*)…);,這是更便攜的,以防萬一不是所有指針類型具有相同的表示。

+0

我想說這也是一個明顯的問題,它打印未初始化的變量,並對結果有期望。 – unwind 2014-09-04 09:11:36

+2

OP的代碼打印(未初始化)變量的地址。不管這是否是UB是另一個問題。 @unwind – alk 2014-09-04 09:14:34

+1

我看不到任何使用未初始化數組元素的地址應該成爲問題的原因。首先,你經常需要使用這個地址來初始化數組。 – 2014-09-04 09:22:47

2

問題是您使用錯誤的格式代碼來打印指針。正如@PascalCuoq所說,您應該使用%p,而不是%d

原因是指針和整數在系統上顯然不是相同的大小。

當您將兩個指針傳遞給不同的printf時,調用%d將打印指針值的第一部分。

當您將兩個指針傳遞給同一個printf調用時,獲取長度錯誤將意味着它將打印兩個不同於任一指針的值。

1

printf報表打印一個整數,把你把一個指針(&t[i]意味着牛逼陣列的個元素的地址)。

一個整數和一個指針不一定是相同的字節數,printf的大多數實現從棧中爲每個%字段獲取固定數量的字節。當printf從堆棧獲取其字段數據時,機器的'端序'將決定地址的最低位還是最高位被用作整數。它看起來像你在一個16位機器上運行,具有24位地址和LSB排序 - 我猜可能是某種微控制器。

你的陣列是在存儲器地址(從輸出轉換爲十六進制: 小號:0xC12198 :0xC121A0 (24個addreses,我認爲)

第一環路處理每個數組單獨分佈在不同的printf語句中,因此您可以看到每個數組的最低有效位在每次迭代時遞增。

第二個循環嘗試在一個`printf中處理兩個數組。所以你得到的值表示其中一個地址的遞增部分,另外第二個是地址的最重要部分,它不是遞增的,第二個數組的地址根本就不輸出。

相關問題