상세 컨텐츠

본문 제목

[C++] 포인터 변수, 배열과 포인터

프로그래밍언어/C++

by 밍구21 2020. 5. 26. 17:17

본문

//포인터 정의

포인터 변수는 포인터라고도 한다.

 

일반적인 변수는 데이터의 값(정수, 실수 문자 등)을 저장한다.

포인터데이터의 값이 저장된 변수의 메모리 주소를 저장한다.

 


 

//포인트 선언 - 데이터 타입* 포인터로 선언할 변수 이름

포인트 선언에서 가장 중요한 건 *(애스터리스크)다.

각 변수 이름 앞에 *를 붙여야 한다.

다른 일반적인 변수들과 마찬가지로 포인트 변수 또한 사용되기 전에 선언이 되어야 한다.

ex)

 

 

 

+포인트 선언 시 주의할 점

 

 

다음은 두 개의 포인터를 선언한 것 같지만 실제로는 

 

 

이렇게 입력한 것과 같다.

 

그러므로 두 개의 포인터를 선언할 때는

 

 

이렇게 각각 하자!


 

//주소 할당- 포인터 이름 = &포인터에 주소를 할당할 변수 이름

포인터가 선언된 이후에는 포인터에 변수의 주소를 할당할 수 있다.

변수 앞에 &(앰퍼샌드) 기호는 주소 연산자이다.

 

 

포인터의 데이터 타입과 변수의 데이터 타입이 다른 경우에는 구문 오류가 발생하니 주의하자.

 

다음은 포인터 Pming에 ming 변수의 주소를 할당한 코드이다.

변수 ming의 주소는 &ming으로 나타내고 포인터 Pming에 그 주소를 할당해줬다.


 

 

다음은 변수의 주소를 출력하는 코드이다.

하나는 주소 연산자를 이용직접 해당 변수의 주소를 출력할 것이고

다른 하나는 주소를 할당해준 포인터 값을 이용해 간접적으로 그 변수의 주소를 출력할 것이다.

 

그 결과, 출력 값은

 

 

같다.

 


참고로 데이터 타입에 따라 변수의 바이트 크기가 다 다르다.

종류 데이터 타입 메모리 크기 (바이트 수)
정수형 char 1
short 2
int 4
long 4
실수형 float 4
double 8

참고로 문자열의 문자수 따라 메모리 크기가 변하는 string형은 문자열이 선언된 이후에 문자열에 대한 메모리 주소가 고정된다.

 

변수의 주소해당 변수에 할당된 첫 번째 바이트의 주소이다.

그렇게 때문에 그 변소의 주소를 할당한 포인터도 해당 변수에 할당된 첫번째 바이트의 주소를 나타낸다.

 


//간접 참조(역참조) - *포인터 이름

포인터를 통해 해당 변수의 값을 간접적으로 읽는 것을 간접 참조라고 한다.

 

 

 

다음은 변수 ming의 값을 출력하는 코드이다.

하나는 변수 ming을 직접 출력해 값을 읽어낸다.

나머지 하나는 포인터 변수를 이용해 간접적으로 읽어낸다.

 

 

결과는 물론 같다.

 


//포인터 연산

간접 참조를 이용해 연산 또한 가능하다.

 

 

위와 같은 코드를 입력하면 아래와 같은 값이 출력된다. 

 

Pming은 위 간접참조에 입력된 것과 같이 정수 219를 가진 변수 ming의 주소가 할당돼있다.

 

Pming = 은 포인터 Pming에 저장된 변수 ming의 주소
Pming + 1 = 은 변수 ming의 주소 + 1 * 데이터 타입의 메모리 크기인 주소
*Pming = 은 포인터 Pming에 저장된 주소인 변수 ming에 저장된 값
*Pming + 1 = 포인터 Pming에 저장된 주소인 변수 ming에 저장된 값 + 1
*(Pming) = 포인터 Pming에 저장된 주소인 변수 ming에 저장된 값
*(Pming) + 1 = 포인터 Pming에 저장된 주소인 변수 ming에 저장된 값 + 1
*(Pming + 1) = Pming + 1인 주소에 할당된 값 (내가 따로 값을 할당해준 적이 없으므로 쓰레기 값이 출력된다.)

