본문 바로가기

C Langauage

Chapter 8. 포인터(Pointer)

Chapter 8. 포인터(Pointer)
1. 포인터
 - 포인터
  · 다른 변수의 주소를 저장하는 변수
  · 포인터 또한 변수이기 때문에 포인터 변수라고도 한다.
  · 포인터 변수의 크기
  ◦ 포인터 변수의 크기는 시스템의 주소 값 크기에 따라 달라진다.
  ◦ 16bit 시스템 : 주소값 크기가 16bit이기 때문에 포인터 변수의 크기가 16bit(2byte)가 된다.
  ◦ 32bit 시스템 : 주소값 크기가 32bit이기 때문에 포인터 변수의 크기가 32bit(4byte)가 된다.
 - & 연산자
  · 변수의 주소를 구할 수 있게 해주는 연산자
  · 배열의 주소를 &연산자를 이용해 구하면 배열의 요소 중 가장 앞의 변수인 0번 변수의 주소를 구해준다.

  · scanf 함수에서 &를 사용하는 이유
  ◦ scanf 함수 또한 함수이기 때문에 함수외부의 변수에 접근하기 위해서는 주소값이 필요하다.
  ◦ 문자열을 %s와 문자 배열의 이름을 이용해 출력하는 이유 또한 배열의 이름이 주소값을 의미하기 때문이다.
 - 포인터의 선언

 int* pnum;
 int *pnum;
 int * pnum;

  · 포인터를 선언할 때는 주소값을 구하고자하는 변수와 같은 데이터형에 *을 붙여주면된다.
  · *의 위치는 데이터형과 변수명 사이에만 써주면 된다.
  · 포인터는 시스템의 주소값 크기에 따라 2byte 또는 4byte가 된다.
 - * 연산자

연산자

형식

용도

*

변수, 상수

곱하기

a*b;

데이터형 * 변수명

포인터(주소를 저장하는 변수)

int * p;

*포인터명

간접접근(포인터가 가리키는 값)

*p;

  · *연산자는 위치에 따라 용도가 3가지가 있다.
  · 간접접근 : *연산자와 포인터를 이용한 메모리 접근방식
  · 포인터는 간접접근을 하기 위해 데이터형이 필요하고 각 데이터형에 해당하는 변수에만 접근할 수 있다.
 - 포인터의 잘못된 사용

 int *ptr;
 *ptr=200;

  · 위처럼 포인터변수를 어떠한 변수를 가리키지도 않은 상태에서 값을 집어넣으면 포인터 변수는 쓰레기 값으로 초기화되며 값이 저장되는 위치를 알 수가 없게 되어 포인터가 잘못 사용 됐음을 알 수 있다.
 - 널포인터

 int *ptr = 0;
 int *ptr = null;

  · 잘못된 포인터 연산을 막기 위해 특정한 값으로 초기화하지 않는 경우 아무것도 가리키지 않겠다는 의미로 null 또는 0으로 초기화를 한다.

 

2. 배열과 포인터
 - 배열이름의 의미

  · 배열의 이름은 배열의 시작 주소값을 의미하는 포인터이다.
  · 단순히 주소 값이 아닌 포인터인 이유는 *연산자 없이도 메모리 접근에 사용되는 *연산이 가능하기 때문이다.
  · 배열의 주소값은 배열의 첫 번째 요소의 주소값과 같다.
 - 배열이름과 포인터변수

비교

배열

포인터 변수

이름

존재

존재

저장되는 것

메모리의 주소값

메모리의 주소값

주소값 변경

가능

불가능

 - 배열의 포인터 연산

 int arr[3] = {1,2,3};
 *(arr+1);
 *arr+1;

  · 배열은 각 인덱스끼리 주소값이 1씩 차이가나며 만약 *연산자를 이용해 *(배열명+1) 하면 주소값에 1을 더한 배열의 인덱스를 찾아간다. 즉, +1을 하면 두 번째 요소를 찾아간다.
  · 만약 *(배열명+1)에서 괄호를 뺀다면(*배열명+1) *연산자를 먼저 연산해 배열의 첫 번째 인덱스 값에 +1을 한 값을 보여줄 것이다.

 

3. 문자열과 포인터
 - 문자열 리터럴

 char* p="abcde";

  · 문자열 리터럴은 문자열 리터럴의 주소를 의미한다..
  · 포인터 변수를 문자열로 초기화하면 문자열 리터럴이 되는데 이는 포인터 변수에 문자열이 저장되는 것이 아니고 메모리상에서 어떤 자리를 문자열이 차지하게 되고 그 자리의 주소가 포인터 변수에 저장이 된다.
  · 포인터 변수는 상수가 아니므로 다른 문자열로 초기화하면 다른 주소가 저장된다.
 - const 포인터

 const char* p
 char* const p
 const char* const p

  · const가 데이터형 앞에 위치한 경우
  ◦ 포인터가 가리키는 것 : 변경 불가능
  ◦ 주소 : 변경가능
  · const가 데이터형과 변수명 사이에 위치한 경우
  ◦ 포인터가 가리키는 것 : 변경가능
  ◦ 주소 : 변경 불가능
  ·  const가 데이터형 앞과 데이터형과 변수명 사이 두 곳에 위치한 경우
  ◦ 포인터가 가리키는 것 : 변경 불가능
  ◦ 주소 : 변경 불가능

 

4. 포인터의 연산

 int * ip = 0x0010;
 int * p;
 p = ip+1;

 double * dp = 0x0010;
 double * p;
 p = dp+1;

 - 포인터는 주소값이며 주소값에 +1과 같은 값을 더해주는 연산을 한다면 해당 포인터 변수의 메모리 크기만큼 주소값을 더해준다.

   즉, int 포인터형은 4byte, double 포인터형은 8byte씩 증가하기 된다.
 - 주소값
  · 변수의 주소값은 실제로 선언할 때마다 점점 감소하는데 이는 메모리상에서 변수가 선언될 때마다 뒤에서부터 메모리가 할당되기 때문이다.
  · 반면에 배열의 인덱스별 주소값은 점점 증가하며 메모리상에서 하나의 배열은 배열의 첫 번째 인덱스부터 끝 인덱스까지 모두 한 번에 할당되기 때문에 인덱스 번호가 커질수록 주소값도 커진다.
  · 주소값의 예

 

5. 포인터와 함수
 - 함수의 데이터 전달 방법

  · Call-by-Value
  ◦ 값에 의한 전달방법으로 함수를 단순히 값을 전달하는 형태의 함수로 호출하는 것
  ◦ 함수 외부의 선언된 변수에 접근이 불가능하다.
  ◦ 함수 외부의 선언된 변수에 접근이 불가능하기 때문에 함수의 연산결과를 변수에 저장해야 함수 외부에서 결과를 볼 수 있다.
  · Call-by-Reference
  ◦ 주소에 의한 전달방법으로 함수를 메모리 접근에 사용되는 주소 값을 전달하는 형태의 함수로 호출하는 것
  ◦ 함수 외부의 선언된 변수에 접근이 가능하다.
  ◦ 함수 외부의 선언된 변수에 접근이 가능하기 때문에 함수를 통해 연산만 해주면 된다. 


'C Langauage' 카테고리의 다른 글

Chapter 10. 전처리기(Preprocessor)  (0) 2015.08.05
Chapter 9. 문자열(String)  (0) 2015.08.05
Chapter 7. 함수(Function)  (0) 2015.08.05
Chapter 6. 배열(Array)과 문자열(String)  (0) 2015.08.05
Chapter 5. 제어문  (0) 2015.08.05