2009-08-25 5 views
57
다음 프로그램 주어

,함수에 특정 크기의 배열 매개 변수가 있으면 포인터로 대체되는 이유는 무엇입니까?

#include <iostream> 

using namespace std; 

void foo(char a[100]) 
{ 
    cout << "foo() " << sizeof(a) << endl; 
} 

int main() 
{ 
    char bar[100] = { 0 }; 
    cout << "main() " << sizeof(bar) << endl; 
    foo(bar); 
    return 0; 
} 

출력

main() 100 
foo() 4 
  1. 이유는 어레이의 첫 번째 요소에 대한 포인터로 전달?
  2. C의 유산입니까?
  3. 표준은 무엇을 말하고 있습니까?
  4. C++의 엄격한 유형 안전이 중단 된 이유는 무엇입니까?
+0

:: 배열이 같은 문제를 처리하는 데 너무 표준 알고리즘을 – paulm

+2

무엇 엄격한 타입의 안전을 작동 방지? 누가 엄격한 유형 안전을 약속 했습니까? C++에는 그런 것이 없다. –

+0

아래 답변에 대한 DR : 배열은 함수에 전달 될 때 포인터가되므로 크기를 확인하면 포인터 크기가됩니다. C로만 작업하는 중이라면 배열에서 벗어나려고하는 모든 크기를 다른 매개 변수로 미리 계산하는 것이 좋습니다. –

답변

63

예 그것은 C.에서 기능 상속 된 것 :

void foo (char a[100]); 

포인터로 조정 매개 변수를 가지고 있고, 그렇게 될 것이다 :

void foo (char * a); 

배열 유형을 보존하려면 배열에 대한 참조를 전달해야합니다.

void foo (char (&a)[100]); 

63,210 C++ '03 8.3.5/3

...이 함수의 형태는 다음과 같은 규칙을 사용하여 결정된다. 각 매개 변수의 유형은 자체 decl-specifier-seq 및 declarator에서 결정됩니다. 각 매개 변수의 유형을 결정한 후 "T 배열"또는 "T를 반환하는 함수"유형의 매개 변수는 각각 "T에 대한 포인터"또는 "T를 반환하는 함수에 대한 포인터"로 조정됩니다 ....

구문 설명하기 : 구글에서 "좌우"규칙에 대한

확인; 그 중 하나에 대한 설명을 찾았습니다 here.그것은으로 약이 예에 적용 할 것

은 다음과 같습니다

void foo (char (&a)[100]); 

시작 '은이'

'이'는

이동 권리 식별자에 - 우리가 찾을 수 a ) 그래서 우리는 방향을 바꾸어 (를 찾는다. 우리가 왼쪽으로 이동하면 우리가 &

을 통과 A는 우리가 개방 ( 그래서 우리는 다시 반전과 오른쪽 볼에 도달 & 후 참조

입니다. 우리는 지금 '는이'100

의 배열에 대한 참조입니다

[100]보고 우리가 char에 도달 할 때까지 우리는 다시 방향을 전환 :

'는이'에 대한 참조입니다 100 문자의 배열

+1

후자에는 배열 크기를 함수 시그니처에 하드 와이어하는 단점이 있습니다. 함수 템플리트는이를 피할 수 있습니다. – sbi

+0

다소 관련있는 메모에서 누군가 나를 위해 위의 구문을 정리할 수 있습니까? 분명히 뭔가 빠졌지 만 배열에 대한 참조를 평가하는 방법을 잘 알지 못합니다. 그것은 참조의 배열처럼 보이게됩니다. – suszterpatt

+4

아마 std :: vector를 사용하면 배열을 전달하는 것과 관련된 모든 문제를 깔끔하게 처리 할 수 ​​있습니다. – markh44

12

예. C 및 C++에서는 배열을 함수에 전달할 수 없습니다. 그것이 바로 그 방법입니다.

왜 일반 배열을 사용하고 있습니까? boost/std::tr1::array/std::array 또는 std::vector을 보셨나요?

그러나 임의의 길이의 배열에 대한 참조는 템플릿 함수에 전달할 수 있습니다. 내 머리 위로 떨어져 :

template< std::size_t N > 
void f(char (&arr)[N]) 
{ 
    std::cout << sizeof(arr) << '\n'; 
} 
+5

그러나 "배열에 대한 참조"를 전달할 수 있습니다. –

+0

그냥 약간의 레거시 코드 – CsTamas

+0

@ 리차드 : 나는 당신이 당신의 코멘트를 쓰는 동안 이것을 추가하고있었습니다. ':)' – sbi

1

정적 배열에 사용되는 C/C++ 용어에는 훌륭한 단어가 있습니다. d 함수 포인터 - 부패. 다음 코드를 고려하십시오, 이러한 경우 항상 표준을 사용

int intArray[] = {1, 3, 5, 7, 11}; // static array of 5 ints 
//... 
void f(int a[]) { 
    // ... 
} 
// ... 
f(intArray); // only pointer to the first array element is passed 
int length = sizeof intArray/sizeof(int); // calculate intArray elements quantity (equals 5) 
int ptrToIntSize = sizeof(*intArray); // calculate int * size on your system 
+1

그리고? 이것은 기껏해야 간접적으로 _ 발생하는 것을 나타냅니다. OP는 그런 식으로 언어가 설정되어 있는지 묻고있었습니다. 또한 "정적 배열"은 실제로 의미하는 것이 동적으로 할당 될 때 혼란스러운 용어입니다. 엄밀히 말하면, 여러분이 보여준 배열은'정적'이 아니라'외부 적 '연결을 가지고 있습니다. 그리고 함수 포인터가 여기서 무엇을해야하는지 잘 모르겠습니다. –