포인터 타입과(pointer type)과 형변환 연산자 (type casting operators)

포인터 타입?

포인터 타입

메모리의 주소를 가지고 있는 변수.
컴터는 바이트 단위로 주소가 있는데, 각각의 모든 집이 주소를 가지고 있다. 그러면 이 주소를 이용해서 원하는 집을 찾을 수 있다는거지.

컴터도 똑같음. 특정 주소를 이용해서 어떤 메모리에 있는 특정 값을 찾고, 불러올 수 있다는 거.

메모리의 구조

변수는 메모리에 저장된다. 메모리는 바이트 단위로 액세스된다.

변수와 메모리

변수의 크기에 따라서 차지하는 메모리 공간이 달라진다.

char: 1byte , int : 4byte ...

변수의 주소

변수을 계산하는 연산자 : &
변수 i의 주소 : &i

포인터의 선언

포인터 : 변수의 주소를 가지고 잇는 변수

포인터도 변수니까, 선언도 해야하고, 변수 이름 규칙도 잘 지켜야함.

int i = 10 // 정수형 변수 i 의 선언
int *p = &i; // 변수 i 의 주소가 포인터 p로 대입 int *p; p = &i; 와 같음 

// * p = &i 가 절대 아님!!!!! 

p 가 &i 인거지, *p가 &i인게 아님!! 절대 아님!!! 시험에 나올듯 ?

다양한 포인터의 선언

char 이든, float 이든, double 이든 전부 주소의 크기는 똑같다.

sizeof() 로 확인해 볼 수 있음.

간접 참조 연산자 * (&의 반대)

포인터를 통해서 그 메모리를 간접참조한다. 포인터가 가리키는 값을 가져오는 연산자.

int i = 10;
int *p = &i; // 선언문에 있는 *s는 간접참조 연산자가 아님! 

cout << *p; // 실행결과 : 10

*p = 20;
cout << *p; // 실행결과 : 20

간접 참조 연산자의 해석

간접 참조 연산자 : 지정된 위치에서 포인터의 타입에 따라 값을 읽어들인다.

int *p = 8; // 위치 8에서 정수를 읽겠다.
char *p = 8; // 위치 8에서 문자를 읽겠다.
double *p = 8; // 위치 8에서 실수를 읽겠다.

연산자의 비교 & : 변수에 대입해서 변수의 주소를 읽어올 때
* : 포인터를 통해서 변수를 간접참조 할 때 쓰는 기호 포인터가 가르키는 내용을 읽어올 때
보통은 절대 주소를 이용해서 읽어오지 않음

형변환 연산자

명시적인 형변환

  • 형변환 : 사용자가 데이터 타입을 변경하는 것
int i = 5;
f = (double)i + (double)j;
f = (double)((int)y + 3);
f = (float)(x = 5); // 수식 x = 5의 결과값인 5가 float형으로 변환

i 와 j는 임시변수로 쓰인거. i, j 는 지금도 int

묵시적인 형변환

int i = 5; double d; float f;

d = (double)i ;
d = i;
f = (double)i; // 형변환된 i가 묵시적으로 변환된 f에 들어감

pointer type의 type cast

float f;
int *i_p;
float *f_p;

f_p = &f; f_p 에 f의 주소를 넣어라.
cout << *f_p << endl;
i_p = (int *)f_p; // float pointer -> int pointer 
f_p = (float *)0x7fffde00; // int -> float *

포인터 사용 시 주의점 # 1

포인터의 타입과 변수의 타입은 일치하여야 한다.

#include <stdio.h>
int main(void){
int i;
double *pd;
pd = &i; // 오류! double형 포인터에 int형 변수의 주소를 대입
*pd = 36.5;
return 0;
}

포인터 사용 시 주의점 # 2

초기화가 안된 포인터를 사용하면 안된다.

int main(void)
{
int *p; // 포인터 p는 초기화가 안되어 있음
*p = 100; // 위험한 코드
return 0;
}

포인터 사용 시 주의점 # 3

  • 포인터가 아무것도 가리키고 있지 않는 경우에는 NULL 로 초기화
  • NULL포인터를 가지고 간접참조하면 하드웨어로 감지할 수 있다.
  • 포인터의 유효성 여부 판단이 쉽다.

배열의 이름만 (a) 사용하면, 그 배열의 시작주소(&a[0])와 같은 의미.

int a[10];

cout << "a means " << a << endl;
cout << "%a[0] is " << &a[0] << endl;

포인터를 쓰는 이유:

데이터의 복사를 피함.

마지막 정리

*p : p라는 이름을 가진, 주소를 저장하는 공간

int *p : p라는 이름을 가진, 주소를 int type로 저장함

int *p = &i i라는 이름의 변수의 주소를 저장하는 이름이 p고 타입은 int인 저장하는 포인터를 선언함

여기서 p는 i의 주소이고, *p는 i의 값임.
선언시 int *p = & i라고 해서 *p = &i 인것은 아님!!

int *p ; p = &i 이 맞음!

'TIL > [C++ 프로그래밍} TIL' 카테고리의 다른 글

TIL (22.04.06)  (0) 2022.04.06
TIL (22.04.04)  (0) 2022.04.04
TIL (22.03.29)  (0) 2022.03.30
TIL (22.03.28)  (0) 2022.03.28
TIL (22.03.23)  (0) 2022.03.23