C++ 포인터 값 복사 - C++ pointeo gabs bogsa

우선 문자열 배열을 만들어야겠죠?

char s1{256]

char s2{256]

s1배열을 s2로 복사하기위해 포인터를 만들어줍니다.

char *from, *to;

from과 to라는 포인터를 만들어줬습니다.

다음으로 할 일은 포인터와 문자열을 연결시켜주는 일입니다.

from = s1;

to = s2;

이런식으로 하면 각각의 포인터들이 배열에 연결됩니다.

문자열을 입력받을껀데 gets함수를 사용해서 입력받습니다.

gets_s(s1);  이렇게 하면 엔터를 칠 때까지 문자열들이 s1배열에 모두 들어갑니다.

마지막으로 복사만 해주면 끝납니다.

while 문을 써서 복사를 해봅시다.

while(*from !='\0')    //*from 과 '\0' 가 다르면 참, 그렇지 않으면 거짓 즉 NULL까지 가면 while문 종료

{

*to++ = *from++;

}

*to = '\0';

여기서 '\0'은 쓰레기값 NULL을 말합니다.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

#include <stdio.h>

#include <string.h>

int main(void)

{

char s1[256];

char s2[256];

char*from, *to;

from = s1;

to = s2;

printf("문자열을 입력하세요 : ");

gets_s(s1);

printf("\n");

while (*from != '\0') {    //*from 과 '\0' 가 다르면 참, 그렇지 않으면 거짓

*to++ = *from++;

}

*to = '\0';

printf("입력된 문자열 %s  \n", s1);

printf("복사된 문자열 %s  \n", s2);

return 0;

}

cs


지난시간에 문자열 복사 함수 strcpy()에 대해서 post를 작성한 적이 있습니다. 그리고 이 함수이 동작 원리를 이해하고 유사한 동작을 수행하도록 사용자정의함수를 구현까지 했었죠. 이번에는 포인터와 관련하여 이 함수에 대해 알아보도록 합시다.

1. 포인트 변수


포인트 변수 표현은 다음과 같습니다.

char *str1;

위와 같이 표현하면 메모리 할당이 안된 상태로 변수가 선언 됩니다. 아직 할당 된 주소지를 갖고 있지 않습니다.

포인트(*)은 가리키다라는 의미를 갖고 있습니다. 즉, str1이라는 변수에 들어 있는 값을 가리킨다라고 이해하시변 됩니다. str1에는 주소지 값이 저장되어 있고 그 저장된 주소값을 포인트(*)로 가리킨다라고 생각하면 됩니다.

char *str1 ="Hello World!";

위와 같이 표현하면 문자열을 포인터변수에 저장하게 되고 저장된 순간 메모리에 할당이 됩니다. 특정 주소지에 해당 문자열이 저장되는 것이죠.

방금전 str1변수에는 주소지값이 저장된다고 했죠. 그러면 "Hello World!"라는 문자열은 어디에 저장되는 거야! 하고 의문을 가질 수 있을 거에요. 해당 문자열은 str1에 변수에 저장된 주소지값이 가리키는 곳에 문자열이 저장됩니다.

쉽게 이해하려면 실제로 실행 시켜서 눈으로 확인 해보면 됩니다. 바로 설명을 드리는 것보다 실행을 시켜보는 것이 좋겠죠.

[코딩]

#include <stdio.h>
#include <string.h>

int main()
{
    char *str1="Hello World!";
    int i;
    
    for(i=0;i<strlen(str1);i++){
        printf("str1[%d]주소 : %d , 문자열 : %c\n",i, str1+i, str1[i]);
        
    }
    
    return 0;
}

[결과]

C++ 포인터 값 복사 - C++ pointeo gabs bogsa

위 실행 결과를 보시는 것처럼 str[0]번째 위치에 주소 4195904 이라는 값이 저장됩니다. 그리고 포인터(*)가 그 주소지를 가리킨다고 했죠. 4195904 라는 주소지에 실제 'H'라는 값이 저장됩니다. 그러니깐 한다리 건너 문자열이 저장된다고 보면 됩니다.

그냥 일반변수에 해당 문자열을 저장하면 되는데 왜! 번거롭에 한다리 건너 저장시키냐고 생각하실 수 있습니다.

