포인터 변수 선언 방법
int *ptr;
int* ptr;
포인터 변수 선언 시 프로그래머의 취향에 따라 별표(*)가 포인터 변수명에 혹은 데이터 타입에 붙을 수도 있습니다.
포인터의 데이터 타입은 저장한 메모리 주소가 가리키는 변수의 데이터 타입과 같아야 합니다.
int num = 10;
int *ptr = #
printf("%d", *ptr);
위 예제에서 보는 것과 같이 ptr 포인터 변수의 데이터 타입은 int로 선언했습니다. 그 이유는 ptr이 저장하는 메모리 주소가 가리키는 변수의 데이터 타입이 int이기 때문입니다.
데이터 타입을 void로 선언하면 어떠한 타입도 저장 가능하나 자주 사용되지는 않습니다.
int *ip // int 변수를 가리키는 포인터
float *fp; // float 변수를 가리키는 포인터
double *dp; // double 변수를 가리키는 포인터
char *cp; // char 변수를 가리키는 포인터
포인터 선언 시의 별표(*)와 값을 가져오기 위한 별표(*) 차이점?
포인터를 처음 접할 때 많이 헷갈리는 것이 별표(*) 가 포인터 변수 선언 시에도 사용되고 값을 가져오기 위해서 사용된다는 것입니다. 이것은 모양만 같을 뿐 전혀 다른 의미입니다.
선언 시에 사용되는 별표(*)는 변수가 포인터라는 것을 알려주는 역활이고 값을 가져오기 사용되는 별표(*)는 포인터가 가리키는 값을 역참조한다는 의미입니다.
int *ptr; // 포인터. 포인터를 선언할 때 *
printf("%d\n", *ptr); // 역참조. 포인터에 사용할 때 *
포인터 변수 초기화
초기화는 메모리 주소를 포인터 변수에 저장하는 과정입니다. 또한 포인터 변수는 같은 데이터 타입의 변수의 주소 값만을 저장할 수 있습니다. 주소 연산자 &를 통해서 변수의 주소값을 가져올 수 있습니다.
#include<stdio.h>
void main()
{
int a = 10;
int *ptr; //포인터 선언
ptr = &a; //포인터 초기화
}
포인터 변수는 항상 같은 데이터 타입을 가진 변수를 최종적으로 가르킵니다.
#include<stdio.h>
void main()
{
float a;
int *ptr;
ptr = &a; //에러, 타입 불일치
}
만약 선언시 포인터 변수에 할당 할 변수의 주소가 확실하지 않은 경우에는 널(NULL) 값으로 초기화 하는 것을 권장합니다. 이렇게 NULL 값으로 초기화된 포인터 변수를 널(NULL) 포인터라 합니다.
#include <stdio.h>
int main()
{
int *ptr = NULL;
return 0;
}
포인터의 사용 또는 포인터의 역참조
포인터 변수에 저장된 메모리 주소가 가리키는 변수의 값을 가져오는 것을 포인터의 사용 혹은 역참조라고 합니다. 여기서 역참조 연산자 *를 사용합니다.
위에서 언급했지만 포인터 변수 선언시의 *와는 다른 의미입니다.
#include <stdio.h>
int main()
{
int a, *p; // 변수 그리고 포인터 변수 선언
a = 10;
p = &a; // 포인터 변수 초기화
printf("%d\n", *p);
printf("%d\n", *&a);
printf("%u\n", &a);
printf("%u\n", p);
printf("%u\n", &p);
return 0;
}
OUTPUT
10
10
3622046324
3622046324
3622046328
printf(“%d”, p);
printf(“%d”, p);
역참조 연산자를 사용하여 p가 가르키는 a의 실질적인 값 10 출력
printf(“%d\n”, *&a);
a변수의 주소 값을 리턴(&) 후 그 주소 값이 가르키는 값(*)을 출력하므로 결국 자신의 값 10 출력
printf(“%u\n”, &a);
주소값을 리턴하는 주소 연산자(&)를 사용했으므로 a 주소 값 출력
printf(“%u\n”, p);
포인터 변수 p는 a의 주소값을 가지고 있으므로 a 주소 값 출력
printf(“%u\n”, &p);
포인터 변수 p 자체에 주소 연산자(&)를 사용했으므로 포인터 변수의 자체의 주소 값 출력
포인터 사용 정리
- 포인터 변수 선언시의 *는 해당 변수가 포인터 변수임을 알려주는 역활을 합니다.
- 모든 변수의 주소를 얻기 위해서는 변수명 앞에 &를 붙여 줍니다.
- 포인터 변수는 변수의 주소를 저장합니다. 선언시 int *a는 a가 정수 값을 가진다는 의미가 아닙니다. 이것은 a가 정수 값을 저장하는 변수의 주소를 저장한다는 의미입니다.
- 포인터 변수에 의해 저장된 주소 값에 액세스하려면 *가 사용됩니다. 여기서 *는 역참조 연산자입니다.
#include <stdio.h>
int main()
{
int i = 10; // 10을 저장하는 정수 변수
int *a; // 포인터 변수 a 선언
/*
포인터 변수 a에 i의 주소값을 저장
*/
a = &i;
/*
a는 결국 i의 주소값을 가지고 있으므로 i 변수의 주소값을 출력
*/
printf("Address of variable i is %u\n", a);
/*
역참조 연산자를 사용하여 a가 가르키는 변수의 값 출력
*/
printf("Value at the address, which is stored by pointer variable a is %d\n", *a);
return 0;
}
OUTPUT
Address of variable i is 1169914348
Value at the address, which is stored by pointer variable a is 10
<< 다음 | 혼자 공부하는 C언어 | 이전 >> |
'프로그래밍 > C' 카테고리의 다른 글
포인터 그리고 배열 (0) | 2019.12.20 |
---|---|
C언어 이중 포인터 (0) | 2019.12.20 |
C언어 포인터 (0) | 2019.12.20 |
C언어 공용체 (Union) (0) | 2019.12.20 |
typedef 별칭(Alias) 주기 (0) | 2019.12.19 |