2013-07-23 3 views
37

포인터를이 없음. 왜 이런 일이 일어나는 걸까요?COUT << 숯 * 인수 인쇄 문자열 가치

+0

"안녕하세요"가되지 않습니까? – sth

+0

출력으로'h'가 표시됩니까? 그렇게해서는 안됩니다. 출력으로'hello'를 얻어야합니다. 여기에 게시 한 코드가 오타 또는 복사하여 붙여 넣기 오류가 아니라고 정확합니까? –

+0

@sth 그는 그렇게한다 : http://ideone.com/IDudH3 – dotixx

답변

8

이에 코드를 변경해야합니다

cout << static_cast<const void*>(terry); 

문제는 << 연산자는 문자열의 내용을 인쇄하기 위해 C 스타일의 문자열에 대한 포인터에 대한 과부하 때문이다. 대신 원시 포인터로 캐스팅하면 원하는대로 iostream을 사용하여 포인터를 인쇄하는 기본 동작을 갖게됩니다.

-1

"hello"는 문자열, 즉 char 배열입니다. const char*은이 배열에 대한 포인터이므로이 포인터를 역 참조 할 때 첫 번째 요소의 값을 가져옵니다. 당신이

int a[] = {1, 2, 3}; 
int *b = a; 
cout << *b << endl; 

이 있다면 당신은 단지 1 인쇄 얻을처럼

때문이다.

+0

왜 메모리 주소를 가져 오지 못하나요? –

+1

@ Mr.Puff char 포인터의 메모리 주소를 얻고 싶다면'ostream << '연산자가 인쇄 문자열에 대한 char 포인터에 대해 오버로드되기 때문에 void 포인터 앞에 캐스팅해야합니다. –

53

std::coutchar *을 C 스타일 문자열 (의 첫 번째 문자)에 대한 포인터로 처리하고 그처럼 인쇄합니다. 대신 주소을 원하는 경우에, 당신은 단지 이 처리되지 것을 포인터로 캐스팅 할 수있는 방법, 뭔가 같은 :

cout << (void *) terry; 

(또는 주조 걱정 경우 const void * 캐스트를 사용 떨어져있는 꾸밈음,이 특별한 경우에는 문제가되지 않는 것). 당신은 실용 주의자보다 순수 주의자의 더 많은 경우


, 당신은 또한의 라인을 함께 C++ static_cast를 사용할 수 있습니다

그것으로,이 특별한 경우에 캐스트를 불필요하지만
cout << static_cast <const void *> (terry); 

void * 잘 작동합니다.

#include <iostream> 
int main (void) { 
    const char *terry = "hello"; 
    std::cout << terry << '\n'; 
    std::cout << (void *) terry << '\n'; 
    std::cout << (const void *) terry << '\n'; 
    std::cout << static_cast<const void *> (terry) << '\n'; 
    return 0; 
} 

가 (주소가 사용자 환경에서 다를 수 있습니다) 출력 : 다음 static_cast를 사용할 때, 당신은 당신에게 돈을 확인해야합니다
hello 
0x8048870 
0x8048870 
0x8048870 

것을 다음 샘플 코드 작업에 모든 옵션을 보여줍니다 static_cast <void *> (그게 const_cast을위한 것임)으로 constance를 버리려고하지 마십시오. 이것은 최신 C++ 캐스트에 의해 수행되는 점검 중 하나이며 이전 스타일의 캐스트에는이 제한이 없습니다.

+1

'char *'값을 C 스타일 문자열로 취급하지 않습니다. C 스타일의 문자열 (의 첫 번째 문자)에 * 포인터 *로 취급합니다. –

+1

@ 키스, 의미 문제, 사과드립니다. 내 말은 C 스타일 문자열로 출력한다는 것입니다. 나는 분명히 할 것이다. – paxdiablo

+0

"의미론"이란 단어가 중요하지 않다는 것을 의미합니까? 그렇지 않습니다. –

1

cout이 오버로드되어 char *을 주면 C 스타일 문자열에 대한 포인터로 인쇄됩니다. 그래서, 그것은 문자를 널 문자를 치기 전까지 출력합니다.

cout 대신 printf를 사용하면 주소가 표시됩니다. 포인터를 다른 유형, 예를 들어 (void *)로 캐스팅 할 수 있으며 주소도 얻을 수 있습니다.

+0

'printf' 자체가 어떻게 출력할지 결정하지 않고, C++에서 같은 타입을 사용해야하는 것과 같은 방식으로 올바른 포맷 지정자를 사용해야합니다. 예를 들어'% s '를 사용하는'printf'는'char *'를 가진'cout'과 똑같은 이슈를 갖습니다. 포인터를 얻으려면 형식 지정자'% p'를 사용하십시오. – paxdiablo

11

<<의 연산자는 std::cout입니다. 그 동작은 오른쪽 피연산자의 유형에 따라 다릅니다. (사실은 여러 가지 기능을 모두 operator<<라는 이름의, 컴파일러가 호출되는 하나를 결정합니다.)

당신이 그것을이 char* 또는 const char*, 그것은 (의 첫 번째 문자)는 C-에 대한 포인터로 피연산자를 취급주는 경우에

cout << *terry; // prints "h" 
cout << terry[0]; // the same 

당신이 그것을 일반의 포인터를 제공하는 경우 : 당신이 그것을 char 값을 제공하는 경우

const char * terry = "hello"; 
cout << terry; // prints "hello" 

, 그것은 문자로 그 값을 출력 : 스타일 문자열 및 해당 문자열의 내용을 인쇄 C 스타일 문자열에 대한 포인터는 특별한 경우로

cout << static_cast<const void*>(terry); // prints something like 0x4008e4 

char* 또는 const char*을 치료하고, 하나의 : 전자 void*, 그것은 (일부 구현 정의 방법으로, 일반적으로 16 진수)이 포인터 값을 인쇄 (내가 생각할 수있는) operator<<은 피연산자의 값이 아닌 다른 값을 출력합니다. 그 이유는 "문자열"형식을 가지고 있지 않고 char* 포인터를 통해 문자열을 조작하는 C에서 C++의 근원으로 돌아갑니다.

operator<<, 다양한 정수 및 부동 소수점 숫자 형식에 대해 std::string 등의 다른 많은 오버로드가 있습니다.

+0

내가 생각할 수있는 또 하나의 특별한 경우는 함수 포인터를 출력하려고 시도하는 것입니다. 함수 포인터는'bool' 오버로드를 선택합니다 (함수가 스트림 조작기의 서명을 가지고 있지 않다면) : http://ideone.com/OkutRD (admittedly , 그것은'bool'로 변환 된 포인터의 "value"를 출력하기 때문에'const char *'의 경우보다 덜 특별합니다) –

관련 문제