2013-04-10 77 views
3

我對指針的瞭解不多。指針程序的輸出

我遇到以下程序。輸出看起來很正常,但實際發生的事情我無法弄清楚。

#include<stdio.h> 
#include<conio.h> 
void main() 
{ 
    int k; 
    int a[] = {1,2,3}; int *b[3] ; int **c[3]; 
    int ***d[3]; int ****e[3]; int*****f[3]; 
    for (k = 0 ; k <3; k++) 
    { 
     b[k] = a + k; c[k] = b + k ; d[k] = c + k; 
     e[k] = d + k ; f[k] = e + k; 

    } 
    for (k = 0 ; k <3; k++) 
    { 
     printf("%3d", *b[k]); printf("%3d", **c[k]); 
     printf("%3d", ***d[k]); printf("%3d", ****e[k]); 
     printf("%3d\n", *****f[k]); 
    } 
} 
+0

是這個功課還是有人試圖惹你?把那個人打了一遍,然後回答他:-) – 2013-04-10 12:35:27

+0

我發現這對工程考試的老問題 – 2013-04-10 12:39:55

+0

是的,這解釋:-) – 2013-04-10 12:40:45

回答

2

第一個for循環只是基本的指針算術。 a[]持有int s,之後的每個數組都包含一個指針。
b[]是一個指向int
c[]是一個指針,指針int

所以它的東西,像這樣的記憶:

Memory Address:  0x00441234 <---+ 0x00441238 <----+  0x0044123C <---+ 
        **********  | **********  |  **********  | 
var name:   * a (+0) *  | * a (+1) *  |  * a (+2) *  | 
        **********  | **********  |  **********  | 
value:    * 1 *  | * 2 *  |  * 3 *  | 
        **********  | **********  |  **********  | 
            |     |     | 
            |     |     | 
        +-> 0x00442345 | +->0x00442349  | +->0x0044234D  | 
        | ************ | | ************ | | ************ | 
        | * b (+0) * | | * b (+1) * | | * b (+2) * | 
        | ************ | | ************ | | ************ | 
        | *0x00441234* -+ | *0x00441238* --+ | *0x0044123C* --+ 
        | ************ | ************  | ************  
        |     |     | 
        |     |     | 
        | 0x00443345  | 0x00443349  | 0x0044334D  
        | ************ | ************  | ************  
        | * c (+0) * | * c (+1) *  | * c (+2) *  
        | ************ | ************  | ************  
        +-- *0x00442345* +-*0x00442349*  +-*0x0044234D* 
         ************  ************  ************  

而且給每個元素的D點每一個元素C等等。最終的結果是你將每個數組中的每個元素(通過一些指針鏈)重新設置爲a的元素。然後在第二個for循環中,您將一遍又一遍地打印a[]的元素。

+0

你是5-6手嗎?和5-6鍵盤?:-) – 2013-04-10 12:41:31

+0

@Koushik他可能有[this](http://www.asciiflow.com/#Draw)。 ;) – 2013-04-10 12:44:43

+0

@SuvP哦哇,這是一個不錯的鏈接。謝謝。 – 2013-04-10 12:46:01

0

這裏是發生了什麼:

您定義的數據類型的變量kint

你定義一個數組,a有值,1, 2, 3

你定義一個指針數組,b

您定義了一個數組指向指針的指針,c

.................................和高達f

類似的

您從0迭代到2,並且分配值bcd,....高達f

您再次從0迭代到2和印刷:

由每個元件在b指出的值,c,..... upto f

EDIT:發生了什麼b [k] = a + k,你是否在你的記憶中前進了k個塊,其地址被分配給了b [k],所以b [k]指向你的塊內存,(可以是任何值)

+0

@Rohit:看到編輯 – cipher 2013-04-10 12:32:03

1
 int k; 
    int a[] = {1,2,3}; //array of 3 ints 
    int *b[3] ; //array of 3 integer pointers 
    int **c[3]; //array of 3 integer double pointers 
    int ***d[3]; //array of 3 pointers to integer double pointers 
    int ****e[3]; //array of 3 pointers to pointers to integer double pointers 
    int*****f[3]; //array of 3 pointers to pointers to pointers to integer double pointers 
    for (k = 0 ; k <3; k++) 
    { 
     b[k] = a + k; 
      //a gives base address to array a 
      //Add k to it and store it in b[k]. Note, this isn't normal arithmetic its 
      //pointer aritmetic 
     c[k] = b + k ; 
     d[k] = c + k; 
     e[k] = d + k ; 
     f[k] = e + k; 
    } 
    for (k = 0 ; k <3; k++) 
    { 
     printf("%3d", *b[k]); //dereference single level pointer 
     printf("%3d", **c[k]); //dereference second level pointer 
     printf("%3d", ***d[k]); printf("%3d", ****e[k]); 
     printf("%3d\n", *****f[k]); 
    } 

你可以有任意數量的指針級別。即指向(指向...的指針)等等[達到由標準定義的限制]

有關有趣的閱讀,請參閱this

0

首先嚐試瞭解b[k] = a + k在做什麼。休息是一樣的。

a[]是具有3個元素1, 2, and 3a陣列本身指的是陣列的0th元件,即a是數組的第一元素的地址。

現在a + k,在指針算術中,表示名爲a的數組的kth元素。

因此,考慮循環的第一遍,且k = 0

你的第一個語句變成b[0] = a + 0。通知a + 0是一個地址,它被一個元素b包含。因此,b應該是int *的類型,並且在您的代碼中它聲明爲int *b[3]

而對於c[0] = b + 0,您存儲的是address of address of int,所以c被聲明爲雙指針int **c[3]

現在,這些事情發生在您使用的每個數組上,只是具有額外級別的指針。這意味着,您持有前一個數組元素的地址。