함수, 주소전달

이윤설·2024년 6월 19일

흥달쌤 C언어 특강

목록 보기
8/10

함수

간단한 예제

#include <stdio.h>

// 간단한 함수 정의
int add(int a, int b) {
    return a + b;
}

int main() {
    int num1 = 10;
    int num2 = 20;
    int result;

    // 함수 호출
    result = add(num1, num2);

    // 결과 출력
    printf("The sum of %d and %d is %d\n", num1, num2, result);

    return 0;
}

살짝 어려운 예제

#include <stdio.h>

void swap(int *x, int *y) {
    int temp = *x;
    *x = *y;
    *y = temp;
}

int main() {
    int a = 5;
    int b = 10;
    
    printf("Before swapping: a = %d, b = %d\n", a, b);
    swap(&a, &b); // 변수의 주소를 전달
    printf("After swapping: a = %d, b = %d\n", a, b); // a와 b의 값이 변경됨

    return 0;
}

함수에 주소 전달

call by value 글을 참고하세용

함수가 주소 전달

#include <stdio.h>

// 두 정수의 합을 계산하고 결과를 포인터를 통해 반환하는 함수
void add(int a, int b, int *result) {
    *result = a + b;
}

int main() {
    int num1 = 10;
    int num2 = 20;
    int sum;

    // add 함수 호출
    add(num1, num2, &sum);

    // 결과 출력
    printf("The sum of %d and %d is %d\n", num1, num2, sum);

    return 0;
}

// 출력
The sum of 10 and 20 is 30
  • a와 b의 합을 계산하여 result가 가리키는 메모리 위치에 저장한다.
  • add 함수를 호출할 때 num1과 num2를 값으로 전달하고, sum의 주소를 전달하여 result 포인터가 sum 변수를 가리키게 한다.
  • 함수 호출 후, sum 변수에 결과가 저장되어 출력된다.

*와 &

  • *sum
    *연산자는 "역참조 연산자"라고 불리며, 포인터가 가리키는 메모리 주소에 저장된 값을 반환한다. 즉, *sum은 포인터 sum이 가리키는 위치에 저장된 값을 나타낸다.
#include <stdio.h>

int main() {
    int sum = 42;
    int *ptr = &sum;  // sum의 주소를 포인터 변수 ptr에 저장
    printf("Value of sum using pointer: %d\n", *ptr);  // ptr이 가리키는 값을 출력
    return 0;
}
  • &sum
    & 연산자는 "주소 연산자"라고 불리며, 변수의 메모리 주소를 반환한다.
    즉, &sum은 변수 sum의 메모리 주소를 나타낸다.
#include <stdio.h>

int main() {
    int sum = 42;
    printf("Address of sum: %p\n", (void*)&sum);  // sum의 메모리 주소를 출력
    return 0;
}

포인터 변수, *와 &

#include <stdio.h>

int main() {
    int var = 10;        // 정수형 변수 선언 및 초기화
    int *ptr = &var;     // 포인터 변수 선언 및 var의 주소로 초기화

    // var의 값 출력
    printf("Value of var: %d\n", var);

    // var의 주소 출력
    printf("Address of var (&var): %p\n", (void*)&var);

    // ptr의 값 (var의 주소) 출력
    printf("Value of ptr (address of var): %p\n", (void*)ptr);

    // ptr이 가리키는 값 (var의 값) 출력
    printf("Value pointed to by ptr (*ptr): %d\n", *ptr);

    // ptr을 사용하여 var의 값 변경
    *ptr = 20;

    // 변경 후 var의 값 출력
    printf("New value of var: %d\n", var);

    // ptr의 값 (주소) 출력
    printf("Value of ptr (address of var): %p\n", (void*)ptr);

    // ptr이 가리키는 값 출력
    printf("Value pointed to by ptr (*ptr): %d\n", *ptr);

    return 0;
}

// 출력값
Value of var: 10
Address of var (&var): 0x7ffee5bff56c
Value of ptr (address of var): 0x7ffee5bff56c
Value pointed to by ptr (*ptr): 10
New value of var: 20
Value of ptr (address of var): 0x7ffee5bff56c
Value pointed to by ptr (*ptr): 20

포인터 변수, *와 & 2

  1. 대부분의 경우, 포인터 변수의 값은 주소이고, 값이 아직 초기화되지 않았거나(이때는 쓰레기값이 들어감) null인 경우는 예외다.
  2. 포인터 변수에 *를 붙이면 포인터 변수의 값이다.
  3. 포인터 변수의 값이 주소라고 가정했을 때, 포인터 변수에 &를 붙였을 때의 주소와 1번에서의 주소는 서로 같을까?

포인터 변수에 &를 붙이면 포인터 변수 자체의 주소를 의미한다.
ptr이 가리키는 주소(1번의 주소)는 ptr 자체의 주소(&ptr)와 다르다.

  var
  -----
 | 10  |  <---- var의 값
  -----
  0x100   <---- var의 주소 (&var)

  ptr
  -----
 | 0x100 |  <---- ptr의 값 (var의 주소)
  -----
  0x104   <---- ptr의 주소 (&ptr)

매개변수 타입 호환

#include <stdio.h>

// 두 정수의 합을 계산하고 결과를 포인터를 통해 반환하는 함수
void add(int a, int b, int *result) {
    *result = a + b;
}

int main() {
    int num1 = 10;
    int num2 = 20;
    int sum = 0;

    // add 함수에 변수의 주소를 전달
    // &sum: 100번지라고 가정한다.
    add(num1, num2, &sum);

    // 결과 출력
    printf("The sum of %d and %d is %d\n", num1, num2, sum);

    return 0;
}

add()는 *result를 요구하는데 &sum을 보내고있다.
서로 타입이 다른데 어떻게 가능한걸까?

int result에서 는 포인터 연산자이며, 이는 result가 포인터 변수임을 나타낸다. 타입이 int이므로 *result는 "정수를 가리키는 포인터"라는 의미이다.

&sum은 sum 변수의 메모리 주소를 나타내는 표현식이다.
sum은 int 타입 변수이므로, &sum은 정수를 가리키는 메모리 주소를 반환한다.

그래서 add(num1, num2, &sum); 호출 시, &sum은 int 타입 데이터의 메모리 주소이므로 int *result에 전달할 수 있다. 타입이 일치하는 것이다.

즉, int *result는 정수를 가리키는 포인터 변수를 요구하고, &sum은 정수 sum의 메모리 주소를 제공하므로 타입이 호환된다.

그냥 둘은 호환된다고 외우는게 편하다.

profile
화려한 외면이 아닌 단단한 내면

0개의 댓글