Skip to main content

Command Palette

Search for a command to run...

포인터 변수

Published
2 min readView as Markdown

주소 값의 저장을 목적으로 선언되는 포인터 변수

int main(void)
{
    char ch1='A', ch2='Q';
    int num=7;
}
/* 총 6바이트(1바이트 + 1바이트 + 4바이트)가 메모리 공간에 할당 
   1바이트의 메모리 공간을 단위로 하나의 주소 값이 할당되며, 주소 값도 1씩 증가
   C언어에서는 시작번지만을 가지고 위치를 표현 */

포인터 변수란 메모리의 주소 값을 저장하기 위한 변수

포인터 변수와 & 연산자

“정수 7이 저장된 int형 변수 num을 선언하고 이 변수의 주소 값 저장을 위한 포인터 변수 pnum을 선언 → pnum에 변수 num의 주소 값 저장"

int main(void)
{
    int num=7;
    int * pnum;    // 포인터 변수 pnum의 선언
    pnum = #   // num의 주소 값을 포인터 변수 pnum에 저장
}
/* &연산자는 '오른쪽에 등장하는 피연산자의 주소 값을 반환하는 연산자' 
   pnum에는 변수 num의 시작번지 주소 값이 저장
   -> 포인터 변수 pnum이 int형 변수 num을 가리킨다. 
   32비트 시스템 포인터 변수 -> 4바이트
   64비트 시스템 포인터 변수 -> 8바이트 */

포인터 변수 선언

  • 포인터 변수는 가리키고자 하는 변수의 자료형에 따라서 선언하는 방법이 달라짐, 사실 주소 값은 동일한 시스템에서 그 크기가 동일하며 모두 정수의 배열들 띔.

⁠type * ptr;  // type형 변수의 주소 값을 저장하는 포인터 변수 ptr의 선언


포인터와 관련있는 연산자: & 연산자, * 연산자⁠

변수의 주소 값을 반환하는 & 연산자

int main(void)
{
    int num = 5;
    int * pnum = &num  // num의 주소 값을 반환해서 포인터 변수 pnum을 초기화
}

/* & 연산자의 피연산자는 변수이여야 하며, 상수는 피연산자가 될 수 없다 */
int main(void)
{
    int num1 = 5;
    double * pnum1 = &num1;  // 일치하지 않음!

    double num2 = 5;
    int * pnum2 = &num2;  // 일치하지 않음!
}

포인터가 가리키는 메모리를 참조하는 * 연산자

int main(void)
{
    int num=10;
    int * pnum=#  // 포인터 변수 pnum이 변수 num을 가리키게 하는 문장
    *pnum=20;    // pnum이 가리키는 변수에 20을 저장하라!
    printf("%d", *pnum);    // pnum이 가리키는 변수를 부호 있는 정수로 출력하라!
}

/* *pnum이 의미하는 바: 포인터 변수 pnum이 가리키는 메모리 공간인 변수 num에 접근 */
#include <stdio.h>

int main(void)
{
    int num1=100, num2=100;
    int * pnum;

    pnum=&num1;     // 포인터 pnum이 num1을 가리킴
    (*pnum)+=30;        // num1+=30; 과 동일

    pnum=&num2;     // 포인터 pnum이 num2를 가리킴
    (*pnum)-=30;        // num2-=30; 과 동일

    printf("num1: %d, num2: %d\n", num1, num2);
    return 0;
}

/* 결과 
num1: 130, num2: 70 */

다양한 ‘포인터 형'이 존재하는 이유

포인터 기반의 메모리 접근 기준을 마련하기 위해

잘못된 포인터의 사용과 null 포인터

  • 포인터 변수를 선언만하고 초기화하지 않으면, 포인터 변수는 쓰레기 값으로 초기화 → 어디를 가리킬 지 모르게 됌.

포인터 변수는 어떤 값으로 초기화를 시켜야 할까

int main(void)
{
    int * ptr1=0;
    int * ptr2=NULL;  // NULL은 사실상 0을 의미
}

/* ptr1을 초기화하는 값 0을 가리캬 'Null 포인터'라 함.
   "아무데도 가리키지 않는다!"를 의미함 */

More from this blog

선행처리기와 매크로

선행처리는 컴파일 이전의 처리를 의미 선행처리는 선행처리기에 의해서, 컴파일은 컴파일러에 의해서, 링크는 링커에 의해서 진행 소스파일 → 선행처리기 → 선행처리 거친 소스파일 → 컴파일러 → 오브젝트 파일 → 링커 → 실행파일 컴파일 과정을 거치게 되면 바이너리 데이터로 이루어진 오브젝트 파일이 생성 선행처리기가 하는 일 삽입해 놓은 선행처리 명령문대로 소스코드의 일부를 수정 여기서 수정이란, 단순 치환의 형태 /* 간단한 선행처리 명령문 */...

Oct 10, 20246 min read

C 언어의 메모리 구조

프로그램을 실행하면 해당 프로그램의 실행을 위한 메모리 공간이 운영체제에 의해서 미리 마련 그리고 바로 이 메모리 공간 내에서 변수가 선언되고, 문자열이 선언되는 것 메모리의 구성 프로그램 실행 시 운영체제에 의해서 마련되는 메모리의 구조는 네 개의 영역으로 구분 코드 영역 / 데이터 영역 / 힙 영역 / 스택 영역 메모리 공간을 나눠놓은 이유는 유사한 성향의 데이터를 묶어서 저장을 하면, 관리가 용이해지고 메모리의 접근속도가 향상 메모리 영역...

Oct 9, 20246 min read

파일과 스트림(Stream), 그리고 기본적인 파일의 입출력

저기 저 파일에 저장되어 있는 데이터를 읽고 싶어요. 프로그램 상에서 파일에 저장되어 있는 데이터를 참조하길 원한다고(읽기 원한다고) 가정했을 때, 우리가 구현한 프로그램과 참조할 데이터가 저장되어 있는 파일 사이에 데이터가 이동할 수 있는 다리를 놓는 일을 먼저 해야 한다. 이러한 데이터 이동의 경로가 되는 다리를 가리켜 ‘스트림(stream)’이라 함. 스트림이라는 것은 운영체제에 의해서 형성되는 소프트웨어적인 상태를 의미하는 것 따라서, ...

Oct 8, 20249 min read

JinGood

31 posts