Notice
Recent Posts
Recent Comments
Link
250x250
«   2025/03   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
Archives
Today
Total
관리 메뉴

공부해보잠

포인터 본문

자격증/정보처리

포인터

heejk 2025. 2. 16. 02:42
포인터와 포인터 변수

포인터는 변수의 주소, 포인터 변수는 변수의 주소를 저장하는 변수이다.
즉, 변수의 "값"이 아니라 변수가 저장된 메모리 주소를 저장하는 것이 포인터이다.

 

2. 포인터 선언과 사용법

포인터는 *를 사용하여 선언하며, & 연산자를 사용하여 변수의 주소를 저장한다.

#include <stdio.h>

int main() {
    int a = 5;      // 정수형 변수 선언
    int *p = &a;    // 포인터 선언 및 a의 주소 저장

    printf("변수 a의 값: %d\n", a);
    printf("변수 a의 주소: %p\n", &a);
    printf("포인터 p가 저장한 값(= a의 주소): %p\n", p);
    printf("포인터 p가 가리키는 값: %d\n", *p);

    return 0;
}
변수 a의 값: 5
변수 a의 주소: 0x7ffe1234abcd
포인터 p가 저장한 값(= a의 주소): 0x7ffe1234abcd
포인터 p가 가리키는 값: 5
  • int *p = &a;  p는 a의 주소를 저장한다.
  • *p  p가 가리키는 변수 a의 값을 가져온다.
  • 즉, *p를 사용하면 a의 값을 읽거나 변경할 수 있다.

포인터를 사용하여 변수 값 변경

포인터를 사용하면 변수 값을 직접 변경할 수 있다.

#include <stdio.h>

int main() {
    int a = 5;
    int *p = &a;  // 포인터 선언 및 a의 주소 저장

    *p = 10;  // 포인터를 사용하여 a의 값을 변경

    printf("변경 후 a의 값: %d\n", a);
    return 0;
}
변경 후 a의 값: 10

 

  • *p = 10;  p가 가리키는 주소에 저장된 값이 10으로 변경됨.
  • 따라서 a의 값도 10으로 변경됨.
  • 즉, 포인터를 사용하면 변수의 원본 값을 직접 수정할 수 있다.

물론, 이렇게 간단한 변수의 변경은 포인터를 사용 할 필요가 없습니다

#include <stdio.h>

int main() {
    int a = 5;  // 변수 선언 및 초기화
    printf("변수 a의 값: %d\n", a);

    a = 10;  // 변수 값 변경
    printf("변수 수정 후 값: %d\n", a);

    return 0;
}

그런데도 왜 포인터가 필요한걸까?

 

포인터가 필요한 이유는

포인터를 사용하면 변수를 효율적으로 관리하고, 원본 데이터를 직접 수정할 수 있다.

  • 변수를 함수에 전달할 때 원본을 직접 수정할 수 있음.
  • 배열과 동적 메모리 할당을 사용할 때 필수적임.
  • 데이터를 복사하지 않고, 메모리를 효율적으로 사용할 수 있음.
  • 변수의 값 변경만 필요하다면, 굳이 포인터를 사용할 필요가 없음.
  • 하지만, 특정한 경우에는 포인터를 사용해야 함.

예제 함수에서 값을 직접 변경해야할 경우

#include <stdio.h>

void modify(int *x) {
    *x = 10;
}

int main() {
    int a = 5;
    modify(&a);
    printf("변경 후 a의 값: %d\n", a);
    return 0;
}
  • 포인터를 사용하면 함수에서 원본 변수를 직접 수정할 수 있음

예제 배열을 사용할 때

#include <stdio.h>

int main() {
    int arr[] = {1, 2, 3};
    int *p = arr;

    *(p + 1) = 20;  // 배열의 두 번째 요소를 변경

    printf("배열 수정 후 값: %d\n", arr[1]);  // 20 출력
    return 0;
}
  • 포인터를 사용하면 배열의 특정 요소를 쉽게 변경할 수 있음

예제 동적 메모리를 할당할때

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *p = (int *)malloc(sizeof(int));  // 동적 메모리 할당
    *p = 10;

    printf("동적 할당된 값: %d\n", *p);

    free(p);  // 메모리 해제
    return 0;
}
  • 동적 메모리를 할당하고 사용할 때 포인터가 필수적으로 필요함

주의사항

1. 초기화되지 않은 포인터 사용 금지

int *p;  // 초기화되지 않은 포인터
*p = 10;  // 오류 발생

포인터를 사용하기전 반드시 초기화 된 포인터를 사용해야 함

int a = 5;
int *p = &a;

 

2. 잘못된 메모리 접근

int *p = NULL;
*p = 10;  // 오류 발생 (NULL 주소에 값을 저장하려고 시도)

 

NULL 포인터 체크 후 사용

if (p != NULL) {
    *p = 10;
}

 

요약

  • 포인터는 변수의 주소를 저장하는 변수이다.
  • 포인터를 사용하면 변수의 원본 값을 직접 수정할 수 있다.
  • 배열, 동적 메모리 할당 등에서 필수적으로 사용된다.
포인터 개념 설명
포인터란? 변수의 주소를 저장하는 변수
포인터의 역할 변수 값을 직접 변경, 함수에서 원본 수정, 배열과 동적 메모리 처리
포인터를 사용하면 좋은 점 메모리 효율적 사용, 원본 데이터 직접 수정 가능
포인터 주의할 점 초기화되지 않은 포인터 사용 금지, NULL 체크 필요

 


포인터 배열

