簡體   English   中英

指向數組的指針數組

[英]Array of pointers to arrays

我是 C 編程的新手,這是我的問題:

我想將每個數組的第一個值存儲在一個新數組中,然后將每個數組的第二個值存儲在一個新數組中,依此類推。

我可以聲明指針數組,但我不知道如何使用它!

請我需要幫助。

int main()
{
    int t1[4]={0,1,2,3};
    int t2[4]={4,5,6,7};
    int t3[4]={8,9,10,11};
    int t4[4]={12,13,14,15};
    int *tab[4]={t1,t2,t3,t4};
    int i,j,k,l;
    for (i=0; i<4;i++)
    {
        printf("%d\t", *tab[i]);
    }

    return 0;
}

當我這樣做時,我只存儲每個數組的第一個值。

你的術語有點到處都是。 我認為回答您的問題的最簡單方法是逐行瀏覽您的代碼。

int main()
{
int t1[4]={0,1,2,3};      //Declares a 4 integer array "0,1,2,3"
int t2[4]={4,5,6,7};      //Declares a 4 integer array "4,5,6,7"
int t3[4]={8,9,10,11};    //Declares a 4 integer array "8,9,10,11"
int t4[4]={12,13,14,15};  //Declares a 4 integer array "12,13,14,15"
int *tab[4]={t1,t2,t3,t4};//Declares a 4 pointer of integers array "address of the first element of t1, address of the first element of t2, ..."
int i,j,k,l;              //Declares 4 integer variables: i,j,k,l
for (i=0; i<4;i++)
 {
  printf("%d\t", *tab[i]); //print out the integer that is pointed to by the i-th pointer in the tab array (i.e. t1[0], t2[0], t3[0], t4[0])
 }

 return 0;
 }

在循環之前,您所做的一切似乎都沒有問題。 您只顯示每個數組的第一個整數,因為您沒有遍歷它們。 要迭代它們,您的代碼應如下所示:

for (i=0; i<4;i++)
{
   for (j=0; j<4; j++)
   {
      printf("%d\t", *(tab[j] + i));
   }
}

上面的代碼使用了兩個循環計數器,一個( i )遍歷數組中的位置(數組中的第一個值,數組中的第二個值等); 另一個遍歷不同的數組( j )。 它通過檢索存儲在tab[j]指針並創建一個具有正確偏移量的新指針來實現這一點,以顯示第i列的值。 這被稱為指針運算(有關於指針運算的其他信息 在這里

大多數人發現語法*(tab[j] + i)很笨拙,但它更能描述實際發生的情況。 在 C 中,您可以將其重寫為tab[j][i] ,這更為常見。

您已按預期存儲數據,您只需要正確訪問它

for (i=0; i<4;i++)
{
  for (j = 0; j < 4; j++) {
    int* temp = tab[i];    
    printf("%d\t", temp[j]);      // or try the next line...
    printf("%d\t", *(temp + j));  // prints same value as above line
    printf("%d\t", tab[i][j];     // the same value printed again
  }
}   

以上所有打印出相同的值,只是使用指針算法訪問該值的不同方式。 tab每個元素都是一個int*每個元素的值是你其他定義的int[]數組在開始時的地址

編輯:響應 Jerome 的評論,您可以通過聲明 4 個數組來實現

int tab1[4]={*t1,*t2,*t3,*t4};
int tab2[4]={*(t1+1),*(t2+1),*(t3+1),*(t4+1)};
int tab3[4]={*(t1+2),*(t2+2),*(t3+2),*(t4+2)};
int tab4[4]={*(t1+3),*(t2+3),*(t3+3),*(t4+3)};

現在tab1包含每個數組的第一個元素, tab2包含第二個元素,依此類推。 然后你可以使用

 int *tttt[4]={tab1,tab2,tab3,tab4};
 for (i=0; i<4;i++) {
   for (j = 0; j < 4; j++) {
     printf("%d\t", tttt[i][j]);   
   }
 } 

打印你想要的東西。 如果你像一開始那樣聲明了另一個指針數組

  int* tab[4] = {t1,t2,t3,t4};

那么本質上在矩陣方面, tttttab的轉置

您存儲了所有內容,但只是不顯示。 嘗試

for (i=0; i<4;i++)
 {
  for (j=0; j<4; j++)
  printf("%d\t", *(tab[i]+j));
 }

int* (*a[5])[5][5][5]聲明了一個包含 5 個指針的數組,指向一個指向 int 的 3d 指針數組

int* (*(*a[5])[5])[5][5][5]聲明了一個由 5 個指針組成的數組,該數組由 5 個指針組成的數組指向一個 3d 指針數組。

#include <stdio.h>

int main()
{
    int t1[4]={0,1,2,3};
    int t2[4]={4,5,6,7};
    int t3[4]={8,9,10,11};
    int t4[4]={12,13,14,15};
    int (*tab[4])[4]={&t1,&t2,&t3,&t4};
    int i,j,k,l;
    for (i=0; i<4;i++)
    {
        printf("%d\t", (*tab[i])[1]);
    }

    return 0;
}

t2&t2之間存在差異。 盡管它們具有相同的值,但它們的類型不同。 int [4]int (*)[4] 編譯器會拋出警告 (clang) 或錯誤 (gcc)。

int a[4]在編譯器級別概念上是指向 4 數組的指針以及數組本身( &a == a )。

int (*a)[4]在編譯器級別在概念上是一個指向 4 數組指針的指針,也是指向數組本身的指針 ( a == *a ) 因為它指向一個數組類型,其中上述是真的。

在運行時,如果int *int (*a)[4]指向同一個地址,它們在物理上是相同的——它只是一個地址,同一個地址。 類型僅與編譯器如何解釋和生成具有該地址的算術運算以及它根據類型實際輸出的程序集有關。 您可以將地址強制轉換為您想要的任何類型,以實現所需的代碼輸出,以在其擁有的地址處操作數據。 然而,一個int a[4]類型在物理上是數組本身,但你使用它就好像在內存中有一個指向它的指針a ,它被賦予與數組本身相同的地址。 指向int a[4]的指針表示“指向地址范圍a的指針,編譯器將其視為具有 int 元素寬度的數組,其中編譯器將數組的開頭視為指向該數組的指針” ,並且對該類型的任何操作都將在解除引用鏈中保持一致,即如果類型是指向數組的指針,則必須在編譯器級別使用 (*a)[0] 訪問第一個元素,但如果您強制轉換相同的地址到int *那么你需要使用 a[0] 來訪問成員。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM