2011-11-06 3 views
0

C++에서 어렵다고 생각되는 포인터에 대해 명확하게 설명하고 싶습니다. 내가 포인터를 선언하고 같은 함수에 전달하는 경우 : 내가 함수에 변수 a를 통과하면원본 개체의 포인터와 복사 된 개체의 포인터

//just an example 
void showInt(int* numbers) 
{ 
    numbers += 3; 
} 

int main() 
{ 
    int* a = 10; 
    showInt(a); 

    return 0; 
} 

, 나는 실제로 원래 변수를 전달 무엇입니까? 아니면 변수의 복사본을 만든 다음 함수에 전달하는 것입니까?

사본이나 실제/원본을 전달하는 방법을 어떻게 알 수 있습니까?

+0

함수의 이름이 필요합니다. –

+1

@TommyA 예, 죄송합니다. 알아 차 렸습니다. P – Danny

+5

'int * a = 10;이 무엇이든간에, 그렇게하지 않습니다. –

답변

3

당신은 그것은 아무 의미하고 컴파일러 오류에 대한 당신을 말할 것이다

int* a = 10 

할 수 없습니다. 당신이 할 때

:이

//just an example 
void showInt(int* numbers) 
{ 
    numbers += 3; 
} 

int main() 
{ 
    int a = 10; 
    showInt(&a); 

    return 0; 
} 

당신이 의 ADRESS을 통과 한 다음이 ADRESS에 3를 추가, 그래서 아무것도 변경되지 않습니다.

당신은 변경하는 경우 :

numbers += 3; 

*numbers += 3; 

에 다음 변수 의 값을 수정할 수 있습니다. 다만 다음

showInt(a); 

를 사용하고 의 값을 수정할 수 있습니다 그래서

void showInt(int& numbers) 

void showInt(int* numbers) 

을 변경 :

이 작업을 수행하는 또 하나 개의 방법이있다 a이고 사본이 작성되지 않습니다.

0

a10의 값을 가리키는 포인터를 나타냅니다. 메서드에 값 10을 전달하려면 *a을 사용합니다. 메모리 위치는 맨 위의 메소드로 전달됩니다. 그 방법에서 당신은 그것을 3 씩 증가시킵니다.

main()에는 10이 있고, 포인터는 a에 있습니다. [이름이없는] 다른 메서드에서는 포인터가 아니라 int이 필요합니다. 포인터를 변경하면 포인터의 대상이 변경되지 않고 매개 변수 (로컬 변수처럼 작동합니다)가 변경됩니다.

희망은 어떤면에서 도움이됩니다.

[편집 : 이제 int 대신 int* 매개 변수를 사용하도록 상단 방법을 변경했습니다. 그게 더 의미가 있습니다. 내 대답을 수정하자]

먼저 코드에 어떤 객체도 복사되지 않습니다. 실제로 코드에는 실제 객체가없고 메모리와 포인터에있는 int 만 있습니다. 주변을 돌아 다니고 가능하게 변경됨).

showInt이 올바르게 포인터를 사용합니다. 포인터를 증가 시키며,이 경우 포인터는 정의되지 않았거나 유효하지 않은 포인터를 가리 킵니다. numbers += 3을하면 숫자는 원래 포인터가 있던 위치에서 3 바이트를 가리키고 그 모든 것이 바뀝니다. 그리고 그 방법의 범위 내에 있습니다.

다음을 수행 한 경우 *numbers += 3 포인터의 대상이 증가하므로 1013으로 바꿉니다. 해당 메모리에 액세스 할 때마다 적용됩니다 (예 : main).

난 당신이 몇 가지 포인터의 장점 대 참조로 읽는 않는 제안 할 수 (예 int&) - 괜찮은 기사 당신은 꽤 괜찮은 '아하'순간 :

+0

Ugh; 나는 또한'int * a = 10; '이 잘못된 주소 10에 대한 포인터를 생성한다는 점을 놓쳤다. 따라서 위의 내용 이외에 아마도 int v = 10을 의미했을 것입니다. int * a = & v;'- int 값을 10 ('v')으로 할당하고 그 값을 가리 키기 위해 ('a'). –

+0

"Ugh : int * a = 10이라는 점도 놓쳤으므로 주소가 10 인 포인터가 잘못되어 있습니다." 별로 유효하지는 않지만 그가 의도 한 바가 아닐 것이라는 것에 동의합니다. –

+0

일부 임베디드 시스템에서는 메모리 위치 10이 일부 IO 레지스터 또는 뭔가를 가리킬 수 있다고합니다. :) –

0

당신은 포인터로 있어야한다 포인터의 복사본을 매개 변수로 전달하면 포인터는 원래 변수를 가리 킵니다. 따라서 포인터를 역 참조하면 원래 값을 갖게됩니다. 포인터는 기본적으로 무언가의 주소이고, int *은 정수의 주소입니다. 포인터의 값을 변경하면 포인터가 다른 것을 가리키는 주소를 변경하게됩니다. 값을 변경하면 포인터가 다른 것을 가리킬 것입니다. 포인터가 가리키는 점의 값을 변경하면 동일한 객체를 가리키는 동안 값이 변경됩니다. 객체의 값이 가리키는 참조하고 있기 때문에, 다음에

void ptrfunc(int *a) 
{ 
    *a = 10; 
} 

void reffunc(int &a) 
{ 
    a = 50; 
} 

void valfunc(int a) 
{ 
    a = 30; 
} 

int main() 
{ 
    int b = 20; 
    // Pass the point to b to the function, will alter the original. 
    ptrfunc(&b); 
    cout << b << endl; 
    // Pass a reference to b to the function, will alter the original. 
    ptrfunc(b); 
    cout << b << endl; 
    // Pass the value of b to the function, will not alter the original. 
    valfunc(b); 
    cout << b << endl; 
    return 0; 
} 
이 함수 값 INT (10)에게 제 COUT을 인쇄 할

, 50는 기능으로 변화한다.valfunc는 b의 사본의 값을 변경하므로 원본은 변경되지 않습니다.

0

의 당신의 예를 통해 가자 :

void showInt(int* numbers) // (1) 
{ 
    numbers += 3;   // (2) 
} 

int main() 
{ 
    int* a = 10;   // (3) 
    showInt(a);    // (4) 
    return 0; 
} 

(1) numbers 변수가이 함수에 전달 된 변수의 복사본입니다;

(2) (1) numbers의 모든 변경 사항은이 함수 내에서만 유지됩니다. 이 함수에 전달 된 원래 변수의 값은 동일하게 유지됩니다! 그러나 다음 사항에 유의하십시오. 포인터 (a)의 값을 함수로 전달할 수는 없지만 해당 포인터의 복사본 (numbers)을 통해 포인터가 가리키는 값을 변경할 수 있습니다! 그건 주요 트릭입니다. 일단 함수 안에 주소가 있으면, 그 주소에 쓸 수 있고, 함수가 반환 된 후에도 그 변화가 남아 있습니다. 주소에 쓰는 것은 포인터 역 참조를 포함하지만 운 좋게도 그렇게하지 않았습니다 - 전달한 주소가 메모리의 임의의 주소 (10)이기 때문에 운이 좋게 말합니다. 주소 10에 글을 쓰려고하면 프로그램이 중단 될 가능성이 있습니다.

(3) a이 "int to pointer"유형이라고 선언 했으므로 value는 일부 int 개체의 주소로되어 있습니다. 10이 일부 int의 유효한 주소라고 가정 할 때 당신은 여기에서 위험한 실수를 범했지만 그 주소에 무엇이 있는지 실제로 알지 못합니다.

(4) 변수 a 사본을 함수에 전달 중입니다. 함수는 해당 값을 numbers 변수에 저장하고 값을 증가시킵니다. 따라서 numbers에는 13 번 주소가 포함됩니다 (값이 13 인 일부 정수 변수의 주소가 아님).

void showInt(int* numbers) 
{ 
    *numbers += 3;   // (1) 
} 

int main() 
{ 
    int a = 10;    // (2) 
    showInt(&a);    // (3) 
    return 0; 
} 

(1) 함수는 numbers에 보관 주소 값을 수정 : 10

당신은 아마 이런 식으로 뭔가를 원 a하지만 동일하게 유지하며 여전히 같은 값을가집니다. 포인터가 역 참조됩니다.

(2) 무작위로 선택한 주소 (예 : 10)뿐만 아니라 int 변수의 유효한 주소가 필요합니다. 따라서 int 변수 인 a을 선언합니다. 주소는 &a입니다.

(3)의 어드레스 a 변수 numbers 통해 showInt에 전달되며 지금 함수 (int 객체 현재 유효한 주소는 - a) 해당 주소에 기록 할 수 a의 값을 수정하도록. 함수가 돌아 오면 a의 값은 13입니다. a의 주소는 여기에서 언제든지 변경되지 않습니다.