2014-11-13 2 views
5

C : int a [2] [3] [4] [5]에있는 배열의 정의와 [0] [0] [ 0] [1] [1] [1]의 주소가 1000인데 int가 4 바이트를 차지한다고 가정합니다.C 배열에있는 인덱스의 주소 찾기

I는 얻었다 :

(3 * 4 * 5 * 4 바이트) + (4 * 5 * 4 바이트) + (5 * 4 바이트) + 4 바이트 = 344

344 + 1000 = 1344 위치 of a [1] [1] [1] [1]

그러나 나는 옳은지 전혀 모른다. 하지만 제 수학은 제게 소리가 나는 것처럼 보였습니다.

+0

나에게 좋은 소리. – JS1

답변

3

그냥 변수의 ADRESS를 인쇄 어떤 당신은 그것을 볼 수 있습니다! :

#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; 

} 

을 그 후에 당신이 어디에 적합한 지 확인하실 수 있습니다!

그리고 당신이 당신의 권리를 보았습니다! 이 같은 334

+0

두 번째'printf'는'a [1] [1] [1]'이 아니라'a [1] [1] [0]'의 주소를 제공합니다. 왜 당신이하려는 일에 대해 직설적으로 말하지 않고'& a [0] [0] [0] [0]'이라고 써야합니까? –

+0

@RedAlert Wups는 1 차원을 잊어 버렸습니다! 덕분에 – Rizier123

+0

포인터가'% d'에 문제가 있습니다 (특히 int가 32 비트이고 포인터가 64 비트 인 경우), [uintptr_t] (http://stackoverflow.com/questions/5795978/string-format-for-intptr-t)를 사용해보십시오. - 그리고 - uintptr - t) –

0

뭔가 확인하는 매우 간단입니다 (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; 
} 

그의 출력은 다음과 같습니다 int 값으로 포인터의

4 
2665056 
2665400 
1344 

참고 변환 그 마지막에 printf. 이 값이 없으면 1000int *으로 조정되어 잘못된 값을 제공합니다.

네, 결론은 틀렸다고 생각합니다.


(a)는 그들이 원하는하지 항상 C 언어의 일부 측면이 구현에 걸쳐 (구현에 지정된 동작을) 다를 수 있기 때문에 경우 또는 어떤 식 으로든 것 (정의되지 않은 동작). 다행히도

가 배열 의 레이아웃 C11 6.5.2.1 Array subscripting에서 표준으로 상세 규정이다 대괄호 표현 하였다

2/A 접미사 식 [] 배열 요소의 첨자 지정 인 목적. 아래 첨자 연산자 []의 정의는 E1[E2](*((E1)+(E2)))과 동일하다는 것입니다. 이진 + 연산자에 적용되는 변환 규칙으로 인해 E1이 배열 객체 (즉, 배열 객체의 초기 요소에 대한 포인터)이고 E1[E2]E2-th 요소를 E1 (0부터 세 수)으로 지정하면 정수입니다.).

3/연속 첨자 연산자는 다차원 배열 객체의 요소를 지정합니다. E이 차원이 i * j * ... * k 인 n 차원 배열 (n> = 2) 인 경우 E (왼쪽 값 외의 것으로 사용됨)은 차원이 j * ... * k 인 (n - 1) 차원 배열에 대한 포인터로 변환됩니다.단항 * 연산자가이 포인터에 명시 적으로 적용되거나 암시 적으로 하위 스크립팅의 결과로 적용되는 경우 결과는 참조 된 (n - 1) 차원 배열이며 lvalue가 아닌 다른 포인터로 사용되는 경우 포인터로 변환됩니다. 배열은 행 우선 순서대로 저장됩니다 (마지막 첨자는 가장 빠르게 변합니다).

+1

출력이 이상하게 보일 때,'2665400 - 2665056 + 1000'은'1086 '이 아닙니다. 컴파일러가 포인터 연산을하려고한다고 생각합니다. –

+1

@RedAlert, 네, 그냥 그걸 알았고, 당신이 생각하기에 C가 많은 사람은 저와 같이 벨트를 앞에두고 그것을 알 것입니다 :-) 수정하여 수정했습니다. – paxdiablo

3

수학이 정확합니다. 당신은 두 개의 주소를 빼서 확인할 수 있지만, 활자 크기를 인식 할 수 포인터 연산을 잊지 마세요, 그래서 당신은 바이트의 크기를 가지고있는 숯불에 주소를 캐스팅해야한다 :

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

을 제공합니다 바이트의 차이. 그런 다음 시작 주소를 추가하면 답변을 얻을 수 있습니다.