2012-10-14 2 views
0

그냥 알고 싶습니다 - 함수에서 참조로 2 차원 배열에 포인터를 전달하는 올바른 방법입니까? 참조로 2 차원 배열에 포인터 전달

bool test::testTheNumber(test (*arr)[9][9], int testNumber, int row, int column) 
{ 
    if(theRow(arr, testNumber, row) && theColumn(arr, testNumber, column)) 
    .... 
} 

내 "theRow"와 "theColumn"답변

테스트 기능과 매우 유사하다 : 내 MAIN.CPP에서

bool sodoku::theRow(sodoku (*arr)[9][9], int testNumber, int row) 

bool sodoku::theColumn(sodoku (*arr)[9][9], int testNumber, int column) 

, 나는 2 차원 배열에 대한 포인터를하고 난 내 함수를 호출 같은 :

test *arr[9][9]; 
theRow(arr,0,0); 
theColumn(arr,0,0); 
testTheNumber(arr,0,0,0,0); 

배열은 참조로 전달할 것인가 또는 나는 * 대신 &를 사용하는 것? 나는 2-D 배열이 어떻게 작동하는지 완전히 모르기 때문에 조금 혼란스러워합니다.

감사합니다.

답변

2

배열이

bool test::testTheNumber(test (*arr)[9], int testNumber, int row, int column) 
{ 
    if(theRow(arr, testNumber, row) && theColumn(arr, testNumber, column)) 
    .... 
} 

또는

bool test::testTheNumber(test arr[][9], int testNumber, int row, int column) 
{ 
    if(theRow(arr, testNumber, row) && theColumn(arr, testNumber, column)) 
    .... 
} 

첫 번째 차원은 필요하지 않습니다.

실제로 배열은 기본적으로 참조로 전달됩니다. &은 필요하지 않습니다.

자세한 내용은 this answer to this question을 읽어보십시오.

+0

아, 고마워. 배열은 기본적으로 참조로 전달됩니다. 그냥 궁금해서. – user1567909

+0

원래 이유를 모르지만 C 언어에서 상속 된 것 같습니다. 기본적으로 값으로 전달하는 것은 필요한 메모리로 인해 좋은 생각처럼 들리지 않습니다. –

+1

'void f (int a [9] [9])'가 아닌'void f (int (* a) [9])'(9 int 배열에 대한 포인터/배열) (int에 대한 포인터/배열) –

0
bool test::testTheNumber(test (*arr)[9][9], int testNumber, int row, int column) 

이 함수에 기준하여 2-D 어레이에 대한 포인터를 전달하는 올바른 방법?

기술적으로 이것은 참조로 배열을 전달하는 것이 아니라 값을 기준으로 배열에 포인터를 전달하는 것입니다. 의미론은 다른 점에서는 매우 유사합니다. & (참조)의 유일한 차이는 * (포인터)를 변경하는 것을

bool test::testTheNumber(test (&arr)[9][9], int testNumber, int row, int column) 

참고 참조하여 함수 에 9x9의 정수 배열을 전달할 서명 할 것이다. 이것의 사용은 다음과 같습니다

int main() { test array[9][9]; test t; t.testTheNumber(array,1,2,3); } 

(이 이해하지 여부는 완전히 다른 것입니다 ... 당신이 멤버 함수보다는 비 멤버 함수를 제공 할 수 있습니다, 예를 들어)

Geoff 제안 제안은 모두 동일하며 인터페이스 변경시 배열의 크기가 서명에서 고정되지 않는다는 점이 문제입니다. 즉,이 함수는 9x9의 배열을 사용하지만 2x9,3x9 ... Nx9의 배열도 허용합니다. 당신이 볼 수 있듯이

bool f(int (*arr)[9]); 
int main() { 
    int array[9][9]; 
    f(array);   // ok, but so is: 
    int array2[3][9]; 
    f(array2); 
} 

는 함수 인수의 유형을 변경하여, 첫 번째 차원은 이제 무료이며이 원본보다 더 나쁜 옵션 그래서 컴파일러는 기꺼이이 어떤 크기를 받아 들일 것입니다 하나.

마지막으로, 제안 사항은 9x9 행렬을 나타내는 유형을 작성하고 해당 유형에 대한 참조를 전달하는 것입니다.

+0

@Geoff_Montee : 예, 정확한 서명에 초점을 맞추고 부패를 잘못 무시했습니다. 제안 사항은 모두 동등하고 똑같은 문제가 있습니다. 배열의 첫 번째 차원은 고정되어 있지 않으므로 컴파일러는 크기를 기꺼이 수용 할 것입니다. 포인터 (질문에서와 같이) 또는 참조 (이 대답에서와 같이)를 사용하면 컴파일러가 컴파일시 2 차원을 검사 할 수 있습니다. –

2