그이유는 포인트변수를 쓰는 목적에 있습니다. 포인트 변수는 프로그램이 처음 실행 할 때 메모리에 바로 할당되는 것이 아니라 실행 가운데 메모리에 할당을 시키기도 하고 해제시키기를 할 수 있는 변수입니다. 즉, 메모리 관리에 효율적인 변수인 것이죠. 일반변수로 모든 변수를 만들고 할당한다면 해당 프로그램은 처음 실행할 때 엄청난 메모리 공간을 차지하고 현재 쓰지도 않는 공간까지 차지하게 됩니다. 이러면 정말 비효율적이겠죠.

더 쉽게 비유를 든다면 게임을 할 때 처음에는 렉없이 메모리도 별로 차지하지 않고 플레이하다가 어느순간 렉이 발생하고 메모리관리창 보면 사용된 메모리가 엄청 늘어난 것을 보실 수 있을 거에요. 즉, 게임 속 여러가지 변수들이 사용되고 할당되고 해제가 제대로 되지 않고 누적되어 쌓여 메모리를 잡아 먹고 있는 현상들이죠. 물론 순간 그 공간의 처리량이 많아서 렉이 발생하는 경우도 있긴 하지만 그렇지 않는 경우는 할당과 해제가 효율적으로 이루어지지 않고 누적되는 현상으로 보시면 됩니다. 게임을 하다가 렉이 발생하면 컴퓨터관리자에서 해당 게임의 메모리 사용률을 보시면 확인하실 수 있을 거에요.

이처럼 포인터 변수는 메모리 관리하는데 유용한 변수입니다. 현재는 8기가 16기가 32기가 메모리를 쓰면 메모리에 대해 깊이 생각안하는 시대가 되었지만 초창기 PC들은 메모리가 지금과 비교도 안되게 저용량이라서 조그마한 프로그램을 돌려서 메모리가 꽉차는 시대가 있었습니다. 그때는 메모리 관리가 선택이 아닌 필수인 시대였지요. 하드웨어 발전이 메모리 관리에 무감각한 시대가 되었네요.

삼천포로 이야기가 빠졌는데 다시 정리하면

str1 => 4195904 => 'H'

이렇게 str1에는 주소값이 들어 있고 포인터(*)로 그 주소지를 가리켜 'H'를 저장합니다.

2. strcpy()함수 내 포인트


char *strcpy(char *dest, const char *src)

함수는 위와 같이 표현이 됩니다. dest에는 str의 문자열이 저장되고 문자열을 복사하면 리턴값으로 문자열을 반환하게 됩니다.

즉,

char *strcpy(char *dest, const char *src){
   
   생략

  return 문자열;

}

이렇게 말이죠. 참고로 반환값은 dest 변수를 반환합니다. 오늘 post를 쓴 이유가 바로 이것이죠. 포인트변수를 사용하면 반환된 변수의 주소지를 던저주게 되고 그 주소지를 공유하게 됩니다. 그걸 살펴보기 위한 코딩입니다.

[예제]

#include <stdio.h>
#include <string.h>

int main()
{
    char *str1="Hello World!";
    char str2[20];
    char *str3;
    str3=strcpy(str2,str1);
    
    printf("str1시작주소 : %d , 문자열 : %s\n",str1, str1);
    printf("str2시작주소 : %d , 문자열 : %s\n",str2, str2);
    printf("str3시작주소 : %d , 문자열 : %s\n",str3, str3);    
    return 0;
}

위 코딩은 각 문자열 변수의 주소지를 비교하세요.

[결과]

C++ 포인터 값 복사 - C++ pointeo gabs bogsa

보시면 str2의 반환된 값이 str3로 넘겨주게 되는데 이때 주소지값을 넘겨 주게 되어 같은 주소지를 갖게 됩니다.
여기서 str2는 왜 배열변수로 했는지! 그냥 포인트변수로 하면 안되는지 궁금하실 수 있는데 해보시면 에러가 뜹니다. 참고로 인자는 고정된 확실한 값을 넘겨줘야지 모호한 값을 받을 수 없습니다. 그냥 포인터변수로만 선언하고 넘겨주면 아직 메모리 할당이 안된 상태로 변수를 인자로 넘길 수 없습니다. str1은 문자열이 저장됨으로 메모리가 할당되었기에 그 주소지를 넘겨주지지 str2는 아직 할당되지 않았기에 주소지를 넘겨줄 수 없다고 생각하시면 됩니다.

마무리


아무튼 오늘 핵심은 반환변수가 포인터로 반환하면 그 주소값을 넘겨주고 변수의 주소지는 반환 받는 포인터 변수의 주소지로 넘겨 받아 같은 주소지를 공유하게 된다는 것을 이해하시면 됩니다.


Sponsored ( Powered by dclick )

C++ 포인터 값 복사 - C++ pointeo gabs bogsa