Link
1편/네트워크 연결하기-http://www.wolfpack.pe.kr/303
2편/Bluetooth사용하기-http://www.wolfpack.pe.kr/310
3편/모바일배포일반-http://www.wolfpack.pe.kr/314
4편/PC에서모바일배포-http://www.wolfpack.pe.kr/315

기대도 하지 않았던 삼성 U70체험단 당첨에 이은 체험기 올리느라 Mobile 개발 환경 구축에 시간을 할애하지 못하였다.
이제 지난 이야기에 이어 2번째 Windows Mobile Emulator에서 Bluetooth 사용법을 알아보도록 하자.

먼저 http://code.google.com/p/bthmsdevemul/ 로 방문해서 Emulator에서 블루투스를 사용할 수 있도록 해주는 Driver를 받자.

0.94 파일은 여기에
압축파일이니 알아서 풀도록하고 이제부터가 중요하다.

1. XP기준으로 제어판>하드웨어 탭에서 장치관리자 클릭
사용자 삽입 이미지
2. Bluetooth 장치의 드라이버 속성 클릭
(본 그림에서 하단의 연한 파랑색의 Bluetooth 장치는 USB장치로 현재는 미장착중임)
사용자 삽입 이미지
3. 드라이버 업데이트 클릭
사용자 삽입 이미지
4. 목록 또는 특정 위치에서 설치로 다음 클릭
사용자 삽입 이미지
5. 검색안함, 설치할 드라이버를 직접 선택후 다음
사용자 삽입 이미지
6. 디스크 있음 클릭
사용자 삽입 이미지
7. 압축해제한 곳의 하위 폴더중 WINXP 선택. (Vista는 Vista32선택)
사용자 삽입 이미지
8. 드라이버가 "FreeBT USB Driver"로 잡히면 다음 클릭
사용자 삽입 이미지
9. 설치중
사용자 삽입 이미지
10. USB 드라이버로 설치완료
사용자 삽입 이미지

이제 진짜 작동하는지 확인할 차례
먼저 .cetool 파일을 실행할 수 있는 프로그램이 필요하다.
Microsoft.com의 Download에서 "Remote Tools Framework"으로 검색하면 금방 나옴
현재의 URL : http://www.microsoft.com/downloads/det ··· 0a6a76e4

다운로드후에 또한번의 설치를!
사용자 삽입 이미지
설치가 완료되면 다시 압축해제한곳으로 가서 "RTFx Plugin"으로 들어가 BthEmulManager.cetool 파일을 더블클릭하면 디바이스를 선택하라고 뜨는데 개발하는 환경에 맞는 해상도를 선택하자.
(Omnia는 6.1의 480*800으로 선택)
사용자 삽입 이미지
이제 모든 작업이 막바지다. 이렇게 띄우면 Bluetooth 통신이 가능한 Emulator가 실행된다.
사용자 삽입 이미지
요녀석을 그대로 띄워둔채로 Visual Studio 2008의 도구에 있는 "장치 에뮬레이터 관리자"를 실행해보자
사용자 삽입 이미지
장치 관리자에 활성화 되어 있다.
사용자 삽입 이미지
실재 Emulator에서 Bluetooth 장치들이 잡히는지 확인 해볼까?
Emulator의 설정(Setting)에서 블루투스의 새장치 추가를 통해 주변 장치를 검색해보았다.
사용자 삽입 이미지
결과는 성공. 추가로 Debug도 가능!
사용자 삽입 이미지