C 배열은 매우 복잡하고 C++가 배열의 작동 방식을 이해하려면 C.와 호환되도록 혼란을 상속 기본 사항은 다음과 같습니다

1) 배열 변수는 것을 제외하고는 첫 번째 요소에 대한 포인터로 표현 행동 그것은 상수입니다 (즉, "array = p;"를 수행 할 수 없습니다) 그리고 sizeof (array)는 배열의 크기 (한 요소의 크기와 요소의 수의 곱)를 제공하지만 sizeof (포인터)는 포인터.

int array[5]; 
int* p = array; 

그런 다음 다음과 같은 표현은 해당 : 당신이 배열로 함수의 인수를 정의 할 때

array[0] == *array 
sizeof(array) == sizeof(int)*5 
sizeof(p) == sizeof(void*) 

2), 그것은 항상 첫 번째 요소에 대한 포인터로 전달됩니다. 그리고 그 기능으로 행동합니다. 사실, C는 전달 된 배열의 크기를 무시합니다. 더우기 함수에서 인수를 배열의 요소 또는 배열 요소의 포인터로 정의하는 것은 컴파일러에서 동일하게 간주됩니다. 그래서 :

void func(int array[5]); 
void func(int array[]); 
void func(int *array); 

는 동일한 기능을 선언하고이 기능는 sizeof (배열) == sizeof 연산자 (무효 *) 때문에 그

내부 배열처럼 보이는, 항상 참조에 의해 전달 될 것으로 보인다 첫 번째 요소에 대한 포인터.

이제 다차원 배열은 요소가 배열 인 일차원 배열입니다. C/C++의 혼란스러운 부분은 C/C++에서 일반적인 유형을 정의하는 혼란스러운 방식입니다. 그래서 :

test* array[9][9]; 

는 C/C++ 타입을 읽어 그 기억하면 식별자로 시작하고 []와() 우선 순위를 가지고, 그래서 어레이 9 개 요소들의 어레이이다 (제 [9]) 배열되는 "test"유형에 대한 포인터 인 9 개 요소 (두 번째 [9]). 이 방법에서 도착 인수하기

:

bool sodoku::theRow(test (*arr)[9][9], int testNumber, int row) 

도착 9 "테스트"요소 (9 개)의 배열의 배열에 대한 포인터 (괄호 우선 순위를 변경)된다.

이 "배열"포인터를 포함 특히 때문에, 상기 이전의 "어레이"변수는 매우 다르다 "테스트"도착는 "테스트"요소를 포함하면서보기 BTW

은 다음의 선언을 완전히 동일 ", 언"도 9 "테스트"9 개 배열의 배열의 첫 번째 요소에 대한 포인터로 해석 될 수

bool sodoku::theRow(test arr[][9][9], int testNumber, int row) 

...

boot sudoku::theRow(test arr[][9], int testNumber, int row) 
{ ... } 

test array[9][9]; 
sudoku::theRow(array, 0, 0); 

그리고 그 방법으로도 정의 할 수 있습니다 : 당신은 아마 수행 할 작업을 실제로

, 그래서, "테스트"9 개 배열의 전달 배열입니다

boot sudoku::theRow(test (*arr)[9], int testNumber, int row) 
{ ... } 

많은 정보가 C/C++의 매우 혼란스러운 배열/포인터 혼합에 관한 인터넷 상에 존재합니다. 예를 들면 : http://pw1.netcom.com/~tjensen/ptr/pointers.htm

+0

위대한 설명! –

+1

+1 배열에 대한 실제 참조를 포함하지 않는다는 점을 제외하고는 설명이 좋습니다. 그러나 결국 제안은 Geoff의 제안과 동일한 문제입니다. 유형 정보의 일부를 제거하는 것입니다. 마지막에 정의 된 함수는 'N'의 가능한 값에 대해'test [N] [9]'의 배열을 전달할 수 있습니다. 즉, 컴파일러는 인수가 올바른 차원인지 확인하지 않습니다. C++에서 해결책은 9x9 배열에 대한 적절한 참조 인'test (& array) [9] [9]'를 전달할 것입니다. –

+0

맞습니다. 배열 참조에는 "배열 감소"기능을 C 언어에서 상속 된 첫 번째 요소에 대한 포인터에 의존하는 대신 인수에 대한 크기 정보를 유지하는 이점이 있습니다. 불행히도, 대부분의 경우, 나는이 정보의 손실에 대해 충분히 신경 쓰지 않고 오래된 C 습관으로 돌아갑니다 (너무 오래 프로그래밍 된 것 같습니다 :-)) 사실, 배열을 조작 할 때, 나는 배열 <>과 벡터 <>와 같은 새로운 C++ 래퍼 템플릿을 사용하거나 자신의 클래스로 래핑하는 것을 선호합니다. 그들은 훨씬 "C++"감각을 만듭니다 ... –