안선생의 개발 블로그
C++ 포인터 본문
포인터
주소를 가르키는 변수
포인터 변수는 처리과정은 정수로 처리한다.
포인터의 주소단위는 byte이다.
포인터를 선언할때 정수를 선언해줘야 한다.
자료형 + *변수명
해당 포인터에게 전달된 주소를 해석하는 단위(자료형)
크기는 전부 32비트 운영체제 4바이트 64비트 8바이트
포인터 선언방법
nullptr : 포인터가 아무것도 가르키지 않는다는 뜻 즉 주소를 안가르킨다.
사용방법
&변수명은 변수명에 주소를 나타냄
pint는 i의 주소값을 넣겠다는 뜻
포인터를 사용하여 변수값 변경
변수명앞에 별을 붙이므로써 주소값을 참조하겠다는 뜻이다. 즉 i의 주소값에 300을 넣겠다는 뜻
포인터는 같은 자료형의 주소만 가능하다.
int포인터의 실수값을 저장하면 문법적으로 에러가 발생한다.
그래도 하고싶으면 강제언래핑으로 해줄 수 있다.
강제언래핑으로 실수 f의 주소를 pint에 넣었다. 전달받은 주소를 정수형 i변수에 넣고 출력하면 저런 값이 나온다 왜 그럴까? 그 이유는 int포인터에 float주소를 강제로 넣었고 int형에 포인터는 int로 받아드리기 때문에 실수 3.0에 저장되어있는 값을 부동소수점으로 표현되어있는 비트를 int비트로 바꿔 보면 저런숫자로 나오기 때문이다.
즉 int 포인터에 실수형으로 강제 언래핑 후 정수형으로 보면 3.0f가 저런 숫자로 바껴서 나온다.
즉 값이 바뀐게 아니고 해석이 달라진 것 같은 주소라도 그걸 가르키는 포인터가 누구냐에 따라 다르게 보기 때문
포인터 변수
int *pint = nullptr;
주소를 접근했을 때 int로 보겠다는 뜻, 포인터 근본 주소는 전부 같다.
포인터 자체는 주소를 저장하는 용도이기 때문에 포인터 변수 자체의 크기는 모두 같다. 64bit운영체제 8바이트 32bit운영체제
4바이트
포인터는 주소를 저장하는 변수인데 주소를 갔을 때 그것을 Int로 해석한다는 뜻이다. 즉 넣어준 주소를 어떻게 볼것인지 말하는 것
64운영체제 기준 포인터 변수의 크기는 8
포인터에 1을 더하면 어떻게 될까
pint는 int*변수 이기 때문에, 가리키는 곳을 int로 해석한다
즉 주소값을 1 증가하는 의미는 다음 int 위치로 접근하기 위해서 sizeof(int)단위로 증가하게된다.
만약 100번지 주소에 있다고 치면 101이 되는게 아니라 int 자료형 크기만큼인 4가 증가해 104번지로 가게 된다. int형은 4byte니 4씩 증가하기 때문 만약 char형이면 101번지로 간다 즉 자료형 크기만큼 증가된다.
포인터와 배열
배열의 특징
메모리가 연속적인 구조이다.
배열의 이름은 배열의 시작 주소이다.
arr+1을 더한다는 뜻은 시작주소에서 int형으로 접근해서 다음 주소인 4바이트 만큼 떨어진 곳을 말한다.
*앞에 붙여줌으로써 arr+1의 주소를 접근한다라는 뜻 즉 배열의 시작에서 한칸 뛴곳 즉 4바이트 떨어진곳에서 10을 넣음
*(arr +1 ) = 10; // arr[1] = 10; 이랑 같은 의미이다. 즉 주소를 참조한다라는 뜻
간단한 문제
short 배열로 연속적인 메모리를 갖고 있음
short배열의 short포인터 주소인데 강제로 int형으로 받음
pi+3에 의미는 int포인터 이므로 시작주소에서 12증가가 됨
short로 바꿔 접근해 즉 2바이트로 접근해서 7이 나오게 된다.
char 배열로 선언 (1byte)
1 | 1 |
그림으로 보면 저렇게 나옴 1byte씩 하나씩 접근
short 포인터로 강제로 바꿈 (2byte)
1(1) | 1(256) |
short로 받아기 때문에 2byte로 접근함 두개를 한꺼번에 접근 즉 하나로 본다.
1byte는 8비트 즉 255이기 때문에 오른쪽 값은
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
255 에서 1을 더한 256
왼쪽 값은
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
1이다. 즉 둘이 하나로 보기 때문에 257의 값이 나온다.
참고
2바이트 메모리를 읽게되면 리틀엔디안 방식에서는 앞쪽 메모리를 하위비트로 시작해서 뒤로 갈 수록 상위 비트로 인지하기 때문에 앞에 배치된 숫자가 하위 비트가 된다.
이 코드를 보면 출력 결과는 100이 나온다 그 이유는 함수 각각의 지역변수이기 때문이다. 변수 a는 main()함수에 따로 test()함수에 따로 있다.
만약 a라는 변수가 진짜 바꼈으면 좋겠다라는 생각을 해보았다.포인터를 이용해서 주소를 줘보자
실행해보니 500으로 바꼈다. 포인터를 이용해서 주소안에 있는 원본값을 변경해주기 때문에 값이 바뀐다.
함수포인터
내가 만든 기능을 만든것을 다른 사람한테 줄 때
void (*pFunc)(void) = nullptr ;
(반환) (주소) (인자)
출처 : https://www.youtube.com/c/AssortRockGameAcademy
'C++' 카테고리의 다른 글
C++ void (0) | 2022.06.06 |
---|---|
C++ 상수(const) (0) | 2022.06.05 |
C++ 정적 변수 & 외부 변수 (0) | 2022.06.01 |
C++ 분할구현 (0) | 2022.06.01 |
C++ 지역변수,전역변수 (0) | 2022.05.30 |