簡體   English   中英

指針算術和c中的二維數組?

[英]Pointer arithmetic and 2-D array in c?

我是C的新手並且堅持“如何將多維數組傳遞給函數”。 我知道你必須傳遞列大小,這樣如果你想從a[0][0]a[1][0]它可以計算一維數組的大小,並可以跳過它。

我寫了一個小程序:

#include<stdio.h>
void foo(char[][2]);
int main()
{
     char arr[2][2] = {'a','b','c','d'};

     foo(arr);
     return 0;
}

void foo(char temp[][2])
{
      temp++;
      printf("%c",*temp);
}

我期望這段代碼會打印字母c ,因為temp最初指向'a' ,一旦我們遞增它,它將跳過第一個1-d數組並轉到第二個1-d數組的第一個元素'c' 但是我認為這種方式不起作用。

請解釋編譯器如何計算這些地址。

指針算術很好。 你忘了取消引用*temp ,它有char[2]類型。

將其更改為**temp ,您將獲得輸出c

對於函數參數char temp[][2]temp衰減為指針。 但僅限於第一(外)維度。 所以它實際上是一個指向char數組[2]的指針

正如您已經假設的那樣,遞增指針將使其前進到下一個外部索引。

因此,您必須使用(*temp)[0]**temp來獲取第一個元素。 **temp有效,因為*temp是一個數組本身,所以它衰減到指向內部數組的第一個元素的指針。 第二個(左) *然后取消引用這個指針: c

請注意,雖然它使用與char **temp相同的語法,但它們根本不同。 指針不是一個數組,在這里,遞增temp只會前進一個指針的大小,這不是你想要的。

請注意,初始化程序最好是根據2維性質:

{ { 'a', 'b' } , { 'c', 'd' } }

這可以確保您獲得內部數組的正確值,這是一種很好的做法。 省略非嵌套表單中的值將導致內部數組的序列錯誤。 當至少啟用了推薦警告( -Wall ,gcc會警告缺少大括號。

除了當它是的操作數sizeof或一元&操作員,或者是一個字符串被用來初始化一個聲明另一個數組,類型“的N元件陣列的表達 T將被轉換(“衰變”)”,以“指向T指針”類型的表達式,表達式的值將是數組中第一個元素的地址。

main ,函數調用foo(arr)中的表達式arr的類型是“2元素數組char的2元素數組”; 因為它不是sizeof或一元&運算符的操作數,所以它“衰變”為類型為“指向2元素char數組的指針”或char (*)[2]的表達式。

因此,參數tempchar (*)[2] ,它指向arr的第一個元素。 參數聲明char temp[][2]等同於char (*temp)[2] 表達式*temp等同於temp[0] ,並且都具有類型“ char 2元素數組”( char [2] )。 表達式temp + 1為您提供下一個2元素char數組的地址,因此*(temp + 1)等效於temp[1]

這是一個總結所有這些的表格:

    Expression        Type            Decays To         Value
    ----------        ----            ---------         -----
           arr        char [2][2]     char (*)[2]       &arr[0][0]
          *arr        char [2]        char *            arr[0]
          &arr        char (*)[2][2]  n/a               &arr[0][0]
        arr[i]        char [2]        char *            &arr[i][0]
       *arr[i]        char            n/a               arr[i][0]
       &arr[i]        char (*)[2]     n/a               &arr[i][0]
     arr[i][j]        char            n/a               arr[i][j]

          temp        char (*)[2]     n/a               &arr[0][0]
         *temp        char [2]        char *            arr[0]
         &temp        char (**)[2]    n/a               addr of temp variable
       temp[i]        char [2]        char *            &arr[i][0]
      *temp[i]        char            n/a               arr[i][0]
      &temp[i]        char (*)[2]     n/a               &arr[i][0]
    temp[i][j]        char            n/a               arr[i][j]

       arr + 1        char [2][2]     char (*)[2]       &arr[1][0]
    *(arr + 1)        char [2]        char *            arr[1]
      temp + 1        char (*)[2]     n/a               &arr[1][0]
   *(temp + 1)        char [2]        char *            arr[1]

     arr[0][0]        char            n/a               'a'
     arr[0][1]        char            n/a               'b'
     arr[1][0]        char            n/a               'c'
     arr[1][1]        char            n/a               'd'

        **temp        char            n/a               'a'
      *temp[0]        char            n/a               'a'
    temp[0][0]        char            n/a               'a'

  **(temp + 1)        char            n/a               'c'
      *temp[1]        char            n/a               'c'
    temp[1][0]        char            n/a               'c'

所以,在你的print語句中,你會寫

printf("%c", **temp); // temp == &arr[1][0] after temp++

要么

printf("%c", *temp[0]); // temp[0] == arr[1] after temp++

要么

printf("%c", temp[0][0]); // temp[0][0] == arr[1][0] after temp++

表達式arr&arr*arrarr[0]&arr[0]*arr[0]&arr[0][0]都產生相同的 - arr的第一個元素的地址(記住,數組的地址和數組的第一個元素的地址是相同的)。 他們的類型不同。

請注意, &temp為我們提供了 &arr 不同的值。 由於temp被聲明為指針而不是數組,因此&temp為我們提供了指針變量的地址。

圖片可能會有所幫助:

      +---+    
 arr: |'a'|  arr[0][0] <------------------+ before temp++
      +---+                               |
      |'b'|  arr[0][1]                    |
      +---+                               |
      |'c'|  arr[1][0] <--+ after temp++  |   
      +---+               |               |
      |'d'|  arr[1][1]    |               |
      +---+               |               |
       ...                |               |
      +---+               |               |
temp: |   |---------------+---------------+
      +---+

暫無
暫無

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

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