함수 포인터 C++ 자습서 39

함수 포인터 C++

함수 포인터는 포인터의 방식으로 함수를 호출하는 것 입니다. 함수를 기계적으로 들여다 보면 실행 코드 입니다. 함수의 지역변수에는 데이터도 들어 있지만 함수를 시작하는 것은 명령어 코드입니다. 이 명령어 코드가 있는 곳은 메모리 주소입니다. 포인터는 메모리 주소에 접근할 수 있으므로 포인터로 함수를 사용하는 것은 어떻게 보면 당연합니다. C++ 뿐만 아니라 포인터를 사용하지 않는 다른 많은 언어들도 비슷한 방식으로 함수를 사용할 수 있습니다.

여기서는 C++의 함수 포인터 사용법을 알아보겠습니다.

함수 포인터 예제

아래 예제에서는 파일 포인터를 사용합니다. 함수의 원형에서 이름 부분을 파일 포인터로 선언합니다. void function(string) 에서 function 을 (*ptr) 로 바꾼 후에 ptr=sayHello 로 대입합니다. 사용할 때는 ptr(string)의 형식으로 사용합니다. 함수에 ( ) 이 괄호가 있고 없고가 중요한데요. 함수 이름도 배열처럼 그냥 사용하면 메모리의 주소를 지시하기 때문입니다. 위에서 함수는 코드가 저장된 메모리의 주소라고 했습니다. 그 주소에서 ( ) 괄호를 더하면 실행하라는 의미를 갖습니다.

sayHello 라는 이름으로 함수를 사용할 수 있지만 함수 포인터를 사용해서 ptr의 이름으로도 사용할 수 있습니다.

#include<iostream>
#include<string>

    using std::cout;
    using std::endl;
    using std::string;

void sayHello(string name);
void (*ptr)(string);

int main()
{
    sayHello("Mr.Park");
    ptr=sayHello;

    ptr("Ms.Ko");

    return 0;
}

void sayHello(string name)
{
    cout <<"Hello, "<<name<<"!"<< endl;

}

[실행결과]

Hello, Mr.Park!
Hello, Ms.Ko!

C++을 학습하다 보면 이런 C++의 심오한 설계에 놀라게 됩니다. 함수는 실행코드가 저장된 메모리의 주소이다. 그래서 포인터로도 함수를 호출할 수 있고 심지어 함수의 주소를 또 다른 함수의 매개변수로 전달할 수도 있습니다.

아래의 예제는 함수 포인터를 받아서 함수 내부에서 포인터로 함수를 호출합니다. 이 방식을 사용하면 함수를 호출하는 함수를 만들 수 있습니다. 이 경우 함수 포인터는 원본 함수와 리턴타입, 매개변수(시그니쳐)가 같아야 합니다.

#include<iostream>
#include<string>

    using std::cout;
    using std::endl;
    using std::string;

void sayHello(string name);
void myFunction(void (*ptr)(string), string);

int main()
{
    myFunction(sayHello, "Mr.Lee");

    return 0;
}

void sayHello(string name)
{
    cout <<"Hello, "<<name<<"!"<< endl;
}
void myFunction(void (*ptr)(string),string name)
{
    ptr(name);
}

[실행결과]

Hello, Mr.Lee!

요약

함수 포인터는 문법이 많이 어렵습니다. 아직 학습 단계에서는 너무 깊이 있게 들어가면 미궁처럼 되버리니까 이런 개념이 있다는 정도를 이해하고 추후 중급 주제를 다룰 때에 한층 더 깊이 들어가는 것이 좋습니다. 또 C++은 객체 지향 프로그래밍 언어이므로 일단은 클래스 위주로 프로그램을 설계하는게 권장됩니다. C++에서 배우는 주제의 상당수가 전통 C언어의 영역이므로 적당히 구분을 해가면서 학습할 필요가 있습니다. 원래는 C언어를 마스터한 다음에 C++을 배우는게 정석이긴 한데 그러기엔 시간이 너무 많이 소요되기 때문에 시대적으로는 스피디 하게 학습할 필요도 있습니다. 지금은 대학의 컴퓨터 전공에서도 C언어를 컴퓨터 개론 수업에 사용하지 않는 경우가 많아져서 약간은 개인의 선택 문제이기도 합니다.

개인적으로 좋은 언어학습의 조합으로 보면 리눅스 환경의 C++ 11을 6개월~1년 정도에 완료할 수 있는 기초 코스를 진행하면서 웹 계열(HTML, 자바스크립트, 노드JS 나 리액트)을 함께 학습한다면 시너지가 좋을 것 입니다.

