2012-04-11 430 views
2

有人能給我一個簡短的解釋,說明在下面的函數中發生了什麼不同嗎?指向指針的指針和指向數組的指針

void f1(data_t **d) 
    { 
     for (int i=0; i<MAXSIZE; i++) 
     { 
      (*d)[i].ival = i; 
     } 
    } 

    void f2(data_t **d) 
    { 
     for (int i=0; i<MAXSIZE; i++) 
     { 
      (*d)->ival = i; 
      (*d)++ 
     } 
    } 

    void f3(data_t *d) 
    { 
     for (int i = 0; i<MAXSIZE; i++) 
     { 
      d->ival = i; 
      d++; 
     } 
    } 

    void f4(data_t *d) 
    { 
     for (int i = 0; i<MAXSIZE; i++) 
     { 
      d[i].ival = i; 
     } 
    } 

特別是在f2中發生了什麼不同。但每件事情都有明顯的不同。

f1和f3做同樣的事情(但不同)。 F2徹底失敗了,和F4是越野車(工作在這個例子中,但是當我試圖把其他值轉換爲其他指針(字符*)的字符串結束奇怪。)

+0

你如何解釋你認爲正在發生的事情...... – 2012-04-11 06:34:29

+3

這是功課嗎? – loganfsmyth 2012-04-11 06:37:05

+1

是這種家庭嗎? – giorashc 2012-04-11 06:37:50

回答

2
void f1(data_t **d) 
{ 
    for (int i=0; i<MAXSIZE; i++) 
    { 
     (*d)[i].ival = i; 
    } 
} 

的d似乎是一個指針到data_t的數組(或者是data_t數組的1個元素的數組)。解除引用來恢復data_t的數組,然後修改此數組的第i個元素。

void f2(data_t **d) 
{ 
    for (int i=0; i<MAXSIZE; i++) 
    { 
     (*d)->ival = i; 
     (*d)++ 
    } 
} 

這是有點棘手,確實做了一些不同於第一種情況。有一個指向data_t數組的指針。這裏我們有一個指向data_t的指針數組。取消指向第一個元素的指針以檢索指向數據的指針。然後 - >用於訪問數據並修改值(x-> y =(* x).y)。最後,指針移動到主數組的下一個元素。

void f3(data_t *d) 
{ 
    for (int i = 0; i<MAXSIZE; i++) 
    { 
     d->ival = i; 
     d++; 
    } 
} 

下面我們就簡單的情況下,d只是data_t一個數組的指針被訪問。在循環內部,一個元素通過 - >來訪問,然後d遞增以指向數組的下一個元素。

void f4(data_t *d) 
{ 
    for (int i = 0; i<MAXSIZE; i++) 
    { 
     d[i].ival = i; 
    } 
} 

與f3類似,元素由[]運算符修改。

請注意以下事實:

int[] =(def) int * 

如果一個的類型是int *和i爲任何整數類型,那麼:

*(a + i) =(def) a[i] 

此外,如果一個點的一個第一元件陣列,然後

*a =(def) a[0] 

,然後,一 「一++」 之後

*a =(def) a[1] 

...等等。

+0

這對我的理解是一個巨大的幫助!!!上面的代碼中做了什麼(def)? – Sun 2012-04-11 07:15:58

+0

=(def)等於「意味着同樣的定義「,它不是一個真正的源代碼 – Spook 2012-04-11 07:21:58

1

讓我們這些一次一個:

// f1 
(*d)[i].ival = i; 

首先,(*d)被解除引用d,這似乎是一個指針,指向data_t變量的陣列。這允許訪問實際的數組,因此[i]正在訪問數組的i個元素並將i賦值給它。

// f2 
(*d)->ival = i; 
(*d)++; 

(*d)被提領d就像在第一個。但是,在繼續之前,有一點關於陣列的信息是您應該瞭解的。

int j[2] = { 42, 50 }; 
int j0 = *j; // j0 is now 42 
j += 1; 
int j1 = *j; // j1 is now 50 

陣列被實現爲在存儲器「插槽」順序地面向各個變量,和陣列實際上只是一個指向第一個時隙。因此,*j是提領j,它目前指向第一個元素,導致42。做j += 1提前指針一個「插槽」,這樣*j現在將導致50

現在回到f2(*d)->ival(**d).ival完全相同。這很像我上面給出的簡單例子。下一行(*d)++正在將指針前進到下一個「插槽」。考慮在內存中什麼是「新銳」這個簡單的示意圖:

 +------+------+ 
     |*(j+0)|*(j+1)| 
j --->|------|------| 
     | 42 | 50 | 
     +------+------+ 

j指向第一個「插槽」,在第一行中所示的間接引用,在第二個值。

f3非常像f2,除了它期望數組作爲參數傳遞,而不是指向它的指針。因此,d只需要與->運營商一起解除引用(再次,完全像(*d).ival)。

f4非常像f1,只是它期望數組作爲參數傳遞,而不是指向它的指針。因此,d[i]正在直接訪問數組的第i個元素i

+0

這也是一個巨大的幫助!謝謝! – Sun 2012-04-11 07:19:34

1
void f1(data_t **d) 
    { 
     for (int i=0; i<MAXSIZE; i++) 
     { 
      (*d)[i].ival = i; 
     } 
    } 
  1. 你得到一個指針陣列**ddata_t,其中元件是一個結構,具有字段ival
  2. 訪問陣列*d
  3. 迭代所有數組元素,元件通過元件,改變索引i。並且更新ival的每個數組元素爲i

注意:不要t change the pointer * D',指向數組開始

void f2(data_t **d) 
{ 
    for (int i=0; i<MAXSIZE; i++) 
    { 
     (*d)->ival = i; 
     (*d)++ 
    } 
} 
  1. 你得到一個指向data_t陣列**d,且該元素的結構,具有場ival
  2. 訪問陣列*d ,這也是一個指針陣列(第一元件)
  3. 更新由所述(上文)元件的ivali,使用指針符號(*d)->ival = i;
  4. 提升指向下一個數組元素的指針(*d)++並返回2.從現在起* d是 指向「篩選」數組的開始。

    空隙F3(data_t * d)

    { 
        for (int i = 0; i<MAXSIZE; i++) 
        { 
         d->ival = i; 
         d++; 
        } 
    } 
    

    1。你得到data_t的數組*d,該元素是一個結構,具有字段ival

    2.也可以認爲你得到一個指向數組的第一個元素的指針。 訪問的訪問和更新ivali,由指針:d->ival = i;

    3.Promote指針到下一個數組元素d++

    空隙F4(data_t * d)

    { 
        for (int i = 0; i<MAXSIZE; i++) 
        { 
         d[i].ival = i; 
         d++; 
        } 
    } 
    

f3。但您使用參考符號(按值)推薦索引並更新ival

+0

這是非常有用的信息,非常明確的解釋。 – Sun 2012-04-11 07:32:39