이중배열과 포인터 배열이란 모두 배열이다. 생각보다 금방 끝날 주제이다.
이중배열이란 배열 안에 배열을 넣겠다는것이다. 다음을 보자
int iArr[2][3] = {0,1,2,3,4,5};
이는 3개짜리 배열 2개를 선언한 것이다. 선언에 관해서는 자세히 설명하지 않겠다. 모르겠으면 앞에 배열을 봐라.
하지만 저렇게 선언하면 아무런 문제가 없긴 하지만. 다른사람이 본다면 저것이 어떻게 나뉘어있는지 한눈에 구분하기 쉽지 않다. 그래서 이런식의 선언 또한 가능하다.
int iArr[2][3]={
{0,1,2},
{3,4,5}
}
확실히 배열이 어떤구조인지 눈에 보인다.
그럼 이중배열의 값을 불러내보자. 특별할거 없다.
iArr[0][0];
이렇게 하면 iArr의 첫번째 값인 0값을 받을 수 있고 또한 대입연산자 =를 사용해 그 값을 변경할 수 있다.
이전과같이 배열의 요소들은 0부터 순서대로 번호표를 받기때문에 iArr[2][3]같은 행동은 하지 않길 바란다.
배열의 이름은 그 배열의 포인터라고 했었다. 이중배열도 마찬가지지만 약간의 차이가 있다. 조금 어렵고 나도 이걸 잘 설명할 수 있을지 모르겠다.
iArr는 이전과 동일하게 iArr배열의 첫번째 주소값이다. 이건 이전과 동일하다.
하지만 iArr[1]을 하면 어떨까??
이또한 주소값을 반환한다. 이중배열중 두번째 배열의 첫번째 주소값을 반환한다.
즉
*iArr[1]; 이라고 불러낸다면 3이 나온다는 것이다.
iArr는 배열의 첫번째 주소값이라고 말했었다. 그렇다면 그 값을 추출하기 위해 앞에 *을 붙여서
*iArr 를 출력하게된다면 어떻게 될까?? 혹시 그 값이 예상이 되는가??
0이라고 했다면 감사합니다. 속아주셔서
배열 포스팅에서 "배열명[ n ]" 연산자는 그로부터 n칸 이동한 값을 불러오라고 했었는데. 그것이 곧 *(배열명 + n) 과 동일한 기능이라고 했었다.
그럼 *iArr는 그 뒤에 상수연산이 없으니 자연히 iArr[0]과 동일하다.
iArr[0]은 첫번째 묶음의 주소값이니 그것만을 출력했으면 포인터값을 보게 되었을것이다.
iArr = 이중배열 전체의 가장 앞 주소값
iArr[0] = 이중배열 중 첫번째 묶음의 가장 앞 주소값
iArr[0][0] = 이중배열중 첫번째 묶음의 첫번째 값 (즉 0)
이것이 가볍게 설명하면 되게 단순하지만, 생각보다 실수를 많이하게된다.
이전에 배열에 대해 설명할때, 배열의 크기를 알아보는 공식을 적어주었었다.
sizeof(배열명)을 이용하여 배열의 총 바이트 수를 구한 뒤, 배열의 자료형 타입의 바이트수를 나누어 배열의 크기를 구할 수 있다고 했었다.
모르겠으면 이전글을 한번 보고오자. 다시설명하기 귀찮다.
그렇다면 sizeof(iArr)는 배열의 총 크기 6과 int형의 바이트수 4가 곱해진 24가 나오게 된다.
그럼 sizeof(iArr[0])은 어떨까?? 우리는 int형 3개 묶음 2개를 선언했기 때문에 그중 첫번째묶음인 3개와 int의 바이트수 4를 곱한 12를 반환하게 된다.
sizeof(iArr) = 24 ( 2 * 3 * 4 ) 앞의숫자 * 뒤의숫자 * 자료형 바이트수
sizeof(iArr[]) = 12 ( 3 * 4 ) 뒤의숫자 * 자료형 바이트 수
sizeof(iArr[][]) = 4 자료형 바이트 수
정리가 되었는가? 추후에 배열을 만지다가 실수하지 않길 바란다.
솔직히 이거 적다가 조금 두서없다는 생각이 들었다. 아마 이해가 잘 안되셨다면 죄송하다. 원래 내가 말을 두서없이 나오는대로 하는 사람이다. 다시한번 읽어보시고 이해가 안되신다면 부디 댓글 부탁드린다. 다시적어볼랑께
이전에 배열을 선언하면 모든 요소들이 여유공간 없이 정렬된다고 했었다. 이중배열도 마찬가지이다. 모든 데이터는 각각의 자료형에 딱맞는 사이즈의 공간만을 점유하고 그 사이 여유공간은 전혀 없다.
굳이 그려보자면 다음과 같다
{{0,1,2},{3,4,5}} 다만 중괄호는 우리가 보기 편하기 위해 적은것이니 무시해도 무방하다.
그렇다면 이런짓 또한 가능하다는 것이다.
iArr[0][5] 를 출력한다면 첫번째 묶음의 처음에서 여섯칸 이동한 (0부터 숫자센다고 했다.) 5가 출력된다.
iArr[1][-1] 를 출력한다면 두번째 묶음의 처음에서 앞으로 한칸 이동한 2가 출력된다.
그렇다면 뭐하러 이중배열을 하지?? 6칸짜리 일반 배열을 선언하는것과 다를바가 없잖아??
맞다. 다만 이중배열을 선언하는 이유는 사람이 편하기 위해서이다. 컴퓨터가 하는일은 모두 같다.
예를들어 한반에 서른명인 반이 다섯반 있다고 하자. 운동장 조회를 위해 모든반이 나왔을때 줄을 어떻게 세우겠는가
당연히 각 반마다 한줄씩 다섯줄 세울것이다. 모든150명의 학생을 한줄로 나열하게 된다면 어디부터 2반이고 3반인지 알기가 쉽지 않다. 그러니 데이터 또한 잘라서 한 세트씩 보는것이다.
위의 행위가 가능하다는것이지 이렇게 접근하라는 소리가 아니다. 결코 좋은 접근이 아니다.
다만 프로그램을 돌리다보면 간혹 저런경우가 생길 수가 있지만 컴파일러는 무엇이 잘못되었는지 알지 못하니 사람이 조심하자는 말이다.
좋다. 이중배열이 끝났다.
이제 삼중배열이다.
농담이다. 이중배열과 동일하게 배열명 뒤에 대괄호 숫자만 늘리면 삼중, 사중, 오중 배열 모두 가능하다. 다만 권장드리진 않는다. 애초에 배열을 선언하는것이 데이터의 관리를 편하게 하기 위함인데. 4중 이상의 배열을 과연 사람이 감당할 수 있을지 모르겠다.
포인터 배열이다. 쥬신 선생님께서 말씀하셨다.한국말은 끝까지 듣고 마지막이 본론이라고, 이또한 배열이다.
다만 그 내용물이 포인터일 뿐이다. 선언방법은 다음과 같다.
자료형 * 배열명 [배열의 크기] = {포인터 ,포인터 들~~~};
놀랍다. 놀랍도록 별거 없다. 다만 나는 아직 이것을 쓴적이 없다. 책에 나와있고, 수업을 들었기에 정리하는것 뿐이다.
내가 여기서 얻어간것은
어떤 자료형이 있다면 모두 배열화하여 여러가지를 한번에 선언하고, 정리할 수 있다. 라는것을 깨달았었고 실제로 그 깨달음을 사용할 일이 조만간 온다. 사용자 정의 자료형에서 다시 언급할 내용이다. 신경 안써도 좋다.
이상 이중배열과 배열포인터를 마친다.