을 출력한다.

 

 


 

//포인터 증감 연산

일반 연산과 마찬가지로 증감 연산 또한 가능하다.

 

 

다음 코드를 이용해 포인터를 이용한 증감 연산을 해보겠다.

val = *Pming++ val = (*Pming)++ val = *++Pming val = ++*Pming






→4만큼 늘어난 Pming의 주소엔 할당된 값이 없으므로 *Pming은 쓰레기값 출력
val에 *Pming값을 대입한 후 *Pming값 증가

→val엔 기존 *Pming값인 219가 출력

→주소값인 Pming은 건든적 없으니 그대로 출력

→*Pming은 증가된 값이 출력



→val에는 4만큼 늘어난 Pming의 주소에 할당된 값이 없으므로 쓰레기값 출력
주소 값인Pming은 int데이터 크기인 4만큼 증가

→4만큼 늘어난 Pming의 주소엔 할당된 값이 없으므로 *Pming은 쓰레기값 출력


→val에는 증가된 *Pming값인 220이 출력

주소값인 Pming은 건든적 없으니 그대로 출력

*Pming은 증가된 값이 출력

 

 

 


//배열과 포인터

 

 

 

괄호[]를 없앤 배열(위 코드에서는 arr)은 출력하면 배열의 시작 주소를 나타낸다. 이런 점에서 배열은 근본적으로 포인터이다.

위 코드대로 하면

arr는 arr의 첫 번째 요소의 주소를 

arr + 1은 arr의 두 번째 요소의 주소를 

arr + 2는 arr의 세 번째 요소의 주소를 

arr + 3은 arr의 네 번째 요소의 주소를 

arr + 4는 arr의 다섯 번째 요소의 주소를  나타낸다.

 

왜냐하면 아까 위에서 언급했다시피 포인터 + 1은 포인터 + 1 * 데이터 타입의 바이트 크기이기 때문이다.

 

그러므로

*(arr)는 arr의 첫 번째 요소의 주소에 할당된 값인 1을

*(arr + 1)는 arr의 두 번째 요소의 주소에 할당된 값인 3을

*(arr + 2)는 arr의 세 번째 요소의 주소에 할당된 값인 5를

*(arr + 3)는 arr의 네 번째 요소의 주소에 할당된 값인 7을

*(arr + 4)는 arr의 다섯 번째 요소의 주소에 할당된 값인 9를 출력한다.

 

일반적으로 배열의 요소를 출력할 때 사용하는 배열 이름[인덱스]과 같은 역할을 한다.

 

 

출력 결과를 보면 두 가지 방법 모두 같은 결과를 나타냄을 알 수 있다.

 

 


 

아래의 코드는 위와는 다르게 포인터를 직접적으로 배열처럼 사용하였다.

인덱스를 갖는 포인터를 사용해 배열처럼 사용할 수 있다.

 

 

+주의해야 할 점

배열의 주소를 포인터에 입력할 때는 주소 연산자(&)를 사용하지 않는다.

위에서 언급했다시피 배열 이름 자체가 배열의 시작 주소이기 때문이다.

 

 

 

네 가지 방법은 모두 동일한 값을 출력한다.

 

 


//함수 호출에서 포인터 인수 전달

 

함수가 인수를 전달하기 위한 방법이 여러 가지 있다.

그중 하나는 포인터 인수를 전달하는 방법이다.

 

 

 

main함수의 n1과 n2 주소가 swap함수의 n1과 n2에 전달되므로 두 함수의 n1끼리 n2끼리 각각 같은 메모리 위치를 참조하게돼 swap 함수에서 두 값이 교환될 수 있다.

'프로그래밍언어 > C++' 카테고리의 다른 글

[C++] 문자열 함수와 스트링 클래스 함수  (0) 2020.04.14

관련글 더보기