다음 포스팅은 PC에서 설치파일을 실행해 크래들에 연결된 모바일 장치에 설치를 어떻게 하면 할 수 있는지 확인해보자.
(주로 CAB파일을 옮겨다 놓고 하지만 .NET Compact Framwork 3.5와 같이 런타임을 따로 설치하는것은 짜증나는일. 걍 PC에 놓고 손쉽게 배포하는 법을 알아보자.)
2009/03/04 15:00 2009/03/04 15:00
"LC.exe가 종료되었습니다"라는 에러가 나면
솔루션탐색기에서 해당 프로젝트를 선택하여 "Properties" 폴더 밑의 "licenses.licx"파일을 삭제하자.
그러면 깔끔하게 해결된다.
2008/12/01 23:32 2008/12/01 23:32
M$가 미쳤나? DotNET 3.0부터 갑자기 이상한 서드파티제품을 쏟아 내어 햇갈리게 만들더니
우연찮게 시연 동영상 보다 이제야 알게되었다. T_T 아놔..
사용자 삽입 이미지
WPF와 실버라이트 당췌 2개의 차이를 알지 못했는데 결국 WPF는 데스크톱환경용이고 실버라이트는 웹환경용이라는 거군. 덴장...
2007/08/28 20:05 2007/08/28 20:05
.NET 1.0이 처음 세상에 나왔을때 본인은 정말 환영하였다.
자바가 싫었던 것 중 하나인 수많은 3rd 파티의 홍수(지금시각에서는 진짜 그때는 새발의 피였다고 회고한다.)가 정말 싫었고 설정하는 짜증이 정말 너무나도 싫었기 때문에
"Setup.EXE"한방에 모든 설정이 끝나는 닷넷 플랫폼이 너무나 좋았다.

.NET 2.0이 나왔을때 partical Class를 지원한답시고 삽질할때 그나마 참아 줄만 했다.

.NET 3.0이 나온다고 난리칠때 본인 존나 짜증난다.
사용자 삽입 이미지
컨셉자체는 비스타와 윈도우 2008을 지원하기 위한 것이라고 명확히 하고 있다.
또한 XP SP2와 윈도우 2003에서도 SDK만 다운로드 하면 된다고 하니 이것도 약간 떱떠름할 뿐이긴 하다.
일단 뒤벼보면 가장 크게 바뀌는 부분이 바로 WCF, WPF, WCS, WWF 등 더블류4형제.
그넘들은 각각 다음을 대체하고 지원하기 위해 나온다고 하니 그나마 덜 짜증이지만
WCF --> DCOM, COM+, SOAP 등의 프로토콜
WPF --> UI (XML base), 3D 등의 유저인터페이스 프리젠테이션 부분
WCF --> 비스타에 포함된 카드스페이스 서비스 부분
WWF --> 트랜젝션이나 작업 절차를 자동으로 해주기위해 지원하는 부분
등등 이다.

이까지는 그냥 떨떠름하다. 좋은거 반 나쁜거 반.
그.런.데....

니미 LINQ, BLINQ라고하는 넘은 완전 삽질 같이 보인다.
샘플코드 한번 봐보자.
 Northwind db = new Northwind(connectionString);
 

 var q =  from o in db.Orders, c in db.Customers
          where o.Quality == "200" && (o.CustomerID == c.CustomerID)
          select new { o.DueDate, c.CompanyName, c.ItemID, c.ItemName };
 
 foreach (var t in q)
 {
     Console.WriteLine("DueDate Type = {0}", t.DueDate.GetType());
     Console.WriteLine("CompanyName (lowercased) = {0}", t.CompanyName.ToLower());
     Console.WriteLine("ItemID * 2 = {0}", t.ItemID * 2);
 }
특히 LINQ문법으로 들어간 쿼리 한번 봐보자.
var라는 불특정 변수 "q"에다가 쿼리를 때렸는데 이거 뭔 병신 짖인지
"select ~ from ~ where ~ "이거를 "from~where~select"로 순서만 바꿔놓고서는 생산성 향상 어쩌고 떠들고 있는것이다.
그래서 일까? 2005년에 발표하고도 이제서야 일반 개발자에게 알려지고 3.0도 아닌 3.5에나 탑재된다고 한다.

dll 지옥 없애겠다고 하더니만 이제는 프레임웤, 3rd Party 지옥에 개발자를 빠트려 버리는 M$ 엿먹어라.

*개인 적인 바램은 ADO.NET보다 느려터진 LINQ와 같은 새로운 언어가 아니다.
닷넷프레임 워크의 향후 개발방향은 현재와 같이 무조건적인 주변의 좋은게 보이면 집어삼켜 몸집을 불리는 프래임워크가 아닌 가변 모듈형식의 스마트 하고 작은 사이즈이면서 민첩한 개발이 가능한 방향으로 가야 하며 이러한 좋은 본보기가 Ruby and Rails이다.
개발자들은 기능이 많다고 그것을 선택하지 않는다.
가능한 최소한의 코드로 자신이 원하는 결과물을 얻기를 원할 뿐이며 개발툴과 컴파일러가 비대해지는 것을 원하는 개발자는 단 1명도 없다.
2007/08/14 14:17 2007/08/14 14:17

