[C++] char*의 출력 (cout, printf)

오사현·2024년 8월 24일

C++ 공부일지!

목록 보기
2/3
post-thumbnail

오늘도 문제가 생겼습니다.

#include <iostream>
using namespace std;

int main()
{
    char my_str[] = "Hello, World!";
    char *ptr = my_str;

    cout << ptr << endl;
    
    return 0;
}

해당 코드를 실행했을때 내 예상대로라면 char *ptr을 cout으로 출력하면 my_str의 메모리 주소가 출력될 것 이라고 생각했지만...

Hello, Worl!

이런 깜찍한 친구가 출력되었습니다.
내가 알고있던 지식과는 다른 출력에 잠깐 얼을 타다 조사를 시작했습니다.

cout과 printf의 차이

일단 *ptrmy_str의 메모리 주소가 저장되는 것이 맞았습니다.
문제의 발생 원인은 cout이 char*를 문자열로 해석하기 때문이라고 합니다.

"그럼 printf로 출력하면 어떻게 될까"

cout이 char*를 문자열로 인식해 그런 것이라면 printf로 출력하면 될 것이라는 단순한 생각을 이행해보았습니다.

#include <iostream>
using namespace std;

int main()
{
    char my_str[] = "Hello, World!";
    char *ptr = my_str;

    cout << ptr << endl;
    printf("%#x", ptr+1);
    
    return 0;
}

출력결과는

Hello, World!
0x61fe0a

printf로 출력시 정상적으로 출력되는 모습을 보였습니다.
이유는 두 출력문의 포인터 해석의 차이 때문이였습니다.

printf의 출력

printf 같은 경우에는 포인터를 메모리 주소로 해석하여 출력합니다. 너무 당연한 이야기지만 cout은 그러지 못했습니다.

cout의 출력

cout같은 경우에는 포인터를 문자열로 해석합니다. 그렇기에 char*를 문자열로 해석해 이 포인터가 가리키는 문자열 전체를 출력하려 합니다. 즉 null이 나오기 전까지 말입니다.

다행히도 int*등 다른 타입의 포인터를 cout으로 출력하면 포인터가 가리키는 실제 값이 아니라 메모리 주소를 출력해줍니다.

왜 그런지 또 의문이 생기네요.

char* 와 int*의 차이

cout은 다양한 타입을 출력할 수 있도록 여러 버전의 << 연산자가 오버로딩 되어 있습니다. 이 덕분에 cout이 같은 << 연산자를 사용하더라도 다른 방식으로 처리할 수 있습니다!

여기서 잠깐! 오버로딩이란 하나의 이름을 가진 함수 또는 연산자가 서로 다른 방식으로 동작할 수 있도록 여러 번 정의하는 것을 뜻 합니다!

char*는 C 스타일 문자열을 가리키는 포인터로 간주됩니다.

C++에서는 cout<< 연산자가 char*에 대해 오버로딩되어 있습니다. 이 이 경우 char*는 단순한 메모리 주소로 취급되는 것이 아니라, 해당 주소가 가리키는 문자열을 출력하는 것으로 해석됩니다. 이때 cout은 포인터가 가리키는 위치부터 널('\0') 문자를 만날 때까지 문자열을 출력합니다.

오 신기하네요~ 그럼 제가 아래 코드를 실행시키면 o, World! 표가 출력된다는 것 같군요... 한번 실행해볼까요?

#include <iostream>
using namespace std;

int main()
{
    char my_str[] = "Hello, World!";
    char *ptr = my_str;

    cout << ptr + 4 << endl;
    
    return 0;
}

o, World!

이번에는 다행히 예상대로 출력되었네요!

핵심 요약!

  • printf와 cout의 포인터 해석법이 다른다.
    • printf는 포인터를 메모리 주소로 해석한다.
    • cout은 포인터를 문자열로 해석한다.
      • 이유는 cout의 << 연산자가 오버로딩 되어있기 떄문이다. 해당 이유 때문에 int*char*를 다르게 해석합니다.
      • char*같은 경우에는 c 스타일 문자열로 해석되어 null문자를 만날때까지 문자열을 출력합니다.

마무리

휴~ c++강의를 보던 중 배운 포인터가지고 놀아보다가 블로그 글까지 쓰게 되었네요. 그럼 저는 진도를 마저 빼보도록 하겠습니다. 글 읽어주셔서 감사드립니다!

profile
안녕하세요? 개발자를 희망하는 고등학생입니다! 잘부탁드립니다! (since 2024/08/24)

0개의 댓글