developer tip

cout << with char * 인수는 포인터 값이 아닌 문자열을 인쇄합니다.

optionbox 2021. 1. 7. 07:54
반응형

cout << with char * 인수는 포인터 값이 아닌 문자열을 인쇄합니다.


이:

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

hello의 메모리 주소 대신 인쇄 합니다 'h'. 왜 이런 일이 발생합니까?


그 이유는 a를 C 스타일 문자열 (의 첫 번째 문자)에 대한 포인터로 std::cout취급 char *하고 인쇄하기 때문입니다. 대신 주소 를 원하면 다음과 같이 처리 되지 않는 포인터로 캐스트 할 수 있습니다 .

cout << (void *) terry;

(또는 const void *이 특별한 경우에 문제가되지 않는 constness를 버리는 것에 대해 걱정한다면 캐스트를 사용하십시오 ).


실용 주의자보다 순수 주의자라면 다음 static_cast과 같이 C ++를 사용할 수도 있습니다 .

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

이 특별한 경우에는 불필요하지만 a에 대한 캐스트 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;
}

출력 (사용자 환경에 따라 주소가 다를 수 있음) :

hello
0x8048870
0x8048870
0x8048870

를 사용하여 때를 참고 static_cast, 당신은 당신이 가진 const와 멀리 캐스팅하지 않도록해야한다 static_cast <void *>(무엇의 그 const_cast입니다). 이것은 최신 C ++ 캐스트가 수행하는 검사 중 하나이며 이전 스타일 캐스트에는 이러한 제한이 없습니다.


<<연산자 std::cout가 오버로드되었습니다. 동작은 오른쪽 피연산자의 유형에 따라 다릅니다. (실제로는 이름이 지정된 여러 가지 함수입니다 operator<<. 컴파일러가 호출 할 함수를 결정합니다.)

당신이 그것을 줄 경우 char*또는 const char*, 그것은 (의 첫 번째 문자) C 스타일 문자열 및 인쇄 해당 문자열의 내용에 대한 포인터로 연산을 처리합니다 :

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

당신이 그것에게주는 경우에 char값을, 그것은 문자로 그 값을 출력합니다 :

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

유형의 포인터를 제공하면 void*해당 포인터 값을 인쇄합니다 (일부 구현 정의 방식, 일반적으로 16 진수).

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

치료 char*또는 const char*C 스타일 문자열에 대한 포인터로하는 것은 특별한 경우이며, 유일한 (내가 생각할 수) 원인 것을 operator<<피연산자의 값이 아닌 다른 뭔가를 인쇄합니다. 그 이유는 "문자열"유형이없고 char*포인터 를 통해 문자열을 조작하는 C에서 C ++의 뿌리로 거슬러 올라갑니다 .

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


코드를 다음과 같이 변경해야합니다.

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

문제는 <<연산자가 문자열의 내용을 인쇄하기 위해 C 스타일 문자열에 대한 포인터에 오버로드 된다는 것 입니다. 대신 원시 포인터로 캐스트하면 원하는대로 iostreams를 사용하여 포인터를 인쇄하는 기본 동작을 갖게됩니다.


std::cout이 정의 std::ostream같이 정의 operator<<됩니다.

특히이 줄 :

template< class CharT, class Traits >
basic_ostream<CharT,Traits>& operator<<( basic_ostream<CharT,Traits>& os,
                                     const char* s );

이것은 <<유형의 인수와 함께 사용할 때 선택됩니다 char*.

문자가 아닌 다른 포인터 유형의 경우는 다음과 같습니다.

basic_ostream& operator<<( const void* value );

This continues to std::num_put which is made for formatting numeric values. Therefore, the pointer is interepreted numerically like %p in C formatting functions.


cout is overloaded so that when you give it a char*, it will print as a pointer to a C-style string. So, it prints out the characters until it hits a null terminating character.

If you used printf instead of cout, you would see the address. You could also cast the pointer to another type, say (void*) and you would also get the address.


"hello" is a string, i.e. the char array. const char* is a pointer to this array, so when you dereference this pointer, you get the value of the first element.

It is like if you have

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

you get just 1 printed.

ReferenceURL : https://stackoverflow.com/questions/17813423/cout-with-char-argument-prints-string-not-pointer-value

반응형