2014-11-13 14 views
5

Với định nghĩa của một mảng trong C: int a [2] [3] [4] [5] và địa chỉ của [0] [0] [ 0] [0] là 1000 địa chỉ của [1] [1] [1] [1], giả sử một int chiếm 4 byte.Tìm địa chỉ của chỉ mục trong một mảng trong C

tôi nhận:

(3 * 4 * 5 * 4bytes) + (4 * 5 * 4bytes) + (5 * 4bytes) + 4bytes = 344

344 + 1000 = 1344 Location của [1] [1] [1] [1]

nhưng tôi không biết mình có đúng hay không. Nhưng toán học của tôi dường như có vẻ hợp với tôi.

+0

Nghe hay với tôi. – JS1

Trả lời

3

Just in địa chỉ của biến bất kỳ bạn sẽ thấy nó !:

#include <stdio.h> 

int main() { 

    int a[2][3][4][5]; 

    printf ("Size of int %d\n", sizeof(int)); 

    printf("Adress of the frist element \t%p\n", &a[0][0][0][0]); 
    printf("Adress of x element \t\t%p\n", &a[1][1][1][1]); 

    printf ("In decimal: \t\t\t%d\n", &(a[0][0][0][0])); 
    printf ("In decimal: \t\t\t%d\n", &(a[1][1][1][1])); 

    printf("Difference between the adresses %d", (char *)&a[1][1][1][1] - (char *)&a[0][0][0][0]); 




    return 0; 

} 

Sau đó bạn có thể kiểm tra xem bạn nơi đúng!

Và khi bạn thấy quyền của mình! nó 334

+0

'printf' thứ hai của bạn cung cấp địa chỉ của' a [1] [1] [1] [0] ', không phải' a [1] [1] [1] [1] '. Tại sao không đơn giản về những gì bạn đang cố gắng làm và viết '& a [0] [0] [0] [0]'? –

+0

@RedAlert Wups đã quên 1 thứ nguyên! cảm ơn – Rizier123

+0

'% d' với con trỏ là vấn đề (đặc biệt nếu int là 32 bit và con trỏ là 64 bit), hãy xem xét sử dụng [uintptr_t] (http://stackoverflow.com/questions/5795978/string-format-for-intptr-t -and-uintptr-t) –

0

Something như thế là khá đơn giản để kiểm tra (a):

#include <stdio.h> 

int main (void) { 
    int a[2][3][4][5]; 

    // Ignore incorrect format specifiers for now. 

    printf ("%d\n", sizeof(int)); 
    printf ("%d\n", &(a[0][0][0][0])); 
    printf ("%d\n", &(a[1][1][1][1])); 
    printf ("%d\n", (int)&(a[1][1][1][1]) 
        - (int)&(a[0][0][0][0]) 
        + 1000); 

    return 0; 
} 

và đầu ra của đó là:

4 
2665056 
2665400 
1344 

Lưu ý chuyển đổi của các con trỏ để int giá trị trong đó printf cuối cùng. Nếu không có điều này, 1000 sẽ được chia tỷ lệ là int *, đưa ra giá trị sai.

Vì vậy, có, dòng dưới cùng, lý do của bạn là chính xác.


(a) Đó không luôn trường hợp vì một số khía cạnh của ngôn ngữ C có thể khác nhau giữa các hiện thực (hành vi thi hành chỉ định) hoặc trong bất kỳ cách nào họ muốn (hành vi undefined).

Hạnh phúc, bố trí các mảng quy định cụ thể của tiêu chuẩn, trong C11 6.5.2.1 Array subscripting:

2/Một biểu thức postfix tiếp theo là một biểu hiện trong dấu ngoặc vuông [] là một định subscripted của một phần tử của một mảng vật. Định nghĩa của toán tử số đăng ký []E1[E2] giống hệt với (*((E1)+(E2))). Do quy tắc chuyển đổi áp dụng cho toán tử nhị phân +, nếu E1 là đối tượng mảng (tương đương, con trỏ đến phần tử ban đầu của đối tượng mảng) và E2 là số nguyên, E1[E2] chỉ định thành phần E2-th của E1 (đếm từ 0).

3/Toán tử con số liên tiếp chỉ định một phần tử của đối tượng mảng đa chiều. Nếu E là mảng n chiều (n> = 2) có kích thước i * j * ... * k thì E (được sử dụng không phải lvalue) được chuyển thành con trỏ thành mảng (n - 1) có kích thước j * ... * k.Nếu toán tử * đơn nhất được áp dụng cho con trỏ này một cách rõ ràng, hoặc ngầm định là kết quả của subscripting, kết quả là mảng tham chiếu (n - 1), mà chính nó được chuyển đổi thành một con trỏ nếu được sử dụng không phải là một lvalue. Sau đó, các mảng được lưu trữ theo thứ tự hàng lớn (chỉ số cuối cùng thay đổi nhanh nhất).

+1

rằng đầu ra có vẻ lạ, '2665400 - 2665056 + 1000' không phải là '1086'. Tôi tưởng tượng trình biên dịch nghĩ rằng bạn đang cố gắng làm số học con trỏ. –

+1

@RedAlert, vâng, chỉ cần nhận thấy rằng, và bạn sẽ nghĩ rằng ai đó với càng nhiều C dưới vành đai của họ như tôi sẽ biết rằng lên phía trước :-) Sửa đổi để sửa chữa. – paxdiablo

3

Toán học của bạn là chính xác. Bạn có thể kiểm tra bằng cách trừ hai địa chỉ, nhưng đừng quên rằng con trỏ số học sẽ nhận ra kích thước chủng loại, vì vậy bạn phải đúc các địa chỉ để char trong đó có một kích thước của một byte:

(char*)&a[1][1][1][1] - (char*)&a[0][0][0][0] 

mang đến cho các sự khác biệt về byte. Sau đó, chỉ cần thêm địa chỉ bắt đầu và bạn có câu trả lời của mình.

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