2012-06-24 38 views
5

Tôi có một ví dụ liên quan đến một con trỏ đến một mảng 2D. Ai đó có thể giúp tôi hiểu những gì đang xảy ra trong ví dụ này?Mảng và con trỏ 2D trong C - cách truy cập các phần tử?

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; 
} 
+0

Đây có phải là [thẻ: bài tập về nhà] không? – Alexander

+0

Yup! Tôi đã tham gia một khóa học CS giới thiệu và đây chỉ là một ví dụ được đưa ra từ các bài giảng của tôi. – shafools

Trả lời

13

data là một mảng 2 chiều, có 4 hàng và mỗi hàng có 3 phần tử (ví dụ: 4 X 3).

Hiện tại, Ptr = *data; có nghĩa là bạn đang lưu trữ địa chỉ bắt đầu của hàng thứ nhất vào biến con trỏ Ptr. Câu lệnh này tương đương với Ptr = *(data + 0). Ptr = *(data + 1) - điều này có nghĩa là chúng tôi đang chỉ định địa chỉ xuất phát của hàng thứ 2.

Sau đó, *Ptr hoặc *(Ptr + 0) sẽ cung cấp cho bạn giá trị của phần tử đầu tiên của hàng đang trỏ. Tương tự, *(Ptr + 1) sẽ cung cấp cho bạn giá trị của phần tử thứ hai của hàng.

Vòng lặp for trong chương trình của bạn được sử dụng để xác định hàng nào có giá trị lớn nhất của tổng các phần tử của nó (3 phần tử). Khi kiểm soát xuất phát từ vòng lặp for, Ptr sẽ trỏ đến hàng có tổng số tiền tối đa của các phần tử và sum0 sẽ có giá trị của tổng.

Hãy xem xét một mảng int a[5];, tôi hy vọng bạn biết rằng a[0]0[a] là giống nhau. Điều này là do a[0] có nghĩa là *(a+0)0[a] có nghĩa là *(0 + a). Logic này có thể được sử dụng trong mảng 2 chiều.

data[i][j] tương tự như *(*(data + i) + j). Chúng ta cũng có thể viết nó như là i[data][j].

Để biết thêm chi tiết, vui lòng tham khảo sách "tìm hiểu con trỏ trong c" của yashwant kanetkar.

1

data là một mảng gồm 3 phần tử của các số nguyên. Trong ngữ cảnh mong đợi một "con trỏ đến foo", bạn có thể sử dụng "mảng foo" và nó sẽ hoạt động giống như con trỏ đến phần tử đầu tiên, vì vậy *data là con trỏ đến phần tử đầu tiên của data, cụ thể là (để nói) {23,55,50}.

Vì vậy, câu trả lời cho câu hỏi đầu tiên trong nhận xét: Không, không đúng là Ptr = 23. (Nó không thể được; Ptr là một int * và 23 là một int.)

Bạn là chính xác rằng Ptr = *(data+i) làm Ptr điểm đến hàng thứ i của data. Chính xác hơn, data là một mảng gồm 3 mảng phần tử int, hoạt động giống như một con trỏ tới mảng gồm 3 phần tử int; thêm i để di chuyển qua i các mảng như vậy.

Cách thông thường để truy cập các cột khác của mảng là lập chỉ mục mảng thông thường. Nếu bạn tham khảo data[i][j], bạn sẽ nhận được cột j của hàng i. Nếu bạn muốn làm điều đó với số học con trỏ rõ ràng, thì lưu ý rằng (ví dụ) Ptr trong mã ví dụ là loại "con trỏ đến số nguyên", vì vậy Ptr+1 (ví dụ) là phần tử 1 của bất kỳ hàng nào Ptr trỏ đến. (Tuy nhiên, như một vấn đề về phong cách, bạn thường không nên làm số học con trỏ rõ ràng khi bạn không thực sự cần.)

0

Trong ví dụ của bạn, vòng lặp đi qua tất cả các hàng ma trận để tìm một số có tổng của tất cả các phần tử giữ giá trị tối đa.

Vào đầu một con trỏ đến dòng đầu tiên được gán:

Ptr = *data; 

Có nghĩa là sau đây là đúng:

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

ý rằng PTR là một con trỏ để nó giữ một địa chỉ bộ nhớ, do đó Ptr khác với (trừ khi địa chỉ bộ nhớ xảy ra là , rất khó xảy ra).

4

Ptr = *data; viết tắt là *(data+0)+0 là con trỏ cho phần tử cột đầu tiên của hàng đầu tiên. số 0 đầu tiên được thêm vào với dữ liệu là hàng số., được đánh dấu và đưa chúng ta đến hàng đầu tiên. * (data+0) vẫn là một địa chỉ và không phải là một giá trị mà nó trỏ tới (đối với mảng 2D). Vì vậy, Ptr bây giờ trỏ đến địa chỉ của cột đầu tiên trong hàng đầu tiên. Số thứ hai là cột số .. Vì vậy, địa chỉ bộ nhớ của hàng đầu tiên và cột đầu tiên được chọn. Sử dụng một lần nữa (*) một lần nữa sẽ chỉ cung cấp giá trị mà địa chỉ nắm giữ. như * (*(data+0)+0) hoặc **data.

Thông thường, nếu p là tên con trỏ, tôi chèo số và số cột j,

  1. (*(p+i)+j) sẽ cung cấp một địa chỉ bộ nhớ của một phần tử trong mảng 2D. tôi là hàng không. và j là col số.,
  2. *(*(p+i)+j) sẽ cung cấp giá trị của phần tử đó.
  3. *(p+i) sẽ truy cập hàng thứ i
  4. để truy cập cột, thêm số cột vào *(p+i). Bạn có thể phải khai báo con trỏ là (*p)[columns] thay vì chỉ *p. Làm như vậy, bạn đang khai báo con trỏ tới một mảng 2D.

Sử dụng số học con trỏ đang xử lý mảng 2d như mảng 1D. Khởi tạo con trỏ * Ptr thành phần tử đầu tiên (int *Ptr = *data) và sau đó thêm số không. (Ptr + n) để truy cập các cột. Việc thêm một số cao hơn số cột sẽ đơn giản tiếp tục đếm các phần tử từ cột đầu tiên của hàng tiếp theo, nếu điều đó tồn tại.

Các vấn đề liên quan