2014-10-05 124 views
3

以下代碼示例演示了指針和數組之間的相似性。在第二種方法中,作者將cur_name聲明爲指向指針的指針。我的問題是,爲什麼這是必要的?爲什麼他會聲明一個新的指針,而不是僅僅使用原始指針名稱?我應該注意到,代碼編譯並運行良好,當我擺脫cur_name和使用名稱,所以這是一個風格而不是功能的問題?任何解釋將不勝感激。爲什麼這個C代碼示例使用指針指針?

#include <stdio.h> 

int main(int argc, char *argv[]) 
{ 
    // create two arrays we care about 
    int ages[] = {23, 43, 12, 89, 2}; 
    char *names[] = {"Alan", "Frank", "Mary", "John", "Lisa"}; 

    // safely get the size of ages 
    int count = sizeof(ages)/sizeof(int); 
    int i = 0; 

    // first way using indexing 
    for(i = 0; i < count; i++) { 
     printf("%s has %d years alive.\n", 
       names[i], ages[i]); 
    } 

    printf("---\n"); 

    // setup the pointers to the start of the arrays 
    int *cur_age = ages; 
    char **cur_name = names; 

    // second way using pointers 
    for(i = 0; i < count; i++) { 
     printf("%s is %d years old.\n", 
       *(cur_name+i), *(cur_age+i)); 
    } 

    printf("---\n"); 

    // third way, pointers are just arrays 
    for(i = 0; i < count; i++) { 
     printf("%s is %d years old again.\n", 
       cur_name[i], cur_age[i]); 
    } 

    printf("---\n"); 

    // fourth way with pointers in a stupid complex way 
    for(cur_name = names, cur_age = ages; 
      (cur_age - ages) < count; 
      cur_name++, cur_age++) 
    { 
     printf("%s lived %d years so far.\n", 
       *cur_name, *cur_age); 
    } 

    return 0; 
} 
+0

的代碼包含註釋' //第三種方式,指針只是數組';這是不準確的 - **指針是_not_數組**。但是,這兩者密切相關。考慮'sizeof(cur_name)'和'sizeof(names)'的值;這些值是非常不同的,所以清楚的指針不是數組。請注意'sizeof(argv)'與sizeof(cur_names)'相同;這是因爲另一種編寫像char * argv []'這樣的數組參數的有效方式是'char ** argv'。因此,作爲參數傳遞的數組是指針(這是混淆來自何處),但本地或全局數組不是「只是指針」。 – 2014-10-05 15:39:23

回答

4

該代碼使用指向指針的指針來表示指向C字符串數組的指針。即,cur_name是一個指向名爲names的C字符串數組的指針。由於C中的字符串本身是由指向char的指針表示的,因此指向此類指針數組的指針變爲指向指針的指針。

爲什麼他會聲明一個新的指針而不是僅僅使用原始指針names

因爲names不是指針,它是一個指針數組(參見聲明之後方括號?這就是使得names的陣列。在前面的單星號是關係到數組元素的類型,這是該程序中的char*)。

形成陣列添加了一個間接的層次:點進的,你需要int*int秒的陣列,但點進的int*數組,你需要一個int**指針。

+0

謝謝你的回覆。不過,要澄清一點。如果'names'不是一個指針,那麼爲什麼在第三個方法中'*(names + i)'返回與*(cur_name + i)'相同的值? – intelli78 2014-10-05 22:19:28

+0

@ intelli78這是一個很好的問題!其原因是指針算法的所有規則也適用於數組。這些表達式中數組的名稱以與處理數組初始元素的指針相同的方式處理。換句話說,如果你使用'char ** names2 = names',那麼它的指針算術表達式就會和'names'上的表達式一樣。 – dasblinkenlight 2014-10-05 22:26:04

+0

這很有幫助,謝謝。 – intelli78 2014-10-05 22:32:50

0

作者確實在第四種方法中增加了它們,所以他需要臨時對象,但是您在第二種方法中沒有必要使用它是正確的。也許他正在使用這個任務來展示他們的等價性?

我認爲如果每個方法都在自己的函數中實現,示例會更清晰。

2

如果如果要定義一個指針到它的第一元件具有類型T的數組如下

T a[N]; 

那麼你必須寫

T *p = a; 

現在代替T代表類型定義爲

char *names[] = {"Alan", "Frank", "Mary", "John", "Lisa"}; 

陣列names的元素,你會得到

typedef char * T; 
T names[] = {"Alan", "Frank", "Mary", "John", "Lisa"}; 

所以指針數組的第一個元素看起來像

T *cur_name = names; 

如果你現在會做反向替代你會得到

char * *cur_name = names; 
^^^^^^ 
    T