보통 제어문을 배우시고, 함수로 넘어가는 경우가 많아요. 저는 C언어 배열 먼저 다루도록 하겠습니다. 함수는 조금 뒤에 배워도 크게 문제는 없습니다. 먼저 array는 같은 자료형을 여러 개 묶어놓은 자료 구조 정도로 생각하면 좋아요. 그런데, 그걸 어떻게 묶느냐가 문제입니다.
이 친구는 시작 위치를 기준으로 연속이 되게 저장이 되어 있어요. 흔히 이런 말을 들어보신 적이 있을 겁니다. array는 삽입, 삭제는 매우 오래 걸리지만, x번째에 있는 원소는 굉장히 빠르게 찾을 수 있다. 그 이유는 간단합니다. 메모리 상에 연속적으로 저장이 되기 때문입니다.
즉, 실제로 arr[2]에 접근하기 위해서, arr의 기준 위치를 알아냅니다. 그림에서는 0x80번지입니다. 그 다음에, 첨자가 2가 붙었기 때문에, 각 원소의 크기에다가 2를 곱한 값 만큼 주솟값을 증가시킬 겁니다. base 주소로부터 말입니다. 그러면, int형의 크기가 4인 경우, 그 값은 0x88번지가 될 건데. 이것이 arr[2]의 값이 있는 주소 정도로 생각하시면 됩니다.
대신, 삽입과 삭제는 어떨까요? 상당히 느릴 거에요. 일례로, [2, 3, 2, 7]이 있고, 1번째에 있는 2를 삭제한다고 해 봅시다.
그러면 초록색 부분을 앞으로 당겨야 할 겁니다. 최악의 경우, 배열의 크기 - 1개의 원소를 앞으로 당겨야 할 거에요. 따라서, 삭제 연산은 최악의 경우 n회 수행된다고 말할 수 있습니다. 어떤 값을 추가하는 연산은 어떨까요?
3 앞에 5를 추가한다고 해 봅시다. 그러면 초록색으로 칠한 부분은 뒤로 밀어야 합니다.
그 다음에 어떻게 하면 좋을까요? 뒤로 민 다음에, arr[0]에 5를 넣어주면 됩니다.
따라서, 시간 복잡도는 O(n)이라고 할 수 있어요. 이것만 일단 주목하고 넘어가셔도 크게 문제가 없습니다.
그러면 먼저 1차원 배열부터 알아봅시다. 다음과 같이 선언합니다.
타입 배열이름[배열크기]
예를 들어 int형 데이터를 4개를 연속적으로 저장하는 것을 만들고 싶다. 그러면 int arr[4]; 이렇게 선언해 주시면 됩니다. 2차원 배열은 타입 배열이름[크기][크기] 이런 식으로 선언해 주시면 되는데, 이것이 어떻게 저장이 되는지는 행 우선, 열 우선 방식에 대한 차이를 설명할 때 다시 언급하고 넘어가도록 하겠습니다.
배열의 원소에 접근할 때에는 배열명[인덱스] 로 접근을 할 수 있어요. 한 가지 중요한 점은, 배열의 첨자는 1부터가 아닌 0부터 시작한다는 것인데요. 처음 접하시는 분들은 매우 헷갈릴 수 있습니다. 왜 1번부터 시작하지 않고 0번부터 시작하나요? 라고 물어보신다면 그냥 외우세요. 라고 하는 수 밖에 없어요.
이 프로그램을 실행해 봅시다. 실행 결과는 5가 나올 거 같습니다. 저는 5번째 요소를 출력하라고 했기 때문입니다. 하지만, 출력 결과는 이와 딴판입니다.
이는 0번 인덱스에 1이, 1번에는 2가, 2번 인덱스에는 3이, 3번에는 4가, 4번에는 5가 있기 때문입니다. 이를 그림으로 나타내면 아래와 같습니다.
그러면 arr[5]는 없네요. 정확히 말하면, bound를 벗어나 버린 겁니다. 이러한 경우, 결과 값은 정의되지 않습니다. 이러한 부분은 조심해야 합니다.
1차원 배열을 초기화 하는 방법까지만 배워보고 예제 문제를 풀어봅시다.
형 배열이름[배열크기] = {원소(1), ... , 원소(배열크기)};
ex. int arr[5] = {2,3,4,5,6};
ps에서 문제를 많이 풀면서, 많이 초기화 한 패턴입니다. 다른 패턴은 모르셔도 좋지만, 이 패턴은 상당히 많이 쓰이니, 익혀 두시는 게 좋습니다. 중괄호 안에, 원소들을 나열하는 식입니다. 혹은 배열의 모든 값을 0으로 초기화 할 때, 이 구문도 상당히 많이 쓰입니다. 예를 들어서 int형 자료를 5개 가지고 있는 배열의 원소들을 모두 0으로 set 한다고 해 봅시다.
int arr[5] = {0};
그러면 위와 같이 초기화를 할 수 있습니다. 이 두 패턴은 상당히 많이 쓰이니 알아두시면 좋겠습니다. 그러면 예제 문제를 풀어봅시다. 8개의 음을 연주하는데 1 2 3 4 5 6 7 8 순으로 연주하면 ascending, 8 7 6 5 4 3 2 1 순으로 연주하면 decending, 그렇지 않으면 mixed를 출력해야 합니다. 어떻게 하면 좋을까요? 제일 쉬운 방법은 이 8개의 수를 연속적으로 저장할 수 있는 배열을 선언하는 겁니다.
그러면 위와 같이 배열을 만들 수 있을 거에요. 여기서 1보다 크거나 같고 8보다 작거나 같은 i에 대해서 arr[i]의 값과 i의 값이 같으면 ascending입니다. 반대로 이런 경우는 어떨까요?
이 때에는 1보다 크거나 같고 8보다 작거나 같은 i에 대해서, arr[i] + i의 값이 9로 모두 같음을 알 수 있어요. 그러면 어떻게 코딩하면 될까요? ascending을 판단하기 위해서 먼저, 1부터 8까지 돌면서 arr[i]의 값과 i 값이 같은지를 판단합니다.
만약에 증가 음계면 출력하고 빠져나오면 됩니다. 그렇지 않다면, 감소 음계인지 판단해야 하는데요. 1보다 크거나 같고 8보다 작거나 같은 i에 대해서 arr[i] + i의 값이 9라면 decending입니다. 그렇지 않다면 증가하고 감소하는 것이 섞여 있으니, mixed입니다.
이를 판단하는 나머지 코드도 작성해 봅시다. 그러면 요렇게 작성하실 수 있습니다. 오늘은 C언어 배열에 대해 간단하게 알아 보았는데요. ps에서 흔히 사용되는 것은 1차원, 2차원 까지는 많이 사용됩니다. 다음 시간에 2차원에 대해서 다루어 보고, 행 우선과 열 우선에 대해서 간략하게 다루어 보도록 하겠습니다.
'코딩 > C' 카테고리의 다른 글
c언어 2차원 배열 : 메모리 상에 어떻게 저장이 될까요? (11) | 2019.09.14 |
---|---|
C언어 문자열 : 특별한 문자로 끝난다. (10) | 2019.09.09 |
c언어 switch 문 : case와 짝꿍이다. (2) | 2019.09.06 |
c언어 break문 : 루프를 빠져나간다. (15) | 2019.08.29 |
c언어 continue문 : 반복문의 끝으로 이동한다. (8) | 2019.08.26 |
최근댓글