10 - Pointer
<학습하기>
포인터 (pointer)
우리가 만든 모든 변수들은 항상 메모리 어딘가에 존재하고 있다.
만약 A라는 변수가 메모리에서 100번지에 존재하고 있다면,
A라는 값을 읽는 것은 100번 메모리에서 값을 읽어오는 것과 같다.
마찬가지로 A 라는 변수에 값을 넣는 것은 100번 메모리에 값을 넣는 것과 같다.
주소 관련 연산자
& : 변수 앞에 붙어서 그 변수가 할당된 위치를 반환한다.
* : 포인터변수 앞에 붙어서 그 주소를 대상으로 어떤 작업을 한다.
포인터 변수
일반적인 값이 아닌 다른 변수의 주소를 담기 위한 변수.
구조는 int형과 같으나 (4바이트 정수)
이 변수에는 정수형 데이터가 아닌 주소값만을 저장할 수 있다.
그러므로 포인터 변수에는 상수값을 저장할 수 없다.
포인터 변수 만들기
일반적인 변수 선언과 비슷하나, 변수 앞에 *을 붙여준다.
int intVar; //일반 변수 - 정수형을 저장하는 intVar이라는 변수 선언.
int *intPnt; //포인터 변수 - 정수형 변수의 주소를 저장하는 포인터 선언.
double dblVar; //일반 변수 - 실수형을 저장하는 dblVar이라는 변수 선언.
double *dblPnt; //포인터 변수 - 실수형 변수의 주소를 저장하는 포인터 선언.
intPnt = &intVar; //intVar이라는 변수의 주소를 가져와서 intPnt에 저장.
dblPnt =&dblVar; //dblVar이라는 변수의 주소를 가져와서 dblVar에 저장.
intPnt = &dblVar; //컴파일 에러.
C언어의 특징으로 변수를 처음 만들었을 때는
그 변수 안에 어떤 값이 들어가 있을지 알 수 없다.
그러므로 포이터의 초기화를 위한 특수한 상수 NULL이 존재하며,
이것을 이용해 포인터를 초기화해서 제대로된 값이 들어있는지를 확인할 수 있다.
ex)
int *intPnt = NULL; //NULL로 초기화.
:
:
if (intPnt !=NULL)
intPnt 사용
else
puts("intPnt 초기화 안됨.");
포인터 변수의 사용
*연산자는 포인터 변수 자체가 아니라
그 포인터 변수가 가리키는 위치에 대해 작업을 하라는 것을 의미한다.
포인터는 변수의 주소를 이용하여 간접적인 접근이 가능하므로,
함수 호출등을 통해서 일반적인 방식으로는 접근할 수 없는 변수에도 접근이 가능해진다.
ex)
scanf ("%d", &intVar);
scanf 역시 하나의 함수이므로
일반적인 방법으로는 입력값을 intVar라는 변수에 저장할 수 없다.
그러나 scanf에서는 &연산자를 통해 주소를 전달함으로써,
scanf에서는 접근할 수 없는 intVar이라는 변수에 간접적으로 접근이 가능하다.
<실습하기>
#include <stdio.h>
int TestScanf(int intVar, int *intPnt);
main()
{
// 일반변수 만들기
int intVar;
double doubleVar;
// 포인터 만들기
int *intPnt = &intVar; // 각 변수의 주소로 초기화
double *doublePnt = &doubleVar;
intVar = 10;
doubleVar = 3.14;
printf("intVar : %d &intVar : %d\n", intVar, &intVar);
printf("doubleVar : %f &doubleVar : %d\n", doubleVar, &doubleVar);
printf("intVar : %d *intPnt : %d\n", intVar, *intPnt);
printf("doubleVar : %f *doublePnt : %f\n", doubleVar, *doublePnt);
puts("TestScanf");
{ // 변수를 만들기 위한 블럭
int intVarA = 0;
int intVarB = 0;
int rtn;
printf("before TestScanF intVarA:%d intVarB:%d\n", intVarA, intVarB);
rtn = TestScanf(intVarA, &intVarB);
printf("after TestScanF intVarA:%d intVarB:%d rtn:%d\n", intVarA, intVarB, rtn);
}
}
int TestScanf(int intVar, int *intPnt)
{
intVar = 100;
*intPnt = 100;
return 10;
}
//void 함수는 return 값이 필요없는 함수를 만들 때 쓴다.
//그러니 TestScanf함수는 void를 쓰면 안되게찌?
<실습하기>
#include <stdio.h>
int TestScanf(int intVar, int *intPnt);
main()
{
// 일반변수 만들기
int intVar;
double doubleVar;
// 포인터 만들기
int *intPnt = &intVar; // 각 변수의 주소로 초기화
double *doublePnt = &doubleVar;
intVar = 10;
doubleVar = 3.14;
printf("intVar : %d &intVar : %d\n", intVar, &intVar);
printf("doubleVar : %f &doubleVar : %d\n", doubleVar, &doubleVar);
printf("intVar : %d *intPnt : %d\n", intVar, *intPnt);
printf("doubleVar : %f *doublePnt : %f\n", doubleVar, *doublePnt);
puts("TestScanf");
{ // 변수를 만들기 위한 블럭
int intVarA = 0;
int intVarB = 0;
int rtn;
printf("before TestScanF intVarA:%d intVarB:%d\n", intVarA, intVarB);
rtn = TestScanf(intVarA, &intVarB);
printf("after TestScanF intVarA:%d intVarB:%d rtn:%d\n", intVarA, intVarB, rtn);
}
}
int TestScanf(int intVar, int *intPnt)
{
intVar = 100;
*intPnt = 100;
return 10;
}
//void 함수는 return 값이 필요없는 함수를 만들 때 쓴다.
//그러니 TestScanf함수는 void를 쓰면 안되게찌?
댓글
댓글 쓰기