WinCNT

C 언어 - 09. 포인터 본문

Study/C

C 언어 - 09. 포인터

WinCNT_SSS 2021. 8. 3. 17:03

포인터의 개념

  • 변수는 기본적으로 자신의 자료형에 맞는 값을 저장한다
  • 하지만 포인터(Pointer) 변수특수한 변수로, 메모리 주소를 저장한다.
    (단순히 메모리 주소를 저장할 때, 어떤 자료형의 주소값인지를 함께 저장한다)
  • 포인터 변수를 선언할 시에는 포인터 변수임을 알려주기 위해, 변수명 앞에 *를 붙인다.
    예시) int *b = &a;
  • 선언 이후 포인터 변수를 사용하게 되면, 포인터 변수가 가리키는 주소의 을 반환한다.

포인터 관련 연산자

주소 연산자(&) 변수 앞에 붙어서 변수의 메모리 시작 주소 값을 구합니다.
포인터(*) 포인터 변수를 선언할 때 사용합니다.
간접 참조 연산자(*) 선언된 포인터 변수 가리키는 변수를 구합니다.
#include <stdio.h>

int main(void)
{
    int a = 10;
    int *b = &a; //여기의 *는 포인터 연산자
    //포인트 변수 *b의 출력값은 변수a의 주소값이 아니라 변수 a의 주소의 값을 반환한다
    //10
    printf("%d\n", *b); //여기의 *는 간접 참조 연산자

    printf("변수 a의 주소 값 : %p\n", &a); //실행할 때마다 값이 변한다
    printf("변수 b의 값      : %p\n",  b); //실행할 때마다 값이 변한다
    printf("변수 b의 주소 값 : %p\n", &b); //실행할 때마다 값이 변한다

    system("pause");
    return 0;
}

예제) 배열 각 원소의 주소 값 출력

#pragma region "배열 각 원소의 주소 값 출력"
#include <stdio.h>
int main(void)
{
    int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    for (int i = 0; i < 10; i++)
    {
        printf("%d\n", &a[i]); //주소 값이 4byte(int에 할당되는 사이즈)씩 증가
    }
    system("pause");
    return 0;
}
#pragma endregion

포인터의 강력한 기능

  • 포인터는 컴퓨터 시스템의 특정한 메모리에 바로 접근할 수 있다.
    따라서 기존에 존재하던 중요한 메모리 영억에 접근하지 않도록 해야 한다.
  • 즉, 다음과 같이 특정한 주소 값을 포인터 변수에 대입하고 바로 값을 바꾸는 코트는 매우 위험하다.
int *a = 0x33484735; //16진수라는 것을 나타내기 위해 0x를 붙임
*a = 0;
  • 포인터는 특정한 메모리 주소 값을 가리키는 것이기 때문에 다중으로 사용 가능하다.
    (다중 포인터는 게임 등의 개발 시, 난독화 기법으로 사용되곤 함)
#pragma region "포인터의 포인터"
#include <stdio.h>
int main(void)
{
    int a = 10;
    int *b = &a;
    int **c = &b; //**은 포인터의 포인터라는 뜻
    int ***d = &c;

    printf("변수 a의      값            : %d\n", a);
    printf("변수 a의 주소 값            : %p\n", &a);
    printf("변수 b가 가리키는 주소의 값 : %d\n", *b);
    printf("변수 b의 값                 : %p\n", b);
    printf("변수 b의 주소 값            : %p\n", &b);
    printf("변수 c가 가리키는 주소의 값 : %d\n", **c);
    printf("변수 c의 값                 : %p\n", c);
    printf("변수 c의 주소 값            : %p\n", &c);
    printf("변수 d가 가리키는 주소의 값 : %d\n", ***d);
    printf("변수 d의 값                 : %p\n", d);
    printf("변수 d의 주소 값            : %p\n", &d);

    system("pause");
    return 0;
}
#pragma endregion

포인터와 배열의 관계

  • 배열과 포인터내부적으로 동일하게 작동한다.
  • 배열을 선언한 후에는 그 이름 자체포인터 변수와 동일하다.
#pragma region "배열과 포인터의 관계"
#include <stdio.h>
int main(void)
{
    int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int *b = a; //배열인 경우 주소 연산자(&)를 붙이지 않음
    printf("%d\n", b[2]);
    printf("배열 a의 값                 : %p\n", a);
    printf("배열 a의 주소 값            : %p\n", &a);
    printf("변수 b가 가리키는 주소의 값 : %d\n", *b);
    printf("변수 b의 값                 : %p\n", b);
    printf("변수 b의 주소 값            : %p\n", &b);
    system("pause");
    return 0;
}
#pragma endregion

 

'Study > C' 카테고리의 다른 글

C 언어 - 11. 문자열  (0) 2021.09.05
C 언어 - 10. 문자  (0) 2021.08.05
C 언어 - 08. 배열  (0) 2021.08.03
C 언어 - 07. 함수  (0) 2021.08.03
C 언어 - 06. 반복문  (0) 2021.08.02