궁금증 연구소

오늘 포스팅 주제는 "포인터와 배열을 같이 쓸때 주의 할점" 임.

 

#include <stdio.h>
#include <mem.h>

int * getOdd(int *parr, int n, int *oddcnt);

main()
{
    int arr[10] = {4,5,1,2,5,6,7,8,10,13};
    int *pa, n;

    pa = getOdd(arr, 10, &n);
    for (int i=0; i<n; i++)
        printf("%4d", *(pa+i));
    
    delete[] pa;
}

int * getOdd(int *parr, int n, int *oddcnt){

    int *pa, *pb, i ;
    int cnt = 0;
    pa = new int[n];


    for(i=0; i<n; i++){
        if(parr[i] % 2 == 1){
            pa[ cnt++ ] = parr[i];    // *oddcnt++ 단항연산자 순서 는 오른쪽이 우선권이 있다. 따라서 갈호가 없으면 ++로 oddcnt 포인터값이 먼저 증가됨
        }
    }

    pb = new int[cnt];
    memcpy(pb, pa, cnt*sizeof(int) );
    delete[] pa;
    *oddcnt = cnt;

    return pb;
}

위 코드는 10개짜리 정수 배열에서 홀수만 뽑아서 리턴해주는 간단한 예제이다.  

 

for(i=0; i<n; i++){
        if(parr[i] % 2 == 1){
            pa[ cnt++ ] = parr[i];    // *oddcnt++ 단항연산자 순서 는 오른쪽이 우선권이 있다. 따라서 갈호가 없으면 ++로 oddcnt 포인터값이 먼저 증가됨
        }
    }

이 코드에서 조건문에 *parr 과 수식에 parr[i] 식을 혼합해서 쓰면 에러가 발생할 수 있다. 인덱스를 이용하는 방식은 포인터의 변화가 없기 때문에 가리키는 값의 변화가 없지만 *parr 값을 활용후 포인터 변경을 통해 값을 호출하는 방식은 포인터 때문에 지칭되는 값이 바뀌기 때문에, 나중에 이 값을 그대로 활용하면 에러가 발생한다.

 

 memcpy(pb, pa, cnt*sizeof(int) );
memcpy 에서 저장하는 것을 buff 대신 pb를 쓰면 증가된 pb의 값을 복사하게 되므로 조심해야 한다.
세번째 인수는 개수가 아니라 바이트수이므로, 바이트를 곱해주어야 한다.
이때 문자열의 경우는 영문의 경우 strlen(배열명)+1 로 바이트수를 구해줄수 있다.
 
 
strlen 글자수

 

strlen() 함수의 경우 한글은 2바이트로 계산되어  한글글자수가 10으로 나오고, 영문은 각 1바이트로 계산되어 공백을 포함해 총 바이트로 결과를 볼 수 있다. 즉 memcpy 의 경우 세번째 인자에 바이트를 인수로 받기 때문에 문자열의 바이트수를 넘길경우는 strlen+1 의 결과값을 넘기면 된다. 

 

글자수

 

반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading