본문 바로가기
프로그래밍 언어/C언어

[혼자 공부하는 C언어] - Chapter 09 정리 및 문제 해결

by amobu0 2024. 6. 24.
혼자 공부하는 C언어 책 정리 및 발생하는 트러블 슈팅 해결

Chapter 09 포인터

학습목표 

  • 시스템 프로그래밍이 가능하도록 도와주는 포인터의 개념을 이해하자
  • 메모리 주소의 개념과 주소 연산자 &, 간접 참조 연산자 *에 관해 알아보자
  • 포인터 기본 사용법과 포인터 사용 규칙을 알아보자

9-1 포인터의 기본 개념

C 언어는 메모리에 접근해서 우리가 원하는 방식으로 테이블을 사용할 수 있게 해주는 언어이다. 지금까지 변수 선언으로 메모리에 공간을 확보하였고, 그곳을, 데이터를 넣고 꺼내 쓰는 공간으로 사용했다. 변수명은 그런 메모리 공간을 식별할 수 있는 이름이었다. 

 

그러나 선언된 블록( { } ), 즉 함수 내부에서만 그 변수를 사용할 수 있었다. 같은 변수명을 사용했다 하더라도 블록이나 함수가 다르면 별도의 저장 공간을 확보하므로 전혀 다른 변수로 사용되는 것이다.


주소 연산자

주소라 하면 변수가 할당된 메모리 공간의 시작 주소를 의미한다. 시작 주소를 알면 그 위치부터 변수의 크기만큼 메모리를 사용할 수 있다. 주소는 주소 연산자 &를 사용해서 구한다.

 

메모리의 주소는 필요할 때마다 계속 주소 연산을 수행하는 것보다 한 번 구한 주소를 저장해서 사용하면 편리하다. 포인터가 바로 변수의 메모리 주소를 저장하는 변수이다. 따라서 주소를 저장할 포인터도 변수처럼 선언하고 사용한다. 선언할 때는 변수 앞에 *만 붙여 주면 된다.

 

일반 변수명을 만드는 규칙에 따라 포인터 이름을 짓고, 변수명 앞에 *를 붙인다. *는 포인터임을 표시하는 기호이다. 주의할 점은 주소 위치에 잇는 변수의 자료형을 적어야 한다.  포인터가 어떤 변수의 주소를 저장한 경우 '가라킨다'고 말하며 둘의 관계를 화살표 방향으로 간단히 표현한다. 포인터가 가리키는 변수를 사용할 때는 포인터에 특벽한 연산자를 사용 하는데, 이를 간접 참조 연산자(*) 또는 포인터 연산자라고 한다.


핵심 포인트

  1. 포인터는 메모리를 사용하는 또 다른 방법이다.
  2. 주소 연산자(&)로 변수가 할당된 메모리의 위치를 확인한다.
  3. 포인터로 가리키는 변수를 사용할 때 간접 참조 연산자(*)를 쓴다.

포인터와 연산자

구분 사용 예 기능
주소 연산자 int a;
&a;
변수 앞에 붙여 사용하며, 변수가 할당된 메모리의 시작 주소 값을 구한다.
포인터 char *pc;
int *pi;
double *pd;
시작 주소 값을 저장하는 변수며, 가리키는 자료형을 표시해 선언한다.
간접 참조 연산자 *pi = 10; 포인터에 사용하며, 포인터가 가리키는 변수를 사용한다.

9-2 포인터 완전 정복을 위한 포인터 이해하기

포인터는 주소를 저장하는 일정한 크기의 메모리 공간이다. 따라서 언제든 다른 주소를 저장하거나 포인터끼리 대입할 수 있다. 그러나 일반 변수와 달리 대입 연산에 엄격한 기준이 적용된다. 주소는 변수에 할당된 메모리 저장 공간의 시작 주소 값 자체고, 포인터는 그 값을 저장하는 또 다른 메모리 공간이다. 따라서 특정 변수의 주소 값은 바뀌지 않지만, 포인터는 다른 주소를 대입해 그 값을 바꿀 수 있다.

 

포인터도 저장 공간이므로 그 크기가 있다. 포인터의 크기는 저장할 주소의 크기에 따라 결정되는데 크기가 클수록 더 넓은 범위의 메모리를 사용할 수 있다. 포인터의 크기는 컴파일러에 따라 다를 수 있으나 모든 주소와 포인터는 가리키는 자료형과 상관없이 그 크기가 같다는 것에는 변함이 없다.


포인터를 사용하는 이유

변수를 사용하는 가장 쉬운 방법은 이름을 쓰는 것이다. 포인터를 사용하려면 추가저거인 변수 선언이 필요하고 주소 연산, 간접 참조 연산 등 각종 연산을 수행해야 한다. 일부러 포인터를 즐겨 사용할 필요는 없지만, 임베디드 프로그래밍을 할 때 메모리에 직접 전급하는 경우나 동적 할당한 메모리를 사용하는 경우에는 포인터가 반드시 필요하다.

 

 

임베디드 프로그래밍이란?

임베디드 프로그래밍은 임베디드 시스템(Embedded System : 내장형 시스템)을 제어하기 위한 프로그램으로, 오늘날 만들어지는 거의 모든 생활 기기에서 특정 기능을 제어하기 위해 구현된다. 예를 들어 정수기에서 정수, 냉수 등을 구분해 물이 나오게 한다던가, 자동차, 냉장고, 전기밥솥, 스마트워치 등에도 각 기능을 담당하는 하드웨어가 있는데, 이 하드웨어를 제어하는 소프트웨어를 만드는 일을 임베디드 프로그래밍이라고 한다.

핵심포인트

  1. 주소포인터는 각각 상수와 변수라는 차이가 있다.
  2. 포인터의 크기는 주소의 크기와 같다.
  3. 포인터에 주소를 저장할 때는 가리키는 자료형이 같아야 한다.
  4. 포인터의 주요 기능 중 하나는 함수 간에 효과 적으로 데이터를 공유하는 것이다.

간접 참조 연산자를 사용한 예(포인터  pa가 변수 a를 가리킬 때)

구분 변수 a 사용 포인터 pa 사용
대입 연산자 왼쪽 a = 10; *pa = 10;
대입 연산자 오른쪽 b = a; b = *pa;
피연산자 a + 20; *pa + 20;
출력 printf("%d", a); printf(%d, *pa);
입력 scanf("%d". &a); scanf("%d", &*pa);
scanf("%d", pa);

주소와 포인터의 특징

구분 사용 예 기능
포인터 int a,b;
int *p = &a;
p = &b;
포인터는 변수이므로 그 값을 다른 주소로 바꿀 수 있다.
포인터의 크기 int *p;
sizeof(p)
포인터의 크기는 컴파일러에 따라 다를 수 있으며, sizeof 연산자로 확인한다.
포인터의 대입 규칙 int *p;
double *pd;
pd = p; (X)
포인터는 가리키는 자료형이 일치할 때만 대입한다.

목표했던 기본편 9장까지 도착했다. 10장부터는 고급편인데 고급편을 공부하면서 기본편도 같이 복습해야겠다. 기본편 2회독 시작이라고 생각하면 되겠다. 

https://m.hanbit.co.kr/store/books/book_view.html?p_code=B3773573071

 

혼자 공부하는 C 언어(개정판)

혼자 해도 충분하다! 1:1 과외하듯 배우는 C 프로그래밍 자습서

m.hanbit.co.kr