백엔드는 자바도 좋은데 자바는 객체 지향에서 C++과 유사한 부분도 많고 어차피 응용 프로그래머라면 웹도 같이 해야 하기 때문에 조금 아쉬운 부분이 있습니다. 모든 언어를 마스터하는 것은 불가능하기 때문에 주력 언어를 선택을 해야 하는 순간이 옵니다. 개인적으로는 C++과 자바스크립트 쪽이 좋다고 보지만 또 하다보면 나날이 인기가 높아지는 파이썬을 무시하기가 힘들지요. 요새는 컴퓨터가 메인이 아닌 일반인들도 파이썬을 하는 시대기 때문에 프로그래머가 파이썬을 못한다면 약간 쪽팔린 부분이 있을 겁니다. 그렇지만 C++을 1년 정도 배웠다면 파이썬은 한 일주일? 빠르면 하루에도 많이 적응할 수 있을 겁니다. C++은 스킬이 아니라 원리적인 부분을 탐구해야 진도가 나가기 때문에 그 원리 위에서 돌아가는 가상머신을 채용한 동적 타이핑 언어들은 별로 어렵지 않습니다. 원리를 체득하는게 중요합니다.

그렇다고 C++ 만이 진리라고 이야기하는게 아닙니다. C의 원리 운영체제 이런 거 잘 몰라도 해외에서는 10년 동안 파이썬 프로그래머로 잘 사는 사람들이 많습니다. 파이썬은 고수준 언어로써 거기에는 또 다른 차원이 있습니다. 파이썬의 철학은 Python Zen 에 나타나 있지만 기본적으로 비전공자 들이 활용하기 좋은 언어입니다. 예를 들어서 통계학자나 물리학자 같은 과학도들이 컴퓨터 전공자들보다 파이썬을 더 잘 활용할 수 있습니다. 그들이 가진 과학적 지식을 컴퓨터 구조나 운영체체론 같이 어렵고 지루한 수업을 듣지 않아도 얼마든지 활용할 수 있게 해주는게 파이썬이라고 할 수 있습니다. 아주 좋을 일이지요. 그런데 컴퓨터 자체를 포커스로 하는 전공자들은 그렇게 되면 뭔가 밥그릇을 넘겨준 기분이 들긴 하지요. 약간 속 좁은 생각일 수도 있는데 그렇다 하더라도 컴퓨터 메이저들은 적어도 다른 전공 보다 좀 더 많이 알것이다 라는게 사회적인 생각입니다. 마치 변호사가 일반인보다 법을 더 잘 알것이라고 기대하는 것과 비슷합니다. 그런 부분을 충족시켜주는 것은 역시 C++ 이지요.

이것은 학벌이나 전공에 많은 신경을 쓰는 한국만의 문제는 아니라고 합니다. Quora 의 질문답변들 중에는 영어권에서 C++ 커뮤니티와 자바 커뮤니티와의 신경전 등 이 언어 베이스에 대한 어떤 지식의 차이에 따른 논쟁이 많습니다. 뭐 항상 나오는 것들 중에는 프로그래머가 전통 C계열이냐 자바 계열이냐 혹은 리눅스 서버 관리자이냐 윈도우 서버 계열이냐 간단한 질문 같지만 핵심적인 늬앙스가 있습니다. 그런면에서 C++을 적어도 기초 정도 마스터 한다면 내가 지식적으로 무장할 수 있는 좋은 언어이다. 그렇게 생각합니다. 이런 논쟁은 지금까지 수십년 동안 있어왔고 앞으로도 계속 될 것이라 봅니다. 왜냐하면 추상화에 기반한 가상화 기술은 계속 진화할 것이기 때문입니다. 사실 컴퓨터의 역사는 이 추상화와 가상화 레벨의 업그레이드 역사입니다. 이에 대해서는 앤드류 타넨바움 교수의 운영체체론에서 잘 설명이 되어 있습니다.

웬지 C++ 포스팅이 30개를 넘어가고 부터는 본문 내용보다 잡설이 더 길어지고 있습니다. 어차피 C++은 멘탈 싸움이라서 포기 하지 않고 매일 조금씩 배우다 보면 다 할 수 있게 됩니다. 기간이 좀 걸릴 뿐 입니다.

계속 말하는데 C++은 어려운 언어입니다. 많은 사람들이 배우려 하다가 중간에 포기하고 다른 언어로 갈아타기도 합니다. 멘탈이 갈려나가기 때문에 이 언어에 대해 좋지 않은 경험을 가진 사람도 많이 있습니다. 컴퓨터 자체를 이해한다는 생각을 갖지 않으면 C++은 하기 힘듭니다. 그리고 빌 게이츠나 리누스 토발즈 같은 천재가 아닌 보통 사람이 컴퓨터를 이해하는 것은 시간이 꽤 오래 걸리는 일 입니다. 하지만 컴퓨터를 진정 사랑하는 사람에게는 엄청 가치 있는 언어입니다. 뭐 사람에 따라 리누스 처럼 C언어를 더 좋아할 수도 있고 아니면 C++을 더 좋아할 수도 있겠지만 그 정도 수준까지 올라가면 더 많은 것들이 보일 것 입니다. 거인의 어깨에 오를 테니까요. 잡설이 길어져서 여기까지 해야겠습니다.

참고문서

함수(C++) | Microsoft Docs

Leave a Comment