쓰레드라고 하는것이 한때는 고수들의 전유물이었는데 요즘은 강호고수들이 많아져서인지 아무나 쓰는 기술되었다.
뭐 암튼 대충 쓰레드에 대해 정리하자는 차원에서 써둠을 밝히니 향후에 제대로 안된다고 이런거 하지말자.

1. 쓰레드 사용하기
일단 닷넷의 쓰레드는 굉장히 쓰기쉽다.
다음의 예제를 함해보자.

using System;
using System.Threading;  //쓰레드를 쓰겠다고 선언하자.

class Test {
  static void Main(){ 
   Console.WriteLine("카운트 0부터 49까지 세기!");
   ThreadStart th = new ThreadStart(work); //1.work메소드를 위임하자.
   Thread t = new Thread(th); //2.쓰레드생성하자.
   t.Start(); //3.시작
   Console.WriteLine("끝!");
  }
  public static void work(){
   for (int i = 0; i<50; i++){
    Console.WriteLine("Conut:{0}",i);
   }
  }
}

결과를 보면 짜잔!
사용자 삽입 이미지

* Ultraedit에서 컴파일하고 실행한 결과창임. 이렇게 하고싶으신분들은 본 블로그 잘뒤져보면 나옴.

2. 쓰레드 중지하기
쓰레드를 중지하기위해서는 2가지 방법이 있다.
- Abort()
- Join()
Abort()는 강제종료이므로 어디서 끝날지 아무도 모른다. 신도 모른다.
Join()은 쓰레드가 다 실행될때 까지 기다렸다가 종료시킨다.
다음예제를 보자

using System;
using System.Threading; 

