배열 탐험 신비의 세계, 진실은 저 너머에 I
보통은 다른 책에서 배열과 포인터를 따로 다루는 게 일반적입니다.
하지만 배열과 포인터는 떼려야 뗄 수 없는 아주 밀접한 관계를 맺고 있습니다. 포인터 없이 배열을 설명하면 반의 반쪽도 안됩니다. 바둑판 몇 개를 그려놓고 끝내야 하고 그러면 여러분도 편하고 저도 편하고 이 세상(?) 모두가 편해집니다. 이게 무슨 이편한세상인줄 압니까?
그다지 어려워 보이지도 않지만 그것은 C에서 말하고 있는 진짜 배열이 아니었습니다.
C의 배열을 제대로 알기는 정말 힘들지만 한번 잘 이해하면 그 어렵다는 포인터는 아주 쉬워집니다. 조금 힘들고 어렵더라도 제대로 배열과 포인터를 함께 설명하겠습니다.
만약에 지금 이 자리에서 여러분들이 그깟 배열쯤이야 라고 생각한다면 큰 오산입니다. 저도 그렇게 생각했다가 큰 코 다쳤습니다. 그것도 한두 번이 아닙니다.
배열은 결코 배가 열 개 있는 게 아닙니다. 무가 열 개 있어 열무가 아니지 않습니까? 아, 무열인가요?
배열이 없다뇨? 그럼 그 동안 우리가 써왔던 배열은 대체 머란 말입니까?
그러게요…
제가 가르치는 수업에서 첫시간 마다 배열이 모죠? 라고 물으면 대부분의 프로그래머들이 같은 타입 고정 사이즈의 데이터 묶음이라고 대답합니다.
그리고 대부분의 C프로그래밍 책들이 배열을 설명할 때 수학의 행렬을 이용해서 설명합니다.
다시 한번 얘기합니다. C언어에서 수학에서 말하고 있는 행렬식 바둑판 배열은 존재하지 않습니다.
만약 그런 것이 존재한다면 C 프로그램은 설명할 수 없는 코드투성이가 됩니다.
제대로 된 배열의 설명을 위해서라면 이렇게 배열이 없다는 극단적이고 자극적인 제목을 달아서라도 여러분들에게 이것을 명확히 알렸으면 하는 작은 소망이 있습니다.
제가 우선 배열의 진실을 설명하기 전에 먼저 여러분들이 가슴에 손을 얹고 정직하게 대답해야 할 질문들이 여기에 몇 가지 있습니다.
왜 배열의 인덱스를 0부터 시작할까요?
배열 인덱스로 -1을 사용할 수 있나요?
배열 사이즈를 넘어서는 인덱스를 사용하면 정말 컴파일이 안되나요?
iArr[3]을 3[iArr]로 사용하거나, "Sinclair"[2]를 사용하면 컴파일 에러가 발생하나요?
왜 배열 이름이 배열의 시작 주소일까요?
정말 배열 이름은 상수 포인터 인가요?
for문을 단 하나만 사용하여 다차원 배열을 초기화 할 수 있을까요?
여러분은 이 가운데 몇 가지를 확실히 대답할 수 있나요?
정답이 궁금하죠? 얼른 빨리 대답하라구요? 여러분들은 지금 우물에서 숭늉을 찾고 있습니다. 제가 이것들을 설명하기 위해 이 { Sinclair ˚C* }를 쓰고 있습니다. 그러니 이제부터 차근차근 함께 공부해 나가도록 하겠습니다.
앞에서 설명했듯이 배열은 연산자 입니다.
다시 한번 이야기합니다.
배열이 연산자 인 것을 안다면 C프로그래밍이 좀 더 쉬워집니다. 하지만 지금까지 단 한번도 연산자로 접근해 본 적이 없으니 이렇게 설명하는 것은 받아들이기 너무 어려울 수 있습니다.
이미 우리 모두가 알고 있는 것처럼 바둑판 식 행렬 배열이 한번에 이해하기는 보다 쉽습니다.
하지만 그 바둑판 식 행렬 배열이 끼치는 악영향에 대해 적으라면 책 한 권으로도 부족할 정도 입니다.
이제부터 패러다임을 조금 바꿔야 합니다.
K&R께서 연산자로 만든 배열을 우리는 바둑판을 그려놓고 이해했습니다.
지금까지 우리가 이해하고 있는 1차원 배열과 2차원 배열은 다릅니다.
다차원 배열은 아예 제대로 사용하지도 못합니다.
그래서 3차원 이상의 다차원 배열을 설명하는 책이 거의 없습니다.
대부분 그냥 사용할 필요가 없다고 말합니다.
하지만 대부분의 컴파일러들이 최소한 16차원까지 배열을 사용할 수 있도록 지원하고 있습니다.
만일 숫자 두 개를 더하는 방법과 열 여섯 개를 더하는 방법이 달라진다면 우리의 인생이 얼마나 더 힘들어 지겠습니까? 곱셈하는 방법이 자릿 수 마다 달라지면 구구단은 대체 왜 모할려고 외운겁니까?
우리가 이미 배운 대로 모든 연산자에는 의미가 있습니다. 앞에서 우리는 수많은 연산자들의 의미를 배웠습니다. 기억합니까? 그 때 배열 연산자를 다른 글타래에서 설명하겠다고 말했습니다. 모든 연산자가 한가지 의미만을 갖고 있지는 않습니다. 일반적으로 이항 연산자 +는 숫자인 피연산자 둘을 더하라는 것입니다. 하지만 Java에서는 문자열을 결합하는 strcat() 함수의 의미도 갖고 있습니다. C++에서는 아예 연산자의 의미를 확장하거나 변경하여 사용할 수도 있습니다. 다행인지 불행인지 C에서는 이미 정해진 연산자의 의미를 바꿀 수 없습니다. 개인적으로 저는 다행이라고 생각합니다. ㅎㅎㅎ~ 이렇게 덧셈 연산자도 두 가지 이상의 정해진 의미를 가질 수 있는 것처럼 배열 연산자도 C언어에서는 메모리를 할당하고 메모리를 참조하는 두 가지 의미를 가지고 있습니다.
#Sinclair #씽클레어 #싱클레어 #씽클레어도씨 #씨언어 #씨프로그래밍 #C언어 #Cprogramming #C_Programming #C #Programming #Clanguage #C_Language