티스토리 뷰

728x90

프로그래밍 언어에서 여러가지 타입의 기반이 되는 가장 원초적인 데이터 타입을 스칼라(Scalar) 타입이라고 합니다. 예를 들어 int, short, char, float, double등이 C언어의 대표적인 스칼라 데이터 타입입니다. 여러가지 데이터가 모여서 하나의 변수처럼 사용할 수 있는 데이터 타입도 있는데 대표적인 것이 배열(Array)과 구조체(Structure)입니다. 실제 프로그래밍 과정에서도 배열과 구조체 없이는 프로그래밍이 불가능할 정도로 매우 중요한 요소입니다. 

배열은 동일한 데이터 타입의 집합으로 각 항목은 첨자(Index)로 접근합니다. int a[10][10]; 처럼 대괄호 속에 배열의 크기를 지정하여 선언하지만 첨자는 0부터 시작하기 때문에 a[0][0]부터 a[9][9]까지 접근할 수 있습니다.

28. 다음 프로그램의 출력 결과는 무엇인가?
    int arr[10] = {0, 9, 8, 4, 0, 0, 1, 2, 0, 1}, cnt = 0, i;
    for (i = 0; i < 9; i++) {
        arr[i + 1] += arr[i];
    }
    printf("%d\n", arr[7] - arr[2]);
① 3 ② 5 ③ 7 ④ 13 ⑤ 15

위의 문제는 배열의 선언과 초기화(Initialization), 사용을 모두 다뤄 볼 수 있는 문제입니다. arr[10]은 원소의 개수가 10으로 각 원소에 접근할 수 있는 첨자(index)는 0~9입니다. barr[10][10][10]으로 정의했다면 원소의 개수는 10*10*10으로 3차원 배열이지만 사용법은 1차원 배열과 다를 것은 없습니다. 

배열 초기화의 경우 위의 예제의 경우 10개의 원소 전부에 값을 초기화 했지만, "int arr[10] = { 0, 9, 8};"와 같이 원소의 개수보다 적은 값을 초기화하는 경우에는 나머지 원소는 0으로 최기화 합니다. 만약에 배열 전체를 0으로 초기화하고 싶다면 "int arr[10] = { 0 };"과 같이 사용하면 됩니다. 

위의 문제에서 arr은 배열의 이름으로 배열의 이름은 첫원소가 위치하는 곳의 시작 위치를 알려주는 포인터(Pointer)와 같습니다.  결과적으로 arr은 &arr[0]와 같은 의미가 되기 때문에 배열명을 포인터 연산에 활용할 수는 있지만 동일한 타입과 동일한 크기의 배열이라고 b_arr = a_arr; 처럼 배열 연산으로 사용할 수는 없습니다. 배열 전체를 이동하거나 복사하려면 memcpy나 memmove와 같은 내장 함수를 사용해야 합니다. 배열 전체를 복사하거나 이동시키려면 for문으로 개별 원소들을 일일이 옮기거나 복사해야 하지만 memcpy나 memmove와 같은 내장 함수를 사용하면 간단하고 빠르게 처리할 수 있습니다. 예를 들면 "memcpy(&barr[0], &arr[0], sizeof(int)*10);"와 같이 사용할 수 있습니다.

위의 문제는 for 루프를 돌면서 각 원소들에 대하여 앞쪽에 있는 원소들의 합과 자신의 값을 더하는 과정임을 이해하면 간단하게 처리할 수 있습니다.

 0  9  8  4  0  0  1  2  0  1
 0  9 17  4  0  0  1  2  0  1
 0  9 17 21  0  0  1  2  0  1
 0  9 17 21 21  0  1  2  0  1
 0  9 17 21 21 21  1  2  0  1
 0  9 17 21 21 21 22  2  0  1
 0  9 17 21 21 21 22 24  0  1
 0  9 17 21 21 21 22 24 24  1
 0  9 17 21 21 21 22 24 24 25

위의 그림은 for문이 수행되면서 배열이 변화하는 과정으로 여덟번째(arr[7]) 값인 24에서 세번째(arr[2]) 값인 17을 빼면 정답은 7입니다.  C언어에서 배열의 시작은 0임을 실수하지 않도록 주의해야 합니다.

C언어에서 배열과 포인터는 불가분의 관계인데 예를 들어 "int *iptr;"로 선언하고 "iptr = arr;" 또는 "iptr = &arr[0];"라고 기술하면 배열의 시작 위치를 포인터 변수 iptr에 입력합니다. 포인터 변수에 배열의 시작 위치가 입력된 다음에는 "*iptr"라고 기술하면 "iptr이 가리키는 곳의 값"의 의미로 arr[0]와 같은 의미로 사용됩니다. iptr++;는 값을 +1하는 것이 아니라 포인터 타입에 따라 해당 타입만큼 위치를 이동시키는 것으로 iptr++; 이후에는 arr[1]을 가리키게 됩니다. C언어에서 포인터는 가리키고 있는 메모리를 지정한 타입의 시작 위치로 인식하기 때문에 포인터 변수는 배열 참조 방식으로도 사용할 수 있습니다. 포인터 변수로 선언했던 iptr도 iptr[0]과 같이 배열 참조 방식으로 사용할 수 있다는 것입니다.

728x90
댓글
최근에 올라온 글
최근에 달린 댓글
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함