
1. 함수의 인자로 배열 전달하기
void Func1(int* arr)
{
sizeof(arr); //포인터 변수 arr의 크기 반환
}
void Func2(int* arr, int num) //main함수에서 arr의 크기를 받음
{
}
int main(void)
{
int arr[3]={1,2,3};
Func1(arr);
Func2(arr, sizeof(arr)/sizeof(int));
return 0;
}
"배열의 주소 값을 인자로 전달받는 매개변수는 포인터 변수이기 때문에 이를 대상으로 sizeof 연산을 할 경우,
배열의 크기가 반환되지 않고 포인터 변수의 크기가 반환된다."
"이렇듯 함수 내에서는 인자로 전달된 배열의 길이를 계산할 수가 없기 때문에,
배열의 크기나 길이정보도 함께 인자로 전달해야 한다."
2. Call-by-value vs Call-by-reference
함수를 호출할 때 단순히 값을 전달하는 형태의 함수호출을 가리켜 Call-by-value라 하고, 메모리의 접근에 사용되는 주소 값을 전달하는 형태의 함수호출을 가리켜 Call-by-referenc라 한다.
3. scanf 함수호출 시 &연산자를 붙이는 이유
int main(void)
{
int nun;
scanf("%d", &num);
...
}
위의 scanf함수호출이 완료되면 변수 num에는 값이 채워진다.
즉 프로그램 사용자로부터 값을 입력 받아서 변수 num에 그 값을 채우는 일을 scanf함수가 하는 것이다.
그리고 이를 위해서 scanf함수는 변수 num의 주소 값을 알아야 한다.
그래야 변수 num에 접근을 해서 값을 채워 넣을 수 있기 때문이다.
그래서 scanf함수호출 시에 변수 num의 주소 값을 전달하고 있다.
이제 변수 num의 앞에 &연산자를 붙이는 이유를 알겠는가?
이렇듯 scanf함수의 호출도 Call-by-reference형태의 함수호출에 해당한다.
그렇다면 문자열을 입력 받을 때에는 왜 & 연산자를 붙여주지 않았던 것일까?
이와 관련해서 다음 코드를 보자.
int main(void)
{
char str[30];
scanf("%s", str);
...
}
이전에도 보였듯이 문자열은 위와 같은 방식으로 입력 받는다.
그리고 문자열이 저장될 배열의 이름 str의 앞에는 &연산자를 붙이지 않는다.
str은 그 자체로 배열의 주소 값이기 때문이다!
그냥 str을 전달하면 배열의 주소 값이 전달되지 않는가!
따라서 & 연산자를 붙일 이유가 없는 것이다.
4. 포인터 대상의 const 선언
int num1=20;
int num2=30;
const int* ptr1 = &num1;
*ptr1=20 //불가능
int* const ptr2 = &num1;
ptr2=&num2
첫 번째 const선언은 포인터 변수 ptr1을 이용해서 ptr1이 가리키는 변수에 저장된 값을 변경하는 것을 허용하지 않는다는 뜻이다.
두 번째 const선언은 포인터 변수 ptr2을 상수로 만들어 한 번 주소 값이 저장되면 그 값의 변경이 불가능하게 된다.(포인터 상수)