C/C

포인터 pointer 1 - & 과 역 참조

HicKee 2022. 10. 1. 23:00

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

1. &변수

    & 오른쪽의 등장하는 피 연산자의 주소값을 반환하는 연산자.

int main() {
	int num1 = 10;
	printf("%p\n", &num1);
	//->00000028D79BF654 메모리 주소 실행할때마다 달라짐
}

변수의 메모리 주소를 구할때 변수 앞에 & 붙이면 된다. (& 은 주소 연산자)
메모리 주소는 16진수 형태 printf()로 %p를 사용하여 출력 (%x 도 사용가능)
메모리 주소는 고정된 것이 아님 실행시 마다 달라짐

2. 포인터 변수 선언

& 변수 로 메모리주소를 구함
메모리 주소를 저장 할때는 포인터(pointer) 변수에 저장한다.

int main() {
	int* numPtr; //포인터 변수
	int num = 10;
	numPtr = #

	printf("아래 두개의 주소가 같은지 확인\n");
	printf("%p\n", numPtr);
	printf("%p\n", &num);
	//메모리 주소로 실행 시 마다 주소가 달라짐을 확인
}

int num,* numPtr; 처럼 선언 할 수도 있지만 문장을 달리해서 선언하는 것이 좋다.
int num;
int*numPtr;

 

포인터 변수를 선언 할때는 자료형을 알려주소 * 을 붙이는 방식을 사용
>> 변수가 int형 이면 이변수의 메모리 주소를 저장하는 포인터는 int* 이어야한다.

포인터 변수에는 변수의 시작 번지 주소값을 저장
주소값의 크기와 변수의 크기는 동일하다.

 

>> 잘못된 포인터 사용 방법 <<

int *ptr; //포인터 변수 ptr은 쓰레기 값으로 초기화된다.
*ptr = 200;

int *ptr = 125; //125번지가 어디일까?
*ptr = 20;


포인터 변수를 우선선언만 해놓고 이후에 주소값을 채워 넣을 예정이라면 
int*ptr1 = 0;
또는
int *ptr2 = null;
이는 포인터가 아무곳도 가르키지 않는 다는 것을 의미 한다.

3. 역참조(dereference) 연산자 사용

포인터 변수에는 메모리 주소가 저장 메모리 주소가 있는 곳으로 이동하여 값을 
가져오고 싶다 > 역참조 연산자를 사용

int main() {

	int* numPtr;//포인터 변수
	int num1 = 10;
	numPtr = &num1; //num1의 메모리 주소를 포인터 변수에 저장
	printf("%d\n", *numPtr); 
	//>>10 역참조 연산자로 num1의 메모리주소에 접급하여 값을 가져온다
}

역참조 연산자 * 은 포인터 앞에 붙임 numPtr앞에 *을 붙이면 numPtr에 저장된 
메모리 주소로 이동하여 값을 가져옴
(numPtr < 메모리 주소를 저장하고 있음) 

포인터는 변수의 주소만 가리키면 역참조는 주소에 접근하여 값을 가져옴

포인터를 선언 할때도 * 을 사용하고 역참조를 할때도 * 을 사용
헷갈리기 쉽지만 선언과 사용을 구분해서 생각 
포인터 선언시 * 은 이 변수는 포인터다 라는 뜻이고
포인터에 사용 하는 * 은 포인터의 메모리 주소를 역참조 하겠다는 뜻이다.

4. 포인터 변수에 역참조 연산자를 사용하여 값을 저장 

int main() {

	int *numPtr; //포인터 변수의 선언
	int num1 = 10;

	numPtr = &num1; //numPtr에 num1의 메모리 주소를 저장

	printf("%d\n",*numPtr); //역참조 연산자로 메모리 주소에 접근하여 값을 가져옴
	printf("%d\n", num1);

	*numPtr = 20; //역참조 연산자를 이용하여 메모리 주소에 접근 20을 대입

	printf("%d\n", *numPtr); 
	printf("%d\n", num1); //실제 num1의 값도 달라지게 된다

}

오류 1

int main() {

	int *numPtr;
	int num1 = 10;

	numPtr = num1;
	
	//'int *'의 간접 참조 수준이 'int'과(와) 다릅니다.(C4047)
	//numPtr은 int 포인터 형, num1은 int형 둘은 자료형이 일치하지 않다.

	*numPtr = num1;
}

Visual Studio 기준 변화하는 값 확인

int main() {

	int* numPtr;
	int num1 = 10;

	numPtr = &num1;
	*numPtr = 20; //F9 F5 디버깅 모드 로컬에서 확인

	printf("%d\n", *numPtr);
	printf("%d\n", num1);

}

마지막

 

변수 :                    메모리 주소를 몰라도 값을 가져오거나 저장할수 있다.
주소연산자 & :     변수의 메모리 주소를 구한다.
역참조 연산자 * : 메모리에 저장된 값에 접근할 수 있다.
                            메모리 주소에 접근하여 값을 가져오고 저장
포인터 :               변수의 메모리 주소만 가리킴, 메모리 공간의 위치만 알 수 있다.

 

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

포인터 pointer 3 - void 포인터  (0) 2022.10.03
포인터 pointer 2 - 자료형 포인터 와 const  (0) 2022.10.02
static  (0) 2022.09.29
C char 그리고 wchar_t 문자, 문자열  (0) 2022.09.28
scanf() C4996 오류 이유, 해결  (0) 2022.09.26