2012-01-27 2 views
-2

C에서 2 차원 배열은 선형 배열처럼 저장되지만 이중 포인터를 사용하여 인덱싱됩니다. 우리는 7왜 int [] []를 int **로 변환하는 컴파일러가 이론상 가능하지 않습니까?

에,

{p1 = 0x7fff5fbffb58 , p2 = 0x7fff5fbffb70, p3 = 0x7fff5fbffb88} 

다음 p1 포인트 1처럼 뭔가에 4 p2p3 점을

int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}}. 

a 첫 번째 지점을 정의하는 경우 즉, 왜 돈 ' t 컴파일러는 이론적으로 가능한 2 차원 배열에서 이중 포인터로의 변환을 허용합니까? 2 차원 배열은 하나씩 저장되지만 인덱스 정보는 항상 임의의 double 포인터로 전달 될 수 있습니다.

+0

2D 배열의 경우, 컴파일러는 가상 포인터'p1','p2' 및'p3'을 중간 포인터로 저장하지 않습니다. 거짓 가정의 경우 –

+0

-1. 그것은 이론적으로 가능하지 않습니다. ** 배열은 포인터가 아닙니다! ** –

답변

9

이론적으로 가능하지 않습니다. 2d 배열은 이중 포인터를 사용하여 인덱싱되지 않습니다. 컴파일러는이 인덱스를 하나의 인덱스로 변환합니다. 예를 들어 int a[3][5]이 있고 a[i][j]에 액세스하는 경우 컴파일러에서 ((int[])a)[5*i+j]으로 변환합니다. 당신이 int[][]int**로 변환 할 경우, 그 때문에의 모든

(귀하의 설명은 완전히 잘못된 것입니다), 모든 하위 배열의 주소를 저장하는 메모리를 할당하고, 그것의 주소를 얻을 필요가있다. 단지 (int**)a은 작동하지 않습니다.

+0

보세요! 따라서 double (* y) [3] = a와 같은 것은 실제로 2 차원 배열에서 포인터로 가득 찬 목록으로의 변환을 수행합니다! – Strin

+0

번호. 포인터를 배열로 "변환"합니다. 배열처럼 포인터에 접근 할 수 있기 때문에 2D 배열처럼 y에 접근 할 수 있습니다. – asaelr

0

int[][]에서 int**으로 변환하려면 int 개의 데이터로 가득 찬 포인터를 도입해야합니다. 우리는 명시 적으로 요구하지 않을 때 그러한 자유를 잡지 않기 위해 c을 사랑합니다.

1

귀하의 예는 컴파일러가 그것을 할 수없는 이유를 보여 p1의 값 p2, 그리고 p3저장,을하지 계산됩니다. 컴파일러는 p1의 주소를 알고 있으며 배열 크기를 알고있는 다른 두 개를 계산합니다. 반면에 이중 포인터를 사용하면 세 개의 포인터 모두 이 순차적 메모리 위치에에 저장되어 포인터 배열을 형성해야합니다.

0

C가 그렇게 말하기 때문에. "이는 sizeof의 운영자 또는 & 단항 연산자의 연산, 또는 어레이를 초기화하는 데 사용되는 문자열 상수, 입력이있는 경우를 제외 표현"

(C99, 6.3.2.1p3) 배열 형식의 "배열 개체의 초기 요소를 가리키며 lvalue가 아닌"형식에 대한 포인터 "형식의 표현식으로 변환됩니다."

이 변환 규칙은 배열 배열에 대해 재귀 적으로 적용되지 않습니다.

int [N][M] 유형의 객체 값은 변환 후 유형이 int (*)[M]입니다.

0

두 가지 다른 이유가 있습니다. int a [3] [3]은 메모리에 배열의 9 개 요소입니다. int ** 각 요소가 다른 배열을 가리키고 데이터를 포함하는 3 개의 요소가있는 포인터 배열이 있어야합니다.

관련 문제