C언어 공부 16
C가 데이터를 값으로 전달하는 이유는, 데이터의 무결성을 유지하기 위해서 이다.
함수의 의도가 배열 내용을 변경하지 않는 것이라면, 프로토 타입과 함수 정의에서 형식 매개변수를 선언할 때 키워드 const를 사용하는 것이다.
const는 상수배열, 상수 포인터, 상수를 가리키는 포인터 등을 만들 수 있다.
일반적으로, 상수를 가리키는 포인터는, 데이터를 변경하는데 포인터를 사용하지 않는 함수에 함수 매개변수로 사용된다.
함수 매개변수에서 const를 사용하면 데이터를 보호할 뿐만아니라 그 함수가 const로 선언된 배열을 가지고 작업하는 것을 허용한다.
const는 몇가지 다른용도로도 사용할 수 있다. 예를들면, 다른곳을 가리킬 수 없도록 포인터를 선언하고 초기화 할 수 있다. 이 테크닉은 키워드 const를 놓는 위치에 비결이 있다.
double rates[5] = {88.99, 100.12, 59.45, 183.11, 340.5};
double *const pc = rates; //pc는 배열의 시작을 가리킨다.
pc = &rates[2]; //허용안된다.
*pc = 92.99 //허용된다. rates[0]을 수정한다.
이와같은 포인터는 여전히 값을 변경하는데 사용할 수 있지만, 처음에 대입된 위치만 가리킬 수 있다.
가리키는 곳도 변경할 수없고 가리키는 값도 변경할 수 없는 포인터를 작성하기 위해 const를 두번 사용할 수 있다.
const double * const pc = rates;
int zippo[4][2]; 가 있다고 가정한다.
포인터나 주소에 1을 더하는 것은, 그것이 가리키는 객체의 크기만큼 값을 증가시킨다. 이점에서 볼때, zippo와 zippo[0]은 다르다. 왜냐하면 zippo는 int형 2개 크기의 객체를 참조하고, zippo[0]는 int형 1개 크기의 객체를 참조하기 때문이다. zippo+1은 zippo[0]+1과는 크기가 다르다.
*연산자를 사용하여 또는 각괄호와 인덱스를 사용하여 포인터나 주소의 내용을 참조하는 것은, 그것이 가리키는 객체의 값을 제공한다.
zippo[2][1]과 포인터 표기 *(*(zippo+2)+1)이 동등하다.
zippo <-배열의 첫번째 원소(int형 2개짜리 배열)의 주소
zippo+2 <-배열의 세번째 원소(int형 2개짜리 배열)의 주소
*(zippo+2) <-배열의 세번째 원소인, int형 2개짜리 배열의 첫번째 원소(하나의 int)의 주소
*(zippo+2)+1 <-배열의 세번째 원소인, int형 2개짜리 배열의 두번째 원소(하나의 int)의 주소
*(*(zippo +2)+1) <-세번째 행, 두번째 열에 저장되어 있는 하나의 int형 값(zippo[2][1])
배열 이름과 포인터 둘중 어느것을 가지고 있으면, 개별적인 원소들을 배열 표기를 사용하여 나타낼 수 있고, 포인터 표기를 사용하여 나타낼 수 있다.
c++에서 비 const 포인터에 const포인터를 할당하도록 허용하지 않지만 C에서는 이 할당이 가능하다.
컴파일러는 배열 표기를 포인터 표기로 변환한다.
일반적으로, N차원 배열에 대응하는 포인터를 선언하려면, 가장 왼쪽의 각괄호를 제외한 모든 각괄호에 값을 제공해야 한다. 왜냐하면, 첫번째 각괄호가 포인터를 나타내고, 나머지 각괄호들은 가리켜지는 객체의 데이터형이기 때문이다.
가변길이 배열 (variable Length Array : VLA) 역시 한번 생성되면 같은 크기를 유지한다. "가변" 이라는 말을 처음 배열을 만들 때 배열의 차원을 지정할 때 변수를 사용할 수 있다는 뜻이다.
가변길이 배열은 동적 메모리 할당을 허용한다. 이것은, 사용자가 프로그램이 실행되는 도중에 배열의 크기를 지정할 수 있다는 것이다.
리터럴은 기호가 아닌 상수를 말한다.
C는 배열을 유도 데이터형(drived type)으로 취급한다. 그 이유는, 다른 데이터형에 기초하여 만들어지기 때문이다.
배열을 처리하는 함수에서 배열 이름을 실전달 인자로 사용할 때, 전체 배열을 함수에 전달하는 것이 아니다. 단지 배열의 주소만을 전달하는 것이다.
배열은 데이터형이 모두 동일한 원소들의 집합이다. 배열의 우너소들은 메모리에 연속적으로 저장되고, 정수 인덱스를 사용하여 접근할 수 있다. 포인터에 정수를 더하거나 증가시키면, 그 포인터의 값이 그것이 가리키는 객체(object)의 바이트 수만큼 증가된다.