-
[SW 정글 30일차] C언어는 배열부터 맛보기기타/SW 사관학교 정글 2021. 9. 1. 02:03
오늘은 이번 주 목요일부터 사용하게 될 C언어의 기본 문법을 공부했다.
C언어를 접하는게 처음이 아니고 앞 부분의 내용은 형태는 다르지만 어느정도 python을 통해 알고 있는 내용이여서 C언어의 벽을 느끼게 하는 포인터부터 공부하려고 했다.
하지만, 포인터를 공부하면서 같이 나오는 것이 배열이라는 것이였고 배열부터 차근차근 공부해야 포인터를 알아볼 때 좋을 것같아 배열을 공부하기 시작했다.
1. 배열 알아보기
배열을 알아보기 전에 C언어에서 값을 메모리를 다루는 형식을 먼저 봐보자.
C언어에서 메모리를 다룰 때에는 변수(variable)을 통해서 메모리에 값을 읽고 쓰고를 한다.
어떠한 타입을 가지고 있는 변수의 이름 하나느 변수의 타입에 해당하는 만큼의 공간을 메모리 상에서 차지하고 있다.
예를 들어, int타입은 4바이트이므로 int a라는 변수가 있다면 a는 메모리 상에서 4 바이트 공간을 차지하고 있게 된다.
그러면 우리가 비슷한 성격을 가진 변수들을 여러 개 다뤄야하는 경우가 온다면 어떻게 해야할까?
배열을 모르기 전에는 아래 코드처럼 일일이 int형 변수를 선언해주어야한다.
int a1, a2, a3, a4, a5, a6;
딱 봐도 매 번 변수를 선언해주는 것은 귀찮은 일이고 변수들을 이용하여 작업 하는 것도 불편함을 초래한다.
ex. 전체 변수들의 합을 구하려면 a1 + a2 + a3 + ... + a6라고 코드를 써야함.
이러한 불편함을 해소해주는 것이 C언어에서 배열(Array)이라는 것이다.
배열은 여러 개의 변수를 한 꺼번에 다룰 수 있는 것으로 컴퓨터 메모리 상에 같은 타입의 변수를 연속적으로 여러 개를 한 꺼번에 정의할 수 있는 방법이다.
C언어에서 배열을 정의하는 방법은 아래와 같다.
(배열의 형(type)) (배열 이름)[원소 개수];
위 정의에서 = { }를 써주면 배열의 각각의 원소에는 중괄호 속의 각 값들이 순차적으로 들어가게 된다.
예를 들어, 아래와 같이 선언하면 배열의 첫 번째 원소는 1, 두 번째 원소는 2, 마지막 원소(10번째 원소)는 10이 된다.
이 방법은 이리 정의된 배열에서는 사용할 수 없다.
#include <stdio.h> int main() { int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; } // 불가능한 경우 (compile error) arr = {2, 4, 1, 5, 7, 4, 3, 1, 4, 10}
그러면 우리가 사용할 배열에 들어갈 원소의 개수는 꼭 정의해주어야할까?라는 의문이 들겠지만 생략해도 원소의 개수에 맞춰 컴파일러가 배열을 정의해준다.
int arr[] = {1, 2, 3, 4}; // 크기가 4 인 배열 정의 int arr2[] = {1, 2, 3, 4, 5, 6} // 크기가 6 인 배열 정의
2. 배열의 위험성?!
다른 언어도 배열이라는 것이 있고 배열에 정의된 각각의 원소들에 접근하는 방법은 배열의 n 번째 원소의 접근하기 위해서는 arr[n - 1]로 쓰면 된다. 즉, 대괄호 [ ] 안에 접근하고자 하는 원소의 (번째수 - 1) 을 써주면 된다.
C언어에서 배열의 원소들은 python, java와 마찬가지로 0번부터 시작한다.
그러면 배열에서 조심해야할 위험성은 무엇일까?
#include<stdio.h> int main() { int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; printf("%d", arr[10]); return 0; }
위 코드를 보면 arr이라는 배열은 10개의 원소들을 가지고 있기 때문에 arr[10]은 존재하지 않는 것이 맞다.
하지만, 출력을 해보면 오류가 아닌 어떠한 값이 출력된다.
(반드시 출력을 해주는 것이 아닌 경우에 따라 오류를 내고 종료될 수도 있다.)
이를 이해하기 위해서는 메모리에 배열이 어떻게 존재하는지 알아야한다.
배열이 생성되면 메모리에는 각 원소들이 연속적으로 자리를 잡게 된다.
내가 생성한 배열이 메모리의 0x1014에서부터 자리를 잡아 arr[0](첫번째원소)가 위치해있다고 생각해보자.
배열을 선얼할 때 int형으로 했으므로 4바이트, 4칸씩 차지하게 된다.
여기서 알 수 있는 것은 배열의 크기에 대한 정보는 메모리에 존재하지 않는다는 것이다.
단순히 우리가 arr[4]를 원한다고 하면 컴퓨터는 '시작위치로부터 4번째위치의 원소를 원하는구나'라고 인식하고 그에 대한 값을 메모리에서 가져와 리턴해주는 것이다.
그러면 배열의 끝쪽이 위치한 메모리의 상황을 봐보자.
배열의 원소들이 순서대로 메모리를 차지한다면 위 그림과 같이 메모리에 올라와 있을 것이다.
그렇게 되면 arr 배열의 마지막 원소인 arr[9]가 위치한 뒤 메모리 부분에는 다른 변수들의 데이터가 들어있을 것이다.
그래서 우리가 arr 베열에 존재하지 않는 arr[10]을 요청하면 컴퓨터는 배열의 크기를 모르므로 arr[9] 뒤에 위치한 데이터가 arr[10]인 줄알고 리턴을 해주는 것이다.
만약, arr[9] 뒷부분 메모리 영역이 접근 불가능한 영역이라면 오류를 내고 종료를 할 것이다.
이렇게 우리가 단순히 접근만해서 데이터를 읽어오는 경우라면 큰 위험성은 없지만 arr[10]에 접근하여 새로운 데이터로 덮어씌운다면 큰 위험성을 초래할 수 있게 된다.
ex) arr[10] = 3
[오늘의 나는 어땠을까?]
제목에서 볼 수 있듯이 정글에 들어온지 한 달이 되는 날이다...
그리고 2틀 뒤면 알고리즘 주차가 끝나고 B트리, 말록랩, 웹서버를 직접 만들어보는 시간을 가지게 된다.
한 달동안 내가 얼마나 성장했을까를 생각해보면 새로 안 지식들도 많고 누군가가 물어본다면 어느정도 대답을 할 수 있어 꽤 성장했다고 느낀다.
어제의 심란함은 꽤 많이 없어졌고 머릿 속에 잡생각들을 비워냈다.
다시 집중을 할 수 있었고 성장을 위한 시간투자를 하였다.
앞으로 새로운 무언가를 구현하면서 나의 부족함을 많이 느낄 수 있다고 생각이 든다.
하지만 부족함은 언제든지 시간과 노력만 있다면 채워질 수 있는 것이지 포기를 부르는 악은 아니다.
오히려 더 나은 성장을 위한 자극제가 될 수도 있다.
부족함에 좌절하지 말고 나의 성장을 위한 원동력이라고 생각하며 노력하자.
<참고 자료>
'기타 > SW 사관학교 정글' 카테고리의 다른 글
SW 정글 4주차 회고 (1) 2021.09.02 [SW 정글 31일차] 오늘은 C 포인터 (0) 2021.09.02 [SW 정글 29일차] @lru_cache (6) 2021.08.31 내 블로그를 구글 검색에 노출시키는 방법 (feat. 구글 서치 콘솔) (3) 2021.08.30 [SW 정글 28일차] 연결리스트 만들어보기 (0) 2021.08.30