C - 포인터 (Pointer)

lsjoon·2024년 1월 29일

C

목록 보기
1/8
post-thumbnail

포인터

프로그래밍 언어에서 다른 변수, 혹은 그 변수의 메모리 공간주소를 가리키는 변수

코드에 직접 값을 가진 변수를 입력하는 것 : 직접 참조 ( 속도가 빠르다 )
포인터가 가리키는 값을 가져오는 것 : 간접 참조, 역참조

- 포인터를 자주 사용하는 언어 : 어셈블리어(Assembly), C, C++, 파스칼
- 극히 제한적으로 사용하는 언어 : 모듈라-2(Modula-2), 에이다(Ada)

특징

  • 포인터는 다른 변수나 함수를 가리키도록 사용됨
  • 일반적으로 포인터는 메모리 주소를 바꿀 수 있음

C 언어의 포인터

- 모든 변수는 메모리에 값을 저장
- const 같은 고정값 변수 외에 모든 변수는 RAM에 할당
- 메모리 공간을 구별하는 역할이 메모리 주소값

- 포인터 변수는 메모리 주소를 지정하는 값을 가짐
    = 데이터가 존재하는 주소값을 사용하여 엑세스

- 전역 변수의 정적 변수는 기계어 코드에 주소값을 고정하지만,
   지역 변수는 스택(Stack) 또는 레지스터(Register)를 통해 위치값을 설정


포인터의 단점

  • 포인터 변수는 주소를 직접적으로 컨트롤하기 때문에 예외처리가 확실하지 않을 경우, 예상치 못한 문제가 많이 발생 ( ex. 널 포인트 같은 경우에 바로 접근할 경우 예외 발생 )
  • 포인터를 선언만 하고 초기화하지 않을 경우, 잘못된 주소를 가리키고 있기 때문에 주의해야 함 ( 통상, 선언과 동시에 초기화를 실시 )
  • 포인터 변수는 주소를 직접 참조하기 때문에 원본의 값이 수정될 수 있음
  • 메모리의 절대 번지 접근 시 시스템 오류를 초래함


주소 연산자 : &

변수의 메모리 주소를 구하기 위해서 변수 앞에 붙이는 연산자

일반적으로 주소는 해당 데이터가 저장된 메모리의 ' 시작 주소 '
메모리 주소는 고정된 것이 아니라, 실행 환경에 따라 계속 변함

메모리 주소는 16진수 형태로 이루어짐 : 00AFF9F4

[ 예제 ]

#include <stdio.h>
 
int main(void)
{	// printf 에서 서식 지정자 %p 를 사용해 출력 가능
	// 8진수 = %o, 16진수 = %x 도 주소값 출력에 사용 가능
    int num = 10;
    printf("%p\n", &num);
    return 0;
}

// output : 00AFF9F4

' int 형 ' 변수 는 4byte 이므로, 변수 num 의 주소값이 F4 부터 F7 까지 걸쳐있음.
  = num 의 시작 주소는 ' F4 '



참조 연산자 : *

포인터(Pointer) : 메모리의 주소값을 저장하는 변수

>>> 포인터 변수 선언 방법 <<<
// 초기화 없이 참조 연산자 사용 시 의도치 않은 메모리에 값을 저장할 수 있음
자료형 * 포인터이름;

// 이와 같이 선언과 동시에 초기화하는 것이 좋음
자료형 * 포인터이름 = &변수이름;
자료형 * 포인터이름 = 주소값;

[ 예제 ]

#include <stdio.h>

int main(void) {
    int num;    		// 1. 일반 변수 선언
    int * pnum;   	 	// 1. 포인터 선언
    
    pnum = &num;    	// 2. 포인터에 num 주소 대입
    *pnum = 10;    		// 3. 포인터로 변수 num에 10 
 
    printf("변수명으로 num 값 출력 : %d\n", num);
    printf("포인터로 num 값 출력 : %d\n", *pnum);
 
    return 0;
}

// >>> output
// 변수명으로 num 값 출력 : 10
// 포인터로 num 값 출력 : 10


이중 포인터 : **

포인터의 포인터

포인터 변수를 가리키는 또 다른 포인터 변수
포인터를 선언 시 *(별표) 의 개수에 따라 삼중, 사중 혹은 그 이상의 포인터도 생성 가능

[ 예제 ]

>>> 이중 포인터 변수 선언 방법 <<<

자료형 ** 포인터이름;

> - - - - - - - - - - - - - - - - - - Example - - - - - - - - - - - - - - - - - - <
#include <stdio.h>
 
int main(void)
{
    int * ptr;     				// 포인터 선언
    int ** dptr;    			// 이중 포인터 선언
    int num = 10;
 
    ptr = &num;     			// 포인터에 num 주소 대입 
 
    dptr = &ptr;    			// 이중 포인터에 ptr 주소 대입
 
    printf("%d\n", **dptr);     // 포인터를 두 번 역참조하여 num의 메모리 주소에 접근
 
    return 0;
}

// output : 10



포인터와 const

포인터 변수 대상으로 const 선언 시, 변수에 사용하는 const 와는 다르게 동작

포인터에 사용하는 const : 포인터를 통한 변경을 허용하지 않음 ( 즉, 변수가 아닌 포인터를 상수화 )
= 변수 num 은 언제든지 변경이 가능, 포인터를 통해 변수 num 을 변경하는 것을 막음

[ 예제 ]

> - - - - - - - - - - - - - - - - - - Example  - - - - - - - - - - - - - - - - - - <
#include <stdio.h>
 
int main(void)
{
    int num = 10;
    const int* p = &num;
 
    *p = 20;    // 컴파일 에러
    
    num = 20;    // 컴파일 성공
 
    printf("변수 num : %d\n", *p);
 
    return 0;
}

// output : 20

#include <stdio.h>


사진 클릭 시 출처 이동
썸네일 출처 , 출처 , 출처

profile
중요한 것은 꺾여도 그냥 하는 마음

0개의 댓글