티스토리 뷰
이전 글: 3. 배열과 문자열에서 계속
포인터 변수
"포인터 변수란 메모리의 주소 값을 저장하기 위한 변수이다."
& 연산자: 피연산자의 주소값을 반환하는 연산자
포인터 변수의 크기는 하드웨어와 운영체제에 따라 달라진다.
32비트 시스템에서는 주소값을 32비트로 표현하기 때문에 포인터 변수의 크기는 4 바이트,
64비트 시스템에서는 64비트로 표현하기 때문에 8바이트 크기를 갖는다.
int * : int 형 포인터
double * : double 형 포인터
int num1 = 5;
double *pnum1 = # // 변수의 자료형에 맞지 않는 포인터 변수의 선언은 문제가 될 수 있다.
// (컴파일 에러는 발생하지 않는다)
int *ptr1 = 0; 또는
int *ptr2 = NULL;
0과 NULL의 의미는 동일하며, 모두 '널 포인터'를 의미한다.
'널 포인터'는 "아무 것도 가리키지 않는다!" 라는 뜻!
포인터와 배열
배열의 이름은 포인터이다. 단, 그 값을 바꿀 수 없는 '상수 형태의 포인터'이다.
그래서 배열의 이름을 '포인터 상수'라고도 한다.
int형 포인터를 대상으로 n 증가 = n x sizeof(int) 크기만큼 증가
double형 포인터를 대상으로 n 증가 = n x sizeof(double) 크기만큼 증가
==> TYPE 형 포인터를 대상으로 n의 크기만큼 값을 증가/감소 시, n x sizeof(TYPE)의 크기만큼 주소 값이 증가/감소한다.
포인터의 증감 연산으로 배열처럼 접근할 수 있다.
즉, arr[i] == *(arr + i)
문자열 배열과 포인터
char str1[] = "My String"; // 변수 형태의 문자열
char *str2 = "Your String"; // 상수 형태의 문자열
str1과 str2 모두 문자열의 시작 주소 값을 담고 있다.
단, str1은 항상 배열을 가리키는 상태여야 하지만 str2는 다른 위치를 가리킬 수 있다.
상수 형태의 문자열은 변경할 수 없다.
예) str2[0] = 'X'; // 안된다.
상수 형태의 문자열은 먼저 문자열이 메모리 공간에 저장된 후 그 주소값을 반환한다.
printf("abc"); 에서 넘기는 것도 동일하다.
예를 들어, WhoAreYou("hong")과 같은 함수를 호출했다면,
void WhoAreYou(char *str) 과 같이 되어 있어야 한다.
포인터 배열
포인터 배열: 포인터 변수로 이뤄진 배열
주소값의 저장이 가능한 배열
int* arr[3] = {p1, p2, p3};
(즉, 배열의 인자로 포인터가 들어있다)
문자열 포인터 배열
char * strArr[3] = {"Simple", "String", "Array"}
(즉, 배열의 인자로 문자열 포인터가 들어있다.
문자열은 자동으로 생성되어 첫 번째 문자의 주소를 리턴한다)
포인터와 함수
int main(void)
{
int arr[3] = {1, 2, 3};
ShowElement(arr);
}
void ShowElement(int *arr) // 동일하다.
void ShowElement(int arr[]) // 참조로 넘길 수 있다.
Call-by-value vs Call-by-reference
Call-by-value : 단순히 값을 전달
Call-by-reference : 메모리 접근에 사용되는 주소값을 전달
int num;
char str[30];
scanf("%d", &num); // 입력을 받아 num에 할당
scanf("%s", str); // str 자체가 배열의 주소
포인터 대상의 const 선언
const int *ptr = # // 포인터 변수 ptr을 이용해서 ptr이 가리키는 값을 변경하는 것을 허용하지 않는다. (*ptr=40 안됨)
int * const ptr = # // 한 번 가리키기 시작한 변수를 끝까지 가리켜야 한다. (ptr=&num2 안됨)
다음 글: 5. 다차원 배열과 포인터
반응형
댓글
공지사항