삽질의 현장/- .NET

#016_닷넷(.NET)_.Net Framework 기본 - 일차원 배열

shovelman 2015. 10. 23. 15:48


안녕하세요 삽잡이입니다.


이번 시간에는 배열에 대해서 알아보려고 합니다.

물론, 지난 시간에 올린 기억이 있으나 다시한번 기분좋게! 달려보도록 하겠습니다.


아래 코드 한 줄은 배열에 대한 예제입니다.


int[] arr = { 10, 20, 30, 40, 50 };


해당 배열은 여러 방법으로 쓸 수 있습니다.


 

사실 'arr1', 'arr2', 'arr3' 처럼 쓸 수 있습니다.

int형 다섯개 짜리가 생략 되있음을 간략하게 사용한 것이지요...

즉, 동적으로 배열 5개짜리를 만드는 것이 저 코드의 내용입니다.


초기 값이 있다면 두번째 코드와 같이 숫자를 생략할 수 있습니다.

어차피 초기값을 보고 결정하기 때문이지요...


그리고 배열은 개수가 고정되어있기 때문에 

앞을 생략하여 마지막 코드처럼 만들 수 있습니다.

마지막 코드가 가장 간단하게 만든 배열 코드이군요...


여담으로 말씀드리자면, 

필드를 초기화하지 않는다면 동적 메모리에 있는 필드는 모두 0으로 초기화가 됩니다.



아무튼... 전체적으로 살펴보자면

클래스 내부에 5개의 메모리를 만들라는 뜻이지요..

그리고 메모리를 만든 뒤에 원소를 초기화 시킨것이구요...

마지막으로 배열의 참조자를 하나 만들어서 

이 배열 객체를 가리키는 것이 이 코드 해석의 완성입니다.


지난 시간에도 알아봤지만,

만약 다양한 타입의 자료형을 담고 싶다면...

이들의 부모인 Object형태의 배열을 만들면 됩니다.

'object[]' 이렇게 말입니다...

그리고 이 object는 사실 System.Object라는 실제 이름의 애칭이지요...

즉, System이라는 namespace로 부터 Object라는 형식을 가져온 것입니다.


int[], object[] 와 같은 형식들은 모두 클래스 이름입니다.

C#은 기본적으로 객체로 움직인다고 했지요...

C/C++은 배열의 이름이 메모리 자체를 가리키는 

메모리 시작주소의 의미를 가지고 있었지만,

C#은 다릅니다... 자체가 객체이기 때문에 차이가 있습니다.


따라서 위의 그림처럼 

int[] 형식의 객체를 만들어 놓고 

arr이라는 참조자를 통해 객체를 가리키는 구조로 되어있는 것입니다.

(참조는 몇 바이트인지 공개는 되지 않았지만 조사해봤을 때 4바이트라고 합니다.)


객체를 가리키는 것과 메모리를 참조하는 것은 다르니 

C/C++과 C#의 차이를 이해하시길 바랍니다...


그런데 만약, 이 배열을 가리키는 참조를 넘기게 될 경우 어떻게 될까요?

예를 들어서 함수의 매개변수로 말입니다...



이때 호출받는 함수의 매개변수는 같은 형식의 참조자이어야 될 것입니다.

즉, 참조자를 매개변수로 받았기 때문에 

똑같은 배열 클래스를 가리키게 될 것입니다.

따라서 매개변수로 받은 참조자를 통해 데이터를 변경할 경우 변경이 됩니다.

왜냐하면 객체의 참조이기 때문에 객체를 가지고 논다는 소리지 않습니까...

즉, 참조자가 객체의 이름이 되기 때문에 가능해진다는 소리입니다.


여러분! C++에서 헤어나오셔야합니다...

물론 저도 못나왔습니다. 푸하하하하하

아무튼... 언어마다 특징이 있습니다... 배열이 기존에 우리가 알던 배열이라고 생각하시면 안됩니다.

C#에서는 단지 객체 하나입니다... 

그 참조가 복사되면 복사된 참조를 이용해서 값을 변경할 수 있다는 사실을 이해하시길 바랍니다.


이렇게 C#에서 사용되는

참조자와 배열 객체에 대해서 이해가 되신다면 이를 어마무시(?)하게 응용이 가능합니다...



예를 들어 메서드를 통해 배열 객체를 받는 다던지, 

참조를 넘긴다던지... 이런게 가능해진다 이 말입니다...


또한 한정자 매개변수를 사용해서 return을 받지 않고 

참조자에 배열 객체를 연결 시킬 수도 있습니다.


그런데 위에서 보신 예제코드와 같이 참조를 가지고 노는 것이 굉장히 중요합니다.

객체를 복사하라고 하면 참조만을 합니다...

그런데 이게 객체 복사일까요?

실제로 객체를 복사하기 위해서는 객체 배열을 복사해야합니다.

즉, 똑같은 배열 객체를 복사하고 그 복사본을 가리켜야 실제 복사인데

이 예제는 단지 참조만을 복사한 '참조 복사'일 뿐이란 소리입니다...


나중.. 시간에 배우겠지만

Deep Copy, Short Copy에 대한 이야기를 잠시 나눈 것입니다.

어찌됬건... 다음 예제를 봅시다.



가끔 라이브러리를 보면 이런 방식으로 구현된 라이브러리들이 있다고하네요... 


아무튼... 이렇게 간단하게... 1차원 배열에 대해서 알아봤습니다.


마지막으로 이 예제 코드에서 'CreateIntArray()', 와 'InitArray()' 메서드에서

받는 매개변수에 대해서 차이를 한번 생각해보시겠습니까?



CreateIntArray의 iarr과 InitArray의 iarr은 전혀 다른 성격입니다...

main함수에 arr과 같은 iarr, stack에 새로 만들어진 iarr...

이 두 차이에 대해서 생각해보시길바랍니다...


다음 시간에 뵙겠습니다.


이상 삽잡이였습니다!