2011-12-29 36 views
7

Tôi có đoạn mã sau:Hai mảng chiều và con trỏ

char board[3][3] = { 
        {'1','2','3'}, 
        {'4','5','6'}, 
        {'7','8','9'} 
        }; 

printf("address of board : %p\n", &board); 
printf("address of board[0] : %p\n", &board[0]); 

Cả printf() báo cáo tất cả in giá trị như nhau: 0x0013ff67

  1. Theo hiểu biết của tôi, hội đồng quản trị (ví dụ) tên mảng đại diện cho địa chỉ của subarray đầu tiên (ví dụ) board[0]

  2. board[0] repres ENT địa chỉ của phần tử đầu tiên trong mảng đầu tiên (nghĩa là) board[0][0]

Tại sao tôi nhận địa chỉ giống nhau trong mọi printf() báo cáo của tôi? Tôi mong đợi các địa chỉ khác nhau cho cả hai câu lệnh.

Tôi khá mới mẻ đối với nội dung này và không hiểu hành vi này. Vui lòng khai sáng cho tôi.

Trả lời

1

Theo hiểu biết của tôi, hội đồng quản trị (ví dụ) tên mảng đại diện cho địa chỉ của mảng con đầu tiên (ví dụ) bảng [0]

này chỉ đúng nếu board được sử dụng bên ngoài của những bối cảnh

  • Như toán hạng của & hành
  • Như toán hạng của sizeof

Khi bất kỳ điều nào áp dụng, biểu thức board đại diện cho mảng và tiếp tục có loại mảng (char[3][3]). Áp dụng toán tử & cho kết quả nhận địa chỉ của mảng, tất nhiên là bằng địa chỉ của phần tử đầu tiên, chỉ có một loại khác (char(*)[3][3] thay vì char(*)[3]). Điều tương tự cũng đúng về mảng board là đúng về mảng phụ đầu tiên của nó board[0].

Khi bạn sử dụng nó bên ngoài các ngữ cảnh đó, bạn sẽ nhận được địa chỉ của phần tử đầu tiên (trong trường hợp của bạn). Địa chỉ đó không phải là một đối tượng mà chỉ là một giá trị. Giá trị không có địa chỉ, nhưng đối tượng có. Cố gắng áp dụng & vào nó sẽ thất bại. Ví dụ:

// error: trying to apply '&' on something that has no address 
&(1 ? board : board) 

Lưu ý rằng mọi điều nêu trên áp dụng cho C; không nhất thiết phải là C++.

+0

Xin cảm ơn sự trả lời của bạn và tôi đã hiểu một phần. Bạn có thể cung cấp một chương trình mẫu đơn giản giải thích nhận xét của bạn không. Tôi sẽ giúp đỡ rất nhiều. Cảm ơn bạn. – intex0075

+0

@intex câu hỏi của bạn * là * chương trình ví dụ đơn giản mà tôi sẽ cung cấp. –

5

Mặc dù đó là một mảng 2D, bên trong bộ nhớ nó sẽ được biểu diễn dưới dạng mảng tuyến tính. vì vậy khi bạn nói, bảng [0] [0] nó vẫn trỏ đến phần tử đầu tiên trong mảng tuyến tính đó và do đó cùng một địa chỉ bộ nhớ.

1

Tất nhiên điều này sẽ in cùng một địa chỉ.
Suy nghĩ về mảng 2D như thế này trong một phút,

int ** ptr;


Địa chỉ *ptr làm bằng &(**ptr).

Bởi vì về cơ bản, đó là những gì mã của bạn đang làm.

và nhớ rằng trong bộ nhớ, mảng 2D sẽ được ánh xạ tuyến tính.

1

Có thể là trường hợp bạn biết một ngôn ngữ hướng đối tượng như Java hoặc Python, và bây giờ bạn đang học ngôn ngữ C. Sự khác biệt giữa Java và C khi suy nghĩ về char board[3][3] là trong C, biến số board được biểu diễn trong bộ nhớ dưới dạng 9 ký tự tại các địa chỉ bộ nhớ lân cận. Cũng giống như vậy:

board: 1 2 3 4 5 6 7 8 9 

Trong C, &board mang lại địa chỉ bộ nhớ giống như &board[0]&board[0][0].

Ngược lại này, trong Java biến sẽ được khai báo là char[][] board và đại diện bộ nhớ của nó khái niệm sẽ trông như thế này:

board: ptr(A) ptr(B) ptr(C) 
A:  1 2 3 
B:  4 5 6 
C:  7 8 9 

nơi ptr(x) điểm đến địa chỉ bộ nhớ của x. Vì vậy, trong Java, board trỏ đến một địa chỉ bộ nhớ khác với board[0].


Bạn nói Trong C, & bảng mang lại địa chỉ bộ nhớ giống như [0] & đồng quản trị và Ban & [0] [0]. Nhưng tôi có thể truy cập phần tử đầu tiên chỉ qua bảng [0] [0] (hoặc) * bảng [0] (hoặc) **. Tại sao nó như vậy??

Mặc dù các biểu thức &board&board[0]&board[0][0] mang lại cùng một địa chỉ, các hệ thống kiểu của ngôn ngữ C đang ngăn bạn truy cập các giá trị char. Trong một trình biên dịch C, các loại là (theo lý thuyết):

board:  type char[3][3] 
board[0]: type char[3] 
board[0][0]: type char 

Giả sử một biến kiểu char, chúng ta có thể viết:

char c; 
c = board[0][0]; 

nhưng không thể viết:

char c; 
c = board; // Error 
c = board[0]; // Error 

vì loại ở phía bên trái không tương thích với loại ở bên phải của nhiệm vụ.

Nếu bạn chắc chắn rằng một điểm địa chỉ để một char, bạn có thể sử dụng một loại diễn viên:

char c; 
c = *(char*)board; // Works OK 
c = *(char*)board[0]; // Works OK 

Nhược điểm là phôi kiểu như vậy có thể dẫn đến lỗi mã hóa.

+0

Bạn nói In C, & board mang lại cùng một địa chỉ bộ nhớ như & board [0] và & board [0] [0]. Nhưng tôi có thể truy cập phần tử đầu tiên chỉ qua bảng [0] [0] (hoặc) * bảng [0] (hoặc) **. Tại sao nó như vậy?? – intex0075

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