티스토리 뷰

Chapter 12.

 

저자는 이 챕터에서 기본적인 함수 관련 문법, 메모리의 동적 할당 및 해제에 알고 있는 상태에서 논할 수 있는 함수에 대한 이론들을 다룬다.

 

 

12.1 매개변수 전달 방법

 

두 함수가 호출 / 피호출 관계로 묵이는 것을 바인딩(binding)이라고 한다. 그리고 함수 호출 과정에서 매개변수로 전달되는 정보가 무엇이냐에 따라 매겨변수 전달방법이 달라진다.

 

기본적으로 매개 변수 전달 방법은 값이냐 주소냐에 따라,

 

  1. Call by Value
  2. Call by Reference

12.1.1 Call by value

Call by value는 간단하므로 하나의 예제를 통해 설명하도록 하겠다.

#include<stdio.h>

int Add(int a, int b){
    return a + b;
}

int main(int argc, char* argv[]){
    printf("%d\n", Add(3, 4));
    return 0;
}

 

12.1.2 Call by reference

Call by reference의 핵심은 매개변수가 포인터라는 점이다.

 

따라서, 호출자는 반드시 메모리의 '주소'를 인수로 넘겨야 한다. 그리고 피호출자 함수는 이 매개변수를 간접지정함으로써 포인터가 가리키는 대상에 접근할 수 있다.

#include<stdio.h>

//매개 변수가 int *인 함수의 선언 및 정의
int Add(int *a, int *b){
    return *a + *b;
}

int main(void){
    int x = 3, y = 4;
    
    //Add( ) 함수를 호출할 떄 지역변수의 주소를 실인수로 기술.
    printf("%d\n", Add(&x, &y));
    return 0;
}

 

Call by reference와 Call by value의 차이점 

 

  1. 주소를 통해 호출자 메모리에 접근할 수 있는 방법을 제시함으로써 두 함수가 강력하게 결합될 수 있다.
  2. 배열처럼 덩치가 큰 메모리를 매개변수로 전달 할 수 있다.
#include<stdio.h>

// 배열 실인수는 '포인터' 매개변수로 받는다.
// 포인터에는 요소의 개수 정보가 없으므로 int 매개변수가 더 필요하다.
// 만일 입력받아야 할 정수의 개수가 달라져도 이 함수 코드는 변하지 않는다!
void InitList(int *pList, int nSize){
    int i = 0;
    for(i = 0; i < nSize; i++){
        printf("정수를 입력하세요 : ");
        scanf("%d", &pList[i]);
    }
}

// 요소가 int 형식인 배열이라면 요소의 개수와 상관없이 정렬할 수 있다.
void SortList(int *pList, int nSize){
    int i = 0, j = 0, nTemp = 0;
    
    for (i = 0; i < nSize - 1; i++)
        for(j = i + 1; j < nSize; j++){
            if (pList[i] > pList[j]){
                nTemp = pList[j];
                pList[j] = pList[i];
                pList[i] = nTemp;
            }
        }
}

void PrintList(int *pList, int nSize){
    int i = 0;
    for (i = 0; i < nSize; i++)
        printf("%d\t", pList[i]);
    putchar('\n');
}

int main(void){
    //자료구조를 지역변수로 선언했기 때문에
    //다른 함수에서는 직접 접근할 수 없다.
    int aList[5] = {0};
    
    InitList(aList, 5);
    SortList(aList, 5);
    PrintList(aList, 5);
    return 0;
}

 

 

피호출자 함수가 동적으로 할당한 메모리를 호출자 함수에서 해제하는 예제.

#include<stdio.h>
#include<stdlib.h>

//주소를 반환하는 사용자 정의 함수 선언 및 정의.
char *GetName(void){
    char *pszName = NULL;
    
    //메모리를 동적 할당시킨다.
    pszName = (char*)calloc(32, sizeof(char));
    printf("이름을 입력하세요 : ");
    
    //동적 할당한 메모리에 사용자가 입력한 문자열을 저장한다.
    gets_s(pszName, sizeof(char) * 32);
    //동적 할당한 메모리의 주소를 호출자 함수에 반환한다.
    return pszName;
}

int main(int argc, char* argv[]){
    char *pszName = NULL;
    
    //이름이 저장된 동적 할당된 메모리의 주소를 반환받는다.
    pszName = GetName();
    printf("당신의 이름은 %s입니다.\n", pszName);
    
    //호출자 함수가 메모리를 해제해야 한다.
    free(pszName);
    return 0;
}

 

문자열을 복사하는 함수.

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

int myStrCopy(char *pszDst, int nSize, const char *pszSrc){
    
    int nLenSrc = strlen(pszSrc), i = 0;
    
    if(nLenSrc + 1 > nSize){
        return nSize - (nLenSrc + 1);
    }
    
    while (pszSrc[i] != NULL){
        pszDst[i] = pszSrc[i];
        i++;
    }
    
    pszDst[i] = '\0';
    return nLenSrc;
}


int main(int argc, char* argv[]){
    char szBuffer[12] = {"TestString"};
    char szBufferDst[12] = {0};
    
    myStrCopy(szBufferDst, sizeof(szBufferDst), szBuffer);
    puts(szBufferDst);
    return 0;
}

 

복사할 문자열의 크기가 복사 받을 문자열의 크기보다 크다면 음수 반환

 

아니라면, 크기 반환

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
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
26 27 28 29 30 31
글 보관함