학이시습

[혼공C] 6주차_포인터 알아보기 본문

혼공학습단/혼공C

[혼공C] 6주차_포인터 알아보기

dbswndud 2024. 2. 15. 21:59

또혼공C 커리큘럼


Chapter 9

01. 포인터의 기본 개념

메모리의 주소

메모리는 우리가 데이터를 넣고 꺼내 쓰는 공간으로, 사용하기 위해 위치를 식별할 수 있어야 합니다.

사용하는 메모리의 위치는 주소 값으로 식별할 수 있습니다. 이 주소 값은 바이트 단위로 구분됩니다.

0부터 시작하고 바이트 단위로 1씩 증가하므로 2바이트 이상의 크기를 갖는 변수는 여러 개의 주소 값에 걸쳐 할당됩니다.

 

주소 연산자 : &

여기서 주소는 변수가 할당된 메모리의 시작 주소입니다.

주소는 주소 연산자 &를 사용해서 구합니다.

변수의 크기나 메모리에 할당되는 방식은 컴파일러와 운영체제에 따라 다를 수 있습니다.

 

포인터와 간접 참조 연산자 : *

포인터는 주소를 지정하는 변수로 일반 변수와 마찬가지로 선언 후에 사용합니다

포인터가 가리키는 변수를 사용할 때 간접 참조 연산자(*)를 사용합니다.

*pa		// *는 간접 참조 연산자, pa는 포인터

포인터가 어떤 변수를 가리키면 포인터로 가리키는 변수를 사용할 수 있습니다.

즉 포인터 pa로 변수 a를 사용할 수 있습니다.

 

const를 사용한 포인터

const 예약어를 포인터에 사용하면 이는 가리키는 변수의 값을 바꿀 수 없다는 의미로, 변수에 사용하는 것과는 다른 의미로 가집니다.

const 변수형 [포인터]

 

확인 문제

더보기

1. 다음 각 변수의 주소를 저장할 포인터를 선언하세요. 변수명은 p로 합니다.

① char ch; char *p
② int in; int *p
③ double db; double *p

 

2. 다음과 같이 변수가 초기화되고 메모리에 할당되었다고 가정하고 주소 연산자와 간접 참조 연산자를 사용한 수식의 결괏값을 적어보세요.

2번 문제

 

수식 &ch &in &db *&ch *&in *&db
결괏값 100 101 105 'A' 10 3.4

 

3. 다음 코드의 실행결과를 작성하세요.

int a = 10;
int *p = &a
*p = 20;
printf("%d", a);
20

 

02. 포인터 완전 정복을 위한 포인터 이해하기 

주소와 포인터의 차이

주소는 변수에 할당된 메모리 저장 공간의 시작 주소 값 자체이고, 포인터는 그 값을 저장하는 또 다른 메모리 공간입니다.

특정 변수의 주소 값은 바뀌지 않지만 포인터는 다른 주소 값을 대입하여 그 값을 바꿀 수 있습니다.

 

주소와 포인터의 크기

포인터도 저장 공간이므로 크기가 있습니다.

포인터의 크기는 저장할 주소의 크기에 따라 결정됩니다. 모든 주소와 포인터는 가리키는 자료형에 관계없이 크기가 같습니다.

 

포인터 대입 규칙

포인터는 크기가 모두 같으므로 대입 연산을 쉽게 생각할 수 있지만 다음 규칙을 따라야 합니다.

  • 포인터는 가리키는 변수의 형태가 같을 때만 대입해야 합니다.
  • 형 변환을 사용한 포인터의 대입은 언제나 가능합니다.

 

포인터를 사용하는 이유

임베디드 프로그래밍을 할 때 메모리에 직접 접근하는 경우나 동적 할당한 메모리를 사용하는 경우에 반드시 필요합니다.

임베디드 프로그래밍은 임베디드 시스템(Embeded System: 내장형 시스템)을 제어하기 위한 프로그래밍으로, 거의 모든 생활기기에서 특정 기능을 제어하기 위해 구현됩니다.

 

확인 문제

더보기

1. 다음 코드를 참고하여 보기에서 상수와 변수를 구분해보세요.

int a = 10;
int *p = &a;
*p = 20;

    ① a     :   변수 

    ② 10   :   상수

    ③ p     :   변수

    ④ *p    :   변수

    ⑤ &a   :   상수

 

2. 주소 값의 크기가 4바이트일 때, sizeof 연산의 결괏값이 가장 큰 것은? 

char *pc;
double *pd;

    ① sizeof(pc)

    ② sizeof(pd)

    ③ sizeof(*pc)

    ④ sizeof(*pd)

 

3. 다음 코드의 실행결과를 작성해 보세요.

int a = 10, b = 20;
int *pa = &a, *pb = &b, *pt;
pt = pa;
pa = pb;
pb = pt;
printf("%d, %d", *pa, *pb);
20, 10

 

 

도전 실전 예제 (선택 문제)

// [도전 실전 예제] 미니 정렬 프로그램

#include <stdio.h>

void swap(double *pa, double *pb);
void line_up(double *maxp, double *midp, double *minp);

int main(void) {
	double max, mid, min;

	printf("실수값 3개 입력 : ");
	scanf("%lf %lf %lf", % max, &mid, &min);
	line_up(&max, &mid, &min);
	printf("정렬된 값 출력 : %.1lf, %.1lf, %.1lf\n", max, mid, min);

	return 0;
}

void swap(double, *pa, double* pb) {
	double temp;

	temp = *pa;
	*pa = *pb;
	*pb = temp;
}

void line_up(double* maxp, double* midp, double* minp) {
    if (*maxp < *midp)
        swap(maxp, midp);
    if (*maxp < *minp)
        swap(maxp, minp);
    if (*midp < *minp)
        swap(midp, minp);
}