포인터 배열이란 포인터를 여러 개 저장할 수 있는 배열을 의미합니다.
즉, 변수의 주소를 저장하는 포인터들이 배열 형태로 저장되는 것입니다.

 

포인터 배열의 개념

포인터 배열은 일반 배열과 다르게 값을 직접 저장하지 않고, 변수의 주소를 저장합니다.

 

포인터 배열 선언 방법

int *ptr[3];  // 정수형 변수의 주소를 저장하는 포인터 배열 선언

ptr 포인터 배열이며, 3개의 정수형 변수 주소를 저장할 수 있습니다.(ptr은 변수명이며, 다른 변수명을 지정해도 됨)

 

포인터 배열 예제

#include <stdio.h>

int main() {
    int a = 10, b = 20, c = 30;
    int *ptr[3] = {&a, &b, &c};  // 포인터 배열 선언 및 초기화

    printf("ptr[0]이 가리키는 값: %d\n", *ptr[0]);  // 10
    printf("ptr[1]이 가리키는 값: %d\n", *ptr[1]);  // 20
    printf("ptr[2]이 가리키는 값: %d\n", *ptr[2]);  // 30

    return 0;
}
ptr[0]이 가리키는 값: 10
ptr[1]이 가리키는 값: 20
ptr[2]이 가리키는 값: 30

포인터 배열은 변수의 주소를 저장하고, *ptr[i]를 통해 해당 변수의 값을 가져올 수 있음([i]는 배열의 인덱스를 의미, [0],[1],[2])

 

 

 

일반 배열과  포인터 배열의 차이

비교 일반 배열 포인터 배열
저장하는 값 실제 데이터 값 (10, 20, 30)
실제 값 저장 (arr[i] = 값)
메모리 주소 (0x1000, 0x2000...)
변수의 주소 저장 (ptr[i] = &변수)
배열 요소 타입 int arr[3]  int 값을 저장 int *ptr[3]  int형 변수 주소 저장
사용 목적 여러 개의 값을 저장할 때 여러 개의 포인터(주소)를 저장할 때
접근 방법 arr[i] → 값 직접 접근 *ptr[i] → 주소를 따라가서 값 접근
값 직접 수정 가능 여부 가능 (arr[i] = 새로운 값) 불가능 (가리키는 주소만 변경 가능)
가리키는 위치 변경 불가능 가능(ptr[i] = &새로운변수)
포인터를 사용한 값 변경 불가능 *ptr[i]로 가리키는 변수 값 변경 가능

 

일반 배열 예제

#include <stdio.h>

int main() {
    int arr[3] = {10, 20, 30};  // 정수형 배열 선언

    for (int i = 0; i < 3; i++) {
        printf("arr[%d] = %d\n", i, arr[i]);  // 배열 요소 출력
    }

    return 0;
}
  • 일반 배열은 arr[3]의 배열 선언, arr[0] = 10, arr[1] =20, arr[2] = 30의 변수를 저장하고 있음.
#include <stdio.h>

int main() {
    int arr[3] = {10, 20, 30};
    arr[1] = 50;  // 직접 값 변경 가능

    printf("arr[1]: %d\n", arr[1]);  // 50 출력

    return 0;
}

 

  • 일반 배열은 값 자체를 저장하고 직접 수정 가능

 

포인터 배열의 예제

#include <stdio.h>

int main() {
    int a = 10, b = 20, c = 30;
    int *ptr[3] = {&a, &b, &c};  

    *ptr[1] = 50;  // b의 값을 50으로 변경 가능 (가리키는 값 변경)
    ptr[2] = &a;   // c 대신 a의 주소를 가리키도록 변경

    printf("b = %d\n", b);  // 50
    printf("*ptr[2] = %d\n", *ptr[2]);  // 10 (a를 가리키도록 변경됨)

    return 0;
}

 

  • 포인터 배열은 가리키는 주소를 변경할 수 있지만, 배열 요소 자체를 직접 수정할 수 없음
  • 그러나 *ptr[i]를 사용하면, 가리키는 변수의 값 변경 가능

포인터 배열을 사용하는 이유

  • 여러 개의 변수 주소를 한 번에 관리할 때 유용
  • 함수에서 여러 개의 변수를 쉽게 전달할 수 있음
  • 2차원 배열처럼 문자열 배열을 처리할 때 사용

 

문자열을 관리할 때 포인터 배열 사용 예제

#include <stdio.h>

int main() {
    char *strArr[3] = {"Hello", "World", "C Language"};  // 문자열을 가리키는 포인터 배열

    for (int i = 0; i < 3; i++) {
        printf("%s\n", strArr[i]);  // 문자열 출력
    }

    return 0;
}

 

  • 포인터 배열을 사용하면 여러 개의 문자열을 효율적으로 관리할 수 있음

 

정리

  • 일반 배열 값을 저장하지만, 포인터 배열 주소를 저장한다.
  • 포인터 배열을 사용하면 가리키는 위치를 변경할 수 있고, 변수의 값도 수정 가능하다.
  • 주로 동적 메모리 할당이나 문자열 배열 관리 등에 활용된다.

즉, 포인터 배열은 "주소를 저장하는 배열"이고, 일반 배열과 다르게 "값이 아니라 주소를 저장한다는 점"이 핵심 차이점이다

 

728x90

'자격증 > 정보처리' 카테고리의 다른 글

Java클래스  (0) 2025.02.16
사용자 정의 함수  (0) 2025.02.16
배열과 문자열  (0) 2025.02.13
반복문  (0) 2025.02.13
제어문  (0) 2025.02.12