[英]How to access the elements of a 2D array represented by a Double pointer as a 1D array in 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列號,
(*(p+i)+j)
將給出二維數組中元素的內存地址。 我是排號 j 是 col 號,*(*(p+i)+j)
將給出該元素的值。*(p+i)
將訪問第 i 行*(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
指向第i
行data
。 更准確地說, 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.