[KOCW 한국산업기술대학교 박정민 교수님] C 프로그래밍 14강

MinWoo Park·2021년 8월 25일
0

KOCW

목록 보기
14/19
post-thumbnail

Part14 포인터와 함수 그리고 void형 포인터

14.1 값에 의한 호출과 주소에 의한 호출

값에 의한 호출(Call By Value): 변수(메모리 공간에 저장된 값) 또는 값을 복사해서 함수 호출

ex) 변수 a의 값 10으로 func(int i) 함수를 호출 => 값에 의한 호출

#include <stdio.h>
int func(int i);

void main()
{
    int a = 10;
    int result = 0;

    result = func(a);
    printf("%d \n", result);
    printf("%d \n", a);
}

int func(int i)
{
    i = i + 1;
    return i;
}

// 11 
// 10 

주소에 의한 호출(Call By Reference): 주소(메모리 공간의 주소)를 참조해서 함수 호출

ex) 변수 a의 주소, &a로 func(int* i) 함수 호출 => 주소에 의한 호출

#include <stdio.h>
int func(int *i);

void main()
{
    int a = 10;
    int result = 0;

    result = func(&a);
    printf("%d \n", result);
    printf("%d \n", a);
}

int func(int *i)
{
    *i = *i + 1;
    return *i;
}

// 11
// 11

14.2 주소를 반환하는 함수

주소 반환의 필요성과 주의 사항

  • 값에 의한 호출은 함수를 호출할 때 대량의 데이터를 전달하는 경우 매개 변수가 늘어나 스택에 쌓이는 많은 시간과 메모리 공간이 필요하지만 주소에 의한 호출은 실행 시간과 메모리 공간 측면에서 좋은 성능을 제공함.

  • 지역 변수를 반환하면 함수가 종료되면서 지역 변수는 소멸되기 때문에 경고가 발생
    ex)

#include <stdio.h>

int *input();

int main(void)
{
    int *p = NULL;
    p = input();
    printf("%d \n", *p);

    return 0;
}

int* input()
{
    int num1;
    scanf("%d", &num1);
    return &num1;
}


main() 함수에 인자가 있을 때

main() 함수도 인자를 받을 수 있다.
int argc와 char* argv[]로 확인할 수 있는데 이는 문자열 수를 저장하고, 문자열의 첫 번째 주소를 저장하는 인자다.

ex)

#include <stdio.h>

int main(int argc, char* argv[]) // int argc: 문자열 수를 저장, char* argv[]: 문자열의 첫 번째 주소를 저장
{
    int i = 0;
    printf("문자열의 수: %d \n", argc);

    for (i = 0; i < argc; i++)
    {
        printf("%d번 째 문자열: %s \n", i, argv[i]);
    }

    return 0;
}

$ ./a.out Good morning C Language

/*
문자열의 수: 5 
argv[0]: ./a.out 
argv[1]: Good 
argv[2]: morning 
argv[3]: C 
argv[4]: Language 
*/

void형 포인터란

자료형에 제약을 받지 않고, 아무 자료형의 주소라도 저장할 수 있는 포인터 변수
아무 자료형의 주소를 저장할 수는 있지만 * 연산자로 값을 간접 접근할 수 없음
강제 형변환이 필요

ex)

#include <stdio.h>
int main(void)
{
    char c = 3;
    double d = 3.1;

    void *vx = NULL;

    vx = &c;
    printf("Address of vx: %x \n", vx);
    // printf("Value of vx: %d \n", *vx) // error
    printf("Value of vx: %d \n", *(char *)vx); // Force type change

    vx = &d;
    printf("Address of vx: %x \n", vx);
    // printf("Value of vx: %d \n", *vx) // error
    printf("Value of vx: %d \n", *(double *)vx); // Force type change

    return 0;
}

강제 형변환

*(char*) vx
  1. (char*): vx의 주소를 char형으로 강제 형변환
  2. 맨 앞의 * 연산자를 통해 강제 형변환된 주소에 저장된 값을 참조

Reference
강의: 박정민, 『C 프로그래밍』, KOCW 한국산업기술대학교, 14강
교재: 박정민, 『열혈강의 C 언어 본색 명강의가 일으키는 C 언어 기적』, 프리렉 (2011), p435-464.

profile
물음표를 느낌표로 바꾸는 순간을 사랑하는 개발자입니다.

0개의 댓글