簡體   English   中英

C 中的二維數組和指針 - 如何訪問元素?

[英]2D array and pointer in C - how to access elements?

我有一個涉及指向二維數組的指針的示例。 有人可以幫助我理解這個例子中發生了什么嗎?

int main()
{

    int i = 0, j=0, sum0=0, sum1=0;
    int data[4][3] = { {23,55,50},{45,38,55},{70,43,45},{34,46,60}};
    int *Ptr;
    Ptr = *data;    //Why is the indirection operator used here? 
                    // Does Ptr = 23 by this assignment?

    for (i=0; i<4; i++) {
        sum1 = 0;
        for (j = 0; j < 3; j++) {
            sum1 += data[i][j];
        }
        if (sum1 > sum0) {
                 sum0 = sum1;
                 Ptr = *(data + i);     // Seems like this statement makes Ptr
        }                               // point one row below ... what syntax
    }                                   // can you use to access columns then?
                                       // Is it possible to use pointer arithmetic
    for (i=0; i<3; i++)                 // to access elements of data[i][j] that
        printf("%d\n", Ptr[i]);          // are not at j = 0?

  return 0;
}

data是一個二維數組,有 4 行,每行有 3 個元素(即 4 X 3)。

現在, Ptr = *data; 意味着您將第一行的起始地址存儲到指針變量Ptr 此語句等效於Ptr = *(data + 0) Ptr = *(data + 1) - 這意味着我們正在分配第二行的起始地址。

然后*Ptr*(Ptr + 0)將為您提供指向的行的第一個元素的值。 同樣, *(Ptr + 1)將為您提供該行第二個元素的值。

程序中的for循環用於確定哪一行具有其元素總和(3 個元素)的最大值。 一旦控件退出for循環, Ptr將指向其元素總和最大的行,而sum0將具有總和的值。

考慮一個數組int a[5]; , 我希望你知道a[0]0[a]是一樣的。 這是因為a[0]表示*(a+0)0[a]表示*(0 + a) 同樣的邏輯可以用在二維數組中。

data[i][j]類似於*(*(data + i) + j) 我們也可以把它寫成i[data][j]

有關更多詳細信息,請參閱 Yashavant Kanetkar 撰寫的《Understanding Pointers in C》一書。

Ptr = *data; *(data+0)+0的縮寫,它是第一行第一列元素的指針。 添加數據的第一個 0 是行號,它是間接的,將我們帶到第一行。 * (data+0)仍然是地址而不是它指向的值(對於二維數組)。 因此,Ptr 現在指向第一行第一列的地址。 第二個零是列號。因此,選擇第一行和第一列的內存地址。 再次使用間接尋址 (*) 現在只會給出地址所持有的值。 * (*(data+0)+0)**data

一般如果p是指針名,i行號j列號,

  1. (*(p+i)+j)將給出二維數組中元素的內存地址。 我是排號 j 是 col 號,
  2. *(*(p+i)+j)將給出該元素的值。
  3. *(p+i)將訪問第 i 行
  4. 要訪問列,請將列號添加到*(p+i) 您可能必須將指針聲明為(*p)[columns]而不僅僅是*p 這樣做,就是在聲明一個指向二維數組的指針。

使用指針算法將二維數組視為一維數組。 將指針 *Ptr 初始化為第一個元素 ( int *Ptr = *data ),然后添加一個編號。 ( Ptr + n ) 訪問列。 添加一個高於列號的數字將簡單地繼續計算下一行第一列的元素(如果存在)。

data是 3 元素整數數組的數組。 在期望“指向 foo 的指針”的上下文中,您可以使用“foo 數組”,它的行為類似於指向其第一個元素的指針,因此*data是指向data的第一個元素的指針,即(可以這么說) {23,55,50}

因此,評論中第一個問題的答案:不, Ptr = 23是不正確的。 (不可能; Ptr是一個int *而 23 是一個int 。)

您是正確的, Ptr = *(data+i)使Ptr指向第idata 更准確地說, data是 int 的 3 元素數組的數組,其行為類似於指向 int 的 3 元素數組的指針; i添加到它會移動過去i這樣的數組。

訪問數組其他列的常用方法是普通數組索引。 如果您參考data[i][j] ,您將獲得第i行的第j列。 如果您想使用顯式指針算法來實現,請注意示例代碼中的(例如) Ptr是“指向整數的指針”類型,因此Ptr+1 (例如)是Ptr指向的任何行的元素 1。 (但是,作為一種風格問題,當您實際上不需要時,您通常不應該進行顯式指針運算。)

在您的示例中,循環遍歷所有矩陣行以找到其所有元素之和保持最大值的行。

在開始時,分配了指向第一行的指針:

Ptr = *data;

這意味着以下內容為真:

(Ptr[0] == 23 && Ptr[1] == 55 && Ptr[2] == 50)

請注意, Ptr是一個指針,因此它包含一個內存地址,因此Ptr不同於23 (除非內存地址恰好是23 ,這不太可能發生)。

C 允許多維數組,將它們作為連續位置布置在內存中,並在幕后執行更多地址運算。 考慮一個二維數組。

int arr[ 3 ][ 3 ] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

編譯器將二維數組視為數組的數組。 其中數組名稱是指向數組中第一個元素的指針。 所以,arr指向第一個3元數組,其實就是二維數組的第一行(即第0行)。 同樣,(arr + 1) 指向第二個 3 元素數組(即第 1 行),依此類推。 該指針的值(arr + 1) 指的是整行。 由於第 1 行是一個一維數組,(arr + 1) 實際上是指向第 1 行第一個元素的指針。現在將 2 添加到該指針。 因此,( (arr + 1) + 2) 是指向第 1 行中元素 2(即第三個元素)的指針。該指針的值( (arr + 1) + 2) 指的是列中的元素第 1 行的 2 個。

暫無
暫無

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

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