언어 자료구조 알고리즘/Escort C++

[C++] 1. 2 클래스를 제외한 C언어와 다른 문법 사항 (const 포인터, void 포인터)

언제나휴일 2016. 4. 15. 11:55
반응형

- const 포인터

 

 함수를 호출할 때 호출부에서 전달하는 문자열을 피 호출 함수에서 변경하지 않기를 기대할 수가 있습니다. strcpy 함수의 원본 문자열이나 strcmp 함수에 전달되는 문자열은 해당 함수 내부에서 변경하지 말아야 합니다. 이 같은 경우에 const 포인터를 사용하여 입력 매개 변수를 약속하게 됩니다. const 포인터로 입력 매개 변수를 약속하는 것은 해당 함수를 호출하면 전달된 메모리 주소에 있는 값을 변경하지 않겠다는 약속이기 때문에 신뢰하고 사용할 수 있습니다. 그런데 C언어에서는 이처럼 약속하고서 실제 피 호출 함수 내부에서 전달받은 메모리 주소에 있는 값을 변경하는 구문을 사용하더라도 컴파일 오류를 발생하지 않고 경고만 발생합니다. C++ 언어에서는 이럴 때 컴파일 오류를 발생함으로써 개발자로 하여금 약속에 어긋난 코드를 피할 수 있게 도와줍니다.

 

 [그림 1.2] const char *로 매개 변수를 정하고 함수 내부에서 이를 char *형 변수 p에 대입하여 이를 통해 값을 바꾸고자 시도하는 코드입니다. p char *형 변수는 해당 주소에 있는 값을 바꿀 수 있는 형식이기 때문에 const char *로 약속한 입력 매개 변수 str을 대입을 하면 이후 p를 이용하여 값을 바꾸었을 때 약속에 위배되게 됩니다. C++ 언어에서는 이럴 때 컴파일 오류를 발생시킴으로써 약속 위배를 막아줍니다.


const char *에서 char *로 변환할 수 없습니다.

[그림 1.2]

 

- void 포인터

 

 void 포인터 형식의 변수는 선언 시에 원소 형식을 명시하지 않고 코드 상에서 어떠한 형식의 포인터도 받을 수 있는 형식입니다. 하지만 반대로 void 포인터 변수의 값을 일반(void 포인터형이 아닌) 포인터 변수에 대입할 경우 그 이후에 간접 연산자에 의해 모순된 작업이 될 개연성이 있습니다.

 

 다음은 C언어로 작성된 코드입니다. 의도적으로 char형을 원소로 하는 배열을 선언하고 배열명을 void 포인터형 변수에 대입한 후 int 형 포인터 변수로 받았습니다. 그리고 int형 포인터 변수와 간접 연산을 통해 값을 바꾸었는데 과연 결과가 어떻게 될까요? [그림 1.3]을 살펴보시기 바랍니다.

 

demo.c - C에서는 컴파일 성공

#include <stdio.h>

void main()

{

    char arr[10]={1,2,3,4,5,6,7,8,9,10};

    void *pv = 0;

    int *pi = 0;

    int i = 0;

    pv = arr;

    pi = pv;

 

    *pi = 10;

    for(i=0; i<10; i++)

    {

        printf("arr[%d]: %d\n",i, arr[i]);

    }

}

 

[그림 1.3] 

 

 

 사용자가 배열을 선언할 때에는 char형을 원소로 하는 배열인데 이를 void 포인터 변수에 대입하여 일반적인 작업을 하는 코드 블록에서 원래 형식이 아닌 int 포인터형으로 잘못 사용하였을 때 C컴파일러는 경고는 발생하지만, 오류를 발생하지 않습니다. 사용자가 발생한 경고를 무시하더라도 컴파일은 성공하기 때문에 버그가 있는 프로그램이 작성되게 됩니다. C++에서는 [그림 1.4]를 보면 알 수 있듯이 이 같은 경우에 경고가 아닌 오류를 발생시켜 사용자로 하여금 코드를 수정할 수 있게 해 줍니다.


void *에서 int *로 변환할 수 없습니다.

[그림 1.4] 


*C11 표준을 따르는 컴파일러에서는 C언어에서도 오류가 발생합니다.


1장 C++ 들어가면서 동영상 보기

(모든 동영상 강의는 무료입니다.)

반응형