2009-03-03 168 views
3

這個例子正常工作:初始化指針數組的指針

static char *daytab[] = { 
    "hello", 
    "world" 
}; 

這不:

static char *daytab[] = { 
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 
}; 

我看到它的方式是,第一個示例創建一個數組,填充指針指向兩個字符串文字(它們本身就是數組)。第二個示例IMO應該是相同的 - 創建一個數組,並用指向兩個char數組的指針填充它。

有人可以向我解釋爲什麼第二個例子是錯誤的?

P.S.你可以這樣寫(沒有測試過):

static char a[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 
static char b[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 
static char *daytab[] = { 
    a, 
    b 
}; 

但是,看起來像太多的工作:)。

+0

4答案,但我只看到一個?怎麼來的? – Ree 2009-03-03 23:02:52

+0

已被作者刪除。 – 2009-03-03 23:23:21

+0

我那天發生過。 SO似乎需要一段時間才能完全解釋已刪除的答案。它將盡快達到正確的數量。 – RBerteig 2009-03-03 23:47:25

回答

3

此:

{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 

只是一個數組初始化。它本身並不創建數組。第一個例子,當你將一個字符串文字分配給一個指針時,DID在靜態存儲器中創建這些字符串(隱藏給你),然後將指針分配給它們。

所以基本上,沒有辦法用數組初始值設定項初始化你的char *。您需要創建一個實際的數組,並將這些數字分配給它。你將不得不這樣做:

char a[][] = { {32, 30, 0}, {34, 32, 33, 0} }; // illegal 

但這是非法的。

您需要單獨構建數組並將它們分配到像上一個示例一樣的數組中。

3

嘗試:

static char daytab[][13] = { 
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 
}; 

這些都不是的char *的。它們也不是字符。你可能想:

static int daytab[][13] ... 
+0

那麼,這將使大小爲13的主數組的每個元素。如果我想要指向不同大小的數組的指針呢?至於char - char可以用於小整數值,所以這裏不是問題。 – Ree 2009-03-03 22:44:09

0

第二個示例的語法是多維數組文本的語法。多維數組不是數組的指針數組。

如果某件事的語法也是不同事物的語法,這取決於它聲明的類型,這將是令人驚訝的。

在第一個示例中,因爲字符串文字被計算爲指針而不是數組值,所以該值被評估爲指針數組。因爲數組文本被評估爲一個數組值而不是一個指針,所以第二個例子是一個多維數組 - 一個數組的元素是數組值,而不是一個數組的元素是指向數組值的數組。

以下代碼演示了多維數組的組合,指向數組的指針,指針數組和指針指針。在這三個中,只有指針數組和指針指針彼此兼容:

void multi_array (int x[][4], size_t len) // multidimensional array 
{ 
    for (size_t i = 0; i < len; ++i) 
     for (size_t j = 0; j < 4; ++j) 
      putchar('a' + x[i][j]); 
    putchar('\n'); 
} 

void ptr_array (int (*x)[4], size_t len) // pointer to an array 
{ ... as multi_array } 

void array_ptr (int *x[], size_t len) // array of pointers 
{ ... as multi_array } 

void ptr_ptr (int **x, size_t len) // pointer to pointer 
{ ... as multi_array } 

int main() { 
    int a[][4] = { { 1,2,3,4 } }; 
    int b[] = { 1,2,3,4 }; 
    int* c[] = { b }; 

    multi_array(a, 1); 
    multi_array((int[][4]) { { 1,2,3,4} }, 1); // literal syntax as value 
    ptr_array(&b, 1); 
    array_ptr(c, 1); 
    ptr_ptr(c, 1); // only last two are the same 

    return 0; 
} 
0

請注意,您的第一個示例也不起作用。它需要:

static const char *daytab[] = { 
    "hello", 
    "world" 
}; 

注意常量

編輯:由「不起作用」,我的意思是不好的做法,容易出錯,這可以說是更糟。

3

嗯,這個線程已經有點老了,但是我正在處理同樣的問題,找到了一種方法來初始化數組的指針到數組,像這樣:

#include <iostream> 
using namespace std; 

int *a[] = { 
    (int[]) { 0 } , 
    (int[]) { 1 , 2 } , 
    (int[]) { 3 , 4 , 5 } , 
    (int[]) { 6 , 7 , 8 , 9 } 
}; 

main() 
{ 
    cout 
    << a[0][0] << endl 
    << a[1][0] << " " << a[1][1] << endl 
    << a[2][0] << " " << a[2][1] << " " << a[2][2] << endl 
    << a[3][0] << " " << a[3][1] << " " << a[3][2] << " " << a[3][3] << endl; 
} 

而且我得到的輸出與GNU克++

0 
1 2 
3 4 5 
6 7 8 9 

和英特爾ICPC編譯

0 
1 1 
40896 32767 -961756724 
0 32767 4198878 0 

因此,語法的成書eems原則上是正確的,只是intel編譯器不能正確地支持它,可能是由於缺乏這種風格的共同使用。


---編輯---

這裏也是一個C版本(如需要):

#include <stdio.h> 

int *a[] = { 
    (int[]) { 0 } , 
    (int[]) { 1 , 2 } , 
    (int[]) { 3 , 4 , 5 } , 
    (int[]) { 6 , 7 , 8 , 9 } 
}; 

int main() 
{ 
    printf("%d\n" , a[0][0]); 
    printf("%d %d\n" , a[1][0] , a[1][1]); 
    printf("%d %d %d\n" , a[2][0] , a[2][1] , a[2][2]); 
    printf("%d %d %d %d\n" , a[3][0] , a[3][1] , a[3][2] , a[3][3]); 
} 

我用gcc和鏗鏘測試,它打印出正確的結果。 Btw。 intel編譯器的錯誤輸出是一個編譯器錯誤。

1
static char **daytab; 
daytab=(char**)malloc(2*sizeof(char*)); 
daytab[0]=(char*)(char[]){0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 
daytab[1]=(char*)(char[]){0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};