class Test {   static void Main(){    Console.WriteLine("카운트 0부터 1만까지 세기!");    ThreadStart th = new ThreadStart(work);    Thread t = new Thread(th);    t.Start(); //시작    t.Abort(); //강제종료    Console.WriteLine("끝!");   }   public static void work(){    for (int i = 0; i<10000; i++){     Console.WriteLine("Conut:{0}",i);    }   } }


이녀석을 실행해보면 Abort()때문에 이렇게 된다.
사용자 삽입 이미지

코드에서는 1만까지 진행하는것으로 만들어졌지만 강제종료되어 8524에서 종료되었다.
한번 더 해보자.

사용자 삽입 이미지
어쩌구리.. 이번에는 다 돌아 버렸다... ㅡㅡ;; 암튼 이런식으로 예측이 불가능한 코드가 되어버린다. 중간에 종료하는것은 왠만하면 하지말고 Join()을 사용하도록 하자.
위코드에서 다음과 같이 수정한다.
   ...전략...
   t.Start(); //시작
   t.Join(); //이전에 t.Abort()임
   Console.WriteLine("끝!");
   ...후략...

사용자 삽입 이미지
이번에는 다 돈다. (사실은 위의 이미지와 같은 이미지임.. 흐흐흐)

3. 쓰레드의 쉬게하기
이번에는 일하다가 중간에 쉬게 해보자.
using System;
using System.Threading; 

class Test {   static void Main(){    Console.WriteLine("쓰레드 시작");    ThreadStart th = new ThreadStart(work);    Thread t = new Thread(th);    t.Start();    Console.WriteLine(t.ThreadState);    Console.WriteLine("끝!");   }   public static void work(){    Thread.Sleep(100);   } }


사용자 삽입 이미지
쓰레드가 시작되고 Sleep명령으로 인해 Sleep모드로 들어갔다.

명령이 주어질때까지 중지하고 싶다면 Suspend()를 사용하자. Suspended된놈을 다시 살리는 것은 Resume()이 있는데 이건 알아서 한번 만들어 보도록 하자.

결론적으로 .NET의 쓰레드(Thread)는 다음과 같은 상태값을 가진다.
(ThreadState()로 나오는 결과값이 바로 타원형안에 있는 녀석들이다.)

사용자 삽입 이미지
이 표만 잘봐두면 쓰레드 어려운것이 아니다.
일단 생성된 쓰레드는 Unstarted라는 값을 가진다. Start()라는 메소드로 Started라는 상태값을 가지게 되는 것이다. 다시말해 타원안에 있는 것은 상태값, 화살표에 있는 것이 바로 메소드 되겠다.

다음에는 멀티 쓰레드 함 해보자.

* 본 게시물에서 사용한 쓰레드라는 표현은 "Thread"의 한음표현이며 쓰레드는 스레드라고도 표기됩니다. Microsoft공식학습서 Inside C# 2nd Ed.에는 쓰레드라고 표기되어 있어 본 게시물도 쓰레드라고 표현함을 알려드립니다.

2007/07/12 16:20 2007/07/12 16:20
지난번에 쾌속으로 스마트 클라이언트를 만들어 보았다.
(관련글 : http://www.wolfpack.pe.kr/103)

* 다음과 같이 하는 방법도 있고 코딩으로 처리하는 방법도 있다.
(http://www.wolfpack.pe.kr/265 참고)

오늘은 가장중요한 배포이다.
(스마트 클라이언트는 서버에서 다운로드 받은 "dll"이나 "exe"파일이 로컬에서 실행되는 것이라는것만 알고 보도록 하자.)

1. 서버
서버쪽은 MIME타입을 제대로 설정해줘야 익스플로러가 제대로 작동한다.
IIS등록정보에서 "MIME형식"을 클릭해서 활성화 시키자.
(예제는 가상사이트의 등록정보로 실재와 다를수 있다.)
사용자 삽입 이미지
"새형식"을 클릭한후 ".dll"파일이면 확장자에 ".dll"을 입력하고 MIME형식에는 "application/octet-stream"이라고 설정하자.
".exe"는 "application/x-msdownload"라고 설정하면 된다.
사용자 삽입 이미지
사용자 삽입 이미지
이것으로 서버쪽은 끄읏!

2. PC설정
PC는 보안설정을 위해 "caspol.exe"라는 넘을 사용한다.
.NET 2.0에서는 "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\"폴더에 있으니 이녀석을 찾아서 DOS창에서 다음과 같이 입력후 실행하면 "yes/no"둘중에 하나를 선택하라고 뜨는데 우리야 뭐 무조건 깔아야 하니 그냥 yes쳐주자.

"caspol.exe -machine -addgroup All_Code -url http://10.250.30.181/* Everything -n SKCC"

사용자 삽입 이미지
실행후의 모습인데 참으로 아름답지는 않지만... ㅡㅡ;;
아무튼 제대로 적용됐단다.

이렇게 하면 실행에는 문제가 없을 것이다. 더 추가적으로 "caspol.exe"에 대해 알아보면 이녀석이 사용하는 인자를 분석해보면 다음과 같다.

"-machine"이라고 된부분은 "-en", "-m", "-u"로 대체가능하다.
각각 enterprise, machine, user를 뜻한다. 즉, 대상범위이다.

"-addgroup"이라고 된녀석은 대상 코드를 이야기하고
다음의 구조중 하나에 추가하란 의미이다.
-All_code -+- MyComputer (내컴퓨터에서 실행)
                +- Intranet (인트라넷에서 실행)
                +- Trusted (신뢰할 수 있는 사이트에서 실행)
                +- Internet (인터넷에서 실행)
                +- untrusted (신뢰하지 않는 사이트에서 실행)
"-url"은 "-site","-zone","-url"등으로 대체될 수 있고 다운로드 받는 곳의 조건을 표현하고 있는데 인터넷에서 받을것이니 그냥 "-url"로하자. 요넘 뒤에 있는것이 "http"나 "ftp"로 시작되는 인터넷 표준 주소이다.
주소바로 뒤에 보이는 "Everything"은 다음과 같은 체계로 나뉜다.
-FullTrust
-SkipVerification
-Execution
-Nothing
-Localintranet
-internet
-Everything
다시말해 권한인데 "Everything"은 권한을 다 주는 거다. (PC포맷시켜도 된다. ㅡㅡ;;)
그다음이 FullTrust이며 이렇게 주루루룩 권한이 낮아져서 Nothing이 되면 아무것도 안된다.

그리고 나서 나오는 것이 "-n"인데 이녀석은 이렇게 설정하는 코드 그룹의 이름으로 여기서는 SKCC로 했다. (왜? 그냥~ 사실 나는 SKC&C라는 회사 다닌다.. ㅡㅡa)

이제 SDK가 깔려있다면 있을 제어판>관리도구>.net framework 2.0 Configuration으로 가서 확인해보자.
사용자 삽입 이미지
2007/04/27 18:01 2007/04/27 18:01

스마트 클라이언트가 뭔지 궁금하신분은 다른 사이트에서 찾아보시고 뭐 간단히 말해 닷넷판 ActiveX되겠다.

일단 VS2005있으면 좋겠고 없으면 말고다. ㅡㅡ;;

먼저 새로운 프로젝트를 생성하고 다음과 같이 "Windows 컨트롤 라이브러리"로 설정한뒤 이름을 "Simple"이라고 하자.

사용자 삽입 이미지
(잘안보이면 그림을 클릭 함해주면 제대로 보임)
위와 같이 하면 아래와 같이 Simple이라는 폴더가 생성되고 각종 파일이 주루루룩 생긴다.
사용자 삽입 이미지
왼쪽에 쪼끄만하게 회색박스가 생길텐데 거기다가 Button컨트롤하나를 올려놓자.
사용자 삽입 이미지
그리고 "button1"을 더블클릭해서 이벤트를 자동생성하고 코딩창에 "MessageBox.show("Hello World!");"를 입력하자.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace Simple {     public partial class UserControl1 : UserControl     {         public UserControl1()         {             InitializeComponent();         }         //아래 4줄이 새로 추가된 코드임.         private void button1_Click(object sender, EventArgs e)         {             MessageBox.Show("Hello World!");         }         //여기까지임.     } }


이제 "F5"키를 눌러서 디버그 모드에서 테스트 함해보자.
사용자 삽입 이미지

아직까지는 문제없이 잘된다.
이제 원래 폴더 밑에 "Simple\bin\Debug"로 가보면 "Simple.dll"이 생성되어 있을것이다.
이놈을 웹루트로 옮기고 아래와 같이 코딩하고 test.htm으로 저장하자.
<object
    id="Simple"
    classid="Simple.dll#Simple.UserColtrol1"
    width="150" height="150">
</object>


id는 알아서 설정해도 될것이다.
그러나 "classid 속성"은 중요하므로 다음과 같은 룰을 따르자.

"classid = [dll명]#[namespace].[class]"

예제에서보면 "Simple.dll"이니 당근 dll명은 "Simple.dll"이다.
namespace는 C#코드에서 "namespace Simple"라고 된 부분이 바로 해당 dll의 namespace이니 요기서 따오면 "Simple"이 되는 것이다.
Class는 "public partial class UserControl1 : UserControl"라고 된부분에서 따오면 된다.
그래서 class부분은 "UserContol1"이 된것이다.
간단한 공식이니 헷갈리지 말고 ^^

이제 웹서버를 통해 실행해보면 다음과 같이 잘 뜬다.
사용자 삽입 이미지
처음 만들어보는 거라 삽질좀 했다. 왜? 그냥 "test.htm"파일을 더블클릭했더니만 절대 실행안된다. 반드시 웹서버에 Request해서 받도록 하자.
2007/04/23 18:25 2007/04/23 18:25

지난번에 자료구조(http://www.wolfpack.pe.kr/87 참조)에 대해 이야기했었는데 오늘은 MS가 여러사람 괴롭혔던 박싱(Boxing)과 언박싱(Unboxing)에 대해 이야기 해보자.

이전 자료구조를 들여다 보면 메모리에 힙과 스택이 있다고 했다.
힙은 그냥 막쓰는 메모리고 스택은 지정한 크기만큼 사용하는 메모리 공간이라고 했었다.
또한 스택은 int형과 같이 형(Type)선언과 동시에 크기가 결정되는 데이터형이 들어간다고 했고 힙은 String과 같이 형(Type)만 선언되고 크기가 결정되지 않는 것들이 들어간다고 했었다.
정확하게 이녀석들을 따져보면
int,byte,char,single,double,boolean,decimal과 같은 녀석들이 바로 스택을 사용하는 Value Type이다.
String, Array, Object, Class, Interface, Delegate과 같은 녀석들은 힙을 사용하는 Reference Type이라고 한다.

뭐 이리 복잡하게 나눠놨냐만은 실재 메모리 사용을 보면 좀더 이해가 쉬우려나?
int a = 0; 이라고 하면

메모리주소 : [0]
라고 메모리 주소에 값 "0"이 들어간다.

그러나 string a = "1234";라고 하면

메모리주소 : [참조하는메모리주소] - 참조된메모리주소 : [1234]
와 같이 할당되는 메모리의 주소에 값은 없고 실재 값이 있는 메모리 주소가 들어간다.

그래서 위에 넘은 Value타입이라고 하고 밑에 넘은 Reference타입이라고 한다.

* 너무 원망말자. 내가 만든 개념이 아니라 공부 많이한 사람들이 만든 개념이니...

이제 본론 박싱(Boxing)은 그럼 뭘까?
바로 Value타입을 Reference타입으로 변환하는 것을 말한다.
코드를 보자

using System;

class Test {   public static void Main() {     int a = 1;     object b = a; //요걸 박싱되었다고 한다.      //또는 이렇게 변환도 가능하다.       /*         string b = a.ToString();        */     Console.WriteLine (b);   } }


언박싱(Unboxing)은 반대개념이다. 즉, Reference타입을 Value타입으로 바꾸는 작업을 말한다.
using System;

class Test {   public static void Main() {     int a = 1234;     object b = a; //박싱하다     int c = (int)b; //언박싱하다     Console.WriteLine (c);   } }


쩝.. 한가지 불만이 있다면 value 타입에서 Reference타입으로 변환할때 중간에 Object 타입으로 변환해야 한다는거 그거 되겠다.

아무튼 이런 구조를 알아서 뭐에 쓰는가 하면 바로 코딩 튜닝에 사용한다.
ILDASM이란 녀석으로 튜닝하는데 이건 나중에 다시 이야기 해보자.

이전 글을 보시려면 http://www.wolfpack.pe.kr/category/Developer/.NET

2007/04/04 18:39 2007/04/04 18:39

좀 늦은 감이 없지 않아 많지만 객체를 이야기하기전에 배열과 구조체를 지나침으로써 객체를 정확히 이해하는데 어려움을 주고 말았다.
따라서 뒤늦게나마 배열/구조체를 이야기해보도록 하자.

배열이란 여러개의 변수를 포함하는 데이터 구조이다.

1차원, 다차원, 가변 배열등 3가지의 인간이 생각할 수 있는 배열이 있는데 다시말하자면 아파트라고 생각하면 이해가 좀 쉬울려나?

이런 상상을 좀 해보자. 1층짜리 아파트가 있다고 가정하고 (하긴 누가 이렇게 짖겠냐만은...) 101호~105호까지 5개의 방이 있고 여기에는 각각 "김씨","박씨","이씨","최씨","민씨" 이렇게 5가구가 살고있다고 치자.

이제 "김씨"가 사는집을 어떻게 표현할 수 있을까?
1. 101호
2. 첫번째집
3. 김씨네집

이렇게 표현할 수 있을것이다. 이것을 데이터로 그대로 옮기면 다음과 같은 형태가 된다.

using System;

class Test {   public static void Main() {     string[] a = new string[]{"kim","park","lee","choi","min" };     //다음은 모두 같은 뜻이다.     //string[] a = {"kim","park","lee","choi","min"};     //string[] a; a= new string[]{"kim","park","lee","choi","min"};     //string[] a = new string[5];  a=new string[]{"kim","park","lee","choi","min"};         // 이렇게는 에러난다.     //string[] a = new string[5];  a={"kim","park","lee","choi","min"};     Console.WriteLine (a[0]);   } }


위의 예제를 실행해보면 알겠지만 이런식으로 배열에 넣고 한묶음씩 데이터를 처리할때는 편하게 할 수 있다.
단, 변수를 초기화하고나서 데이터를 나중에 넣을경우는 반드시 "new"를 써주도록 하자.

이제 다차원 배열을 생각해보자. 다차원 배열은 1차원배열이 여러게 있다는 것이다.
다시말해 아파트가 2층, 3층으로 올라 갔다고 생각하자.
1층에는 "김","박","이","최","민"이 살고 2층에는 "류","원","홍","왕","고"씨가 산다고하면 이것을 두개의 변수에 나눠서 하면 당연히 1차원 배열에서와 같이 2번 써주면 되지만 이거 영~ 불편하다. 따라서, 한변수에 때려넣고 1층 1호, 2층 3호와 같은 식으로 "지칭"하면 더 간단하게 코딩할 수 있을것이다.
다음의 예제를 보자
using System;

class Test {   public static void Main() {     string[,] a = {{"kim","park","lee","choi","min" },{"ru","won","hong","wang","ko"}};     Console.WriteLine (a[1,1]);   } }


"won"씨 아저씨가 "네!!"라고 응답하는가? ^^?

이제 가변배열이다. 가변배열은 위와 같이 2층에 5개의 아파트를 만든게 아니라 한층에는 평수를 좀 크게해서 1층에는 5개인데 2층에는 2개와 같이 각층의 아파트 갯수가 다를때 사용하는 방법 되겠다.
왜? 이렇게 사용하나? 그냥 크게 잡아서 2*5로 10개의 방을 만들어 놓으면 알아서 넣고 가져가면 되는데 말이다. 내 생각에는 아마도 "초기 컴퓨터의 용량문제와 깊은 관계가 있지 않을까 생각된다."
아무튼 한번 해보자. 물론 이것도 1차 배열의 응용일 뿐이다.

using System;

class Test {   public static void Main() {     string[][] a = {      new string[]{"kim","park","lee","choi","min" },      new string[]{"ru","won","hong"}     };     Console.WriteLine (a[0][3]);   } }


실행 해본다고 다는 아니고 이게 이해가 안되면 구조체를 이야기 할 수 없으니 이해가 안되면 1차원 배열부터 차근차근 다시 해보면서 오도록 하자.

이제 구조체다. 구조체는 배열보다 상위의 개념이다. 그리고 객체로 가는 중간단계이다. 왜?
배열에서 시작된 데이터의 집합을 좀더 직관적으로 명세화 하면서 만들어졌고 구조체에 "행위"다시말해 기능을 정의해놓은것이 객체이기 때문이다.

* 객체 = 스팩정의서(제원) + 기능정의서
* 구조체 = 스팩정의서(제원)
* 배열 = 데이터 집합

이제 예를 들어보면 다음과 같은 정보가 있다고 치자.

- 위치 : 동경 37.1, 북경 23.1

뭐 이런 데이터시트에 입력하고 빼고하는등의 일을 한다고 하면 어떻게 하겠는가? 배열로해결할 수 도 있겠지만 좀더 효율적인 방법을 사용할 필요가 있다. 그래서 대두된 것이 구조체(Struct)이다.
using System;

class Test {   public struct a{     public int x,y;     public a(int p, int q){       x = p;       y = q;     }   }   public static void Main(){         a A = new a(10,10);     Console.WriteLine ("X:{0},Y:{1}",A.x,A.y);         /*     //이렇게해도 마찬가지 결과     a A;     A.x = 10;     A.y = 20;     Console.WriteLine ("X:{0},Y:{1}",A.x,A.y);     */   } }



여기까지해서 객체의 전단계인 배열, 구조체까지 알아보았다.
여기에 하나더 보너스! 배열에 들어간 데이터를 모두 뽑아야 한다면 얼마나 노가다인가?
이럴때 쓰라고 있는 신의 선물이 있으니 바로 foreach문이다.

using System;

class Test {   public static void Main() {     string[,] a = new string[2,2]{{"kim","park"},{"ru","won",}};     foreach (string i in a){         Console.WriteLine (i);     }   } }


2007/03/21 17:59 2007/03/21 17:59

지난번에 "객체를 이제좀 알것같다.(클래스 편)"에서 클래스라는 넘을 한번 쯤 내가 이해하는 수준에서 뒤집어봤다.
뭐 나름대로 정리해본 결과 "객체란 속성과 기능을 정의한 정의서이다."라고 정의내려버렸다.
거기에 한걸음 더 나아가 클래스안에 있는 녀석들과 대화할 수 있는 인터페이스까지 소스상에서 만들어봤는데 "왜 그래야 하는가?"에 대한 물음에 대답하라면 "모든 클래스가 public으로 구현된다면 대규모 개발에서는 반드시 충돌이 일어날거다"라는 궁색한 변명밖에 할 수 없고 그것이 정답이라고 할 수도 없다.
객체지향 프로그래밍이란 하나의 표준이다. 따라서 생산성과 표준화란 미명하에 자유로운 프로그래밍 스타일을 해치는 말을 하고 싶지 않고 간단한 예로 PHP란 언어를 보면 객체지향이든 절차지향이든 원하는 스타일대로 프로그래밍하고픈 대로 하면 되는 언어는 이것이 정답이니까 이것으로 꼭 해야돼!라고 하는 것 자체가 언어의 특성을 죽이는 결과만 낳을 뿐이기에 더욱 더 그러하다.

오늘 하고 싶은 이야기는 객체의 인터페이스에서 더 나아가 객체 전체를 인터페이스 하는 방법인 상속에 대해 쓰려한다.
상속이라고 하니 굉장히 딱딱한 용어가 되어버리는데 이런 예를 들면 어떨까?

흔히 게시판이라고하는 사용자 저작 툴 다시말해 큰 의미의 객체에서 그 기능을 보면 쓰기, 읽기, 수정, 삭제, 그리고 리스팅 이렇게 5가지의 큰 기능이 있고 그중 하나인 쓰기만 하더라도 텍스트 입력, 이미지 링크걸기, 파일 업로드, DB저장 등의 기능이 세분화 되며 다시 텍스트 입력을 보더라도 HTML 코드 입력, 색깔지정, 크기 지정 등등의 세부 기능이 또 따로 존재한다.

여기에서 프로그래밍에서 변치않은 명제 "Division & Conquer"를 대입해보자.

쪼게고 쪼게서 쪼겔때가 없는 나머지 하나를 공략해 구현한다는 취지에서 보면 우리는 제일먼저 텍스트입력기능을 하는 클래스부터 개발해야 할 것이다. 그리고 HTML입력 클래스를 개발할 것이고 이미지 업로딩 기능을 하는 클래스를 개발하고 등등등 세부 클래스를 만들것이다.
그렇다면 이제 문제 이것을 어떻게 합칠 것인가라는 문제에 도달한다.
차에 비교한다면 타이어와 브레이크, 조향장치, 엑셀, 엔진등의 부품을 사다놓고 이를 조립하는 과정이랄까?

다시말해 "상속은 조립이다"

이를 코드로 예제로 들면 다음과 같다.

using System;

class Test {   public static void Main() {     //b클래스를 초기화한다.     b b = new b();     //b클래스에 없는 abc인터페이스를 설정한다.     b.abc = "Hello";     //b클래스에 없는 "mthod_a"를 호출하자.     Console.WriteLine (b.mthod_a());   } }

public class a{     private string aa = "1234";     public string abc{           get { return aa; }           set { aa = value; }     }     public string mthod_a(){         return aa;     } }

public class b:a{    public string bb = "bbbb";    public string mthod_b(){       return bb;    } }


예제를 보면 "b"클래스는 "a"클래스를 상속받았다. 이를 통해 무엇을 할 수 있는가?
Main()을 보면 "b"클래스를 초기화하여 메모리로 올렸음에도 a에 있는 인터페이스와 메소드를 작동시킬수 있는 것이다.

이것만 이해한다면 객체지향프로그래밍의 중요한 특징 2가지를 모두 이해한것이다.
나머지는 언어의 특성이므로 다음부터는 C#을 기준으로 이야기해보자.

2007/03/14 16:36 2007/03/14 16:36