'Visual Basic'에 해당되는 글 6건

  1. 2008.11.16 개발방식의 모습에서 본 C#과 RAD 툴 이야기. 8
  2. 2008.10.24 동적 할당 이야기 - 3 1
  3. 2007.11.26 MDI 폼 예제
  4. 2007.10.17 VB 질문하는 법 2
  5. 2007.10.12 오랫만에 해보는 VB 4
  6. 2007.08.29 가변 인수 및 동적 배열 예제
Study - Programming/C#2008. 11. 16. 14:46

※이 글은 본인의 지극히 얄팍한 지식과 경험을 통해서 생각한 주관적인 글입니다. 이 포스팅의 기술적인 내용은 본인의 지식에서 나온 것이라 실제와 다를 가능성도 있습니다. 이에 대한 수정과 비판은 환영이나 비난은 자제해 주시면 감사하겠습니다.


  내가 처음 프로그래밍이란 것을 접한건 초등학교 3학년때 Visual Basic 5.0을 통해서였다. 일반적으로 프로그래밍을 배울 때는 C같은 언어를 통해서 변수,루프,함수 같은 기본 문법을 배우고 거기서 세세한 사항 및 기술 등을 배우고 다른 언어로 넘어가던지 윈도우 프로그래밍 같은걸 배우던지 할텐데, 난 바로 윈도우 프로그래밍부터 시작하다 보니 기본적인 문법 같은것도 대충 대충배우고 그랬었다.(C를 조금 하긴 했었지만 그때도 포인터나 구조체같은건 신경도 안썼다. 결정적으로 그런 개념들에 대한 중요성을 인식하지 못했었다. 독학이다 보니.) 실제로 함수 등의 문법 사항을 이해하기 시작한건 본격적으로 C를 공부하기 시작한 대학 1학년때 미친듯이 프로그래밍 공부 할 때였다.
  아무튼 이런식으로 약간 역순(말은 이렇지만 역순이라고는 생각하지 않는다. 대세가 위의 방식이지 내 방식이 정석이 아니다 뭐다 그런건 없다는 것이 본인의 생각이다.)으로 배우다 보니 편리한 RAD방식에서 딱딱한 콘솔 기반의 프로그래밍 그리고 거기서 윈도우 프로그래밍으로 넘어갈 때는 정말 힘들었었다. 그리고 좀더 편리한 방식이 없나 종종 생각하기도 했다. VB의 편리함은 충분히 좋은 장점이지만 그에 비해 언어적 약점이 많이 아쉬웠다. 그리고 C나 C++, JAVA같은 언어는 강력한 언어적 지원과 갈수록 좋은 개발환경을 제공해 주었지만 역시 VB의 편리함과 비교해서는 아쉬운 점이 많았다.
  그러다 접한 것이 C#이다. C#은 위 두가지의 장단점을 잘 조합한 좋은 언어라고 생각한다. 엄청나게 강력한 언어적 기능 그리고 윈폼을 활용한 강력한 개발 환경. 분명 기존 언어들과 비교해서 한발자국 나가긴 나간 언어이다. 예전에 RAD툴 관련 글들을 보면서 현재는 VB 등의 RAD툴이 강력한 생산성에도 불구하고 부실한 언어적 기능 때문에 빛을 못받고 있지만 갈수록 RAD툴은 대세가 될 것이라는 글을 많이 봤다. C#은 이 말이 실현되고 있음을 보여 주는 한가지 예라고 할 수 있다. 
  그러나 이 C#도 치명적인 약점이 있다. 바로 .NET Framework라는 것. 조그마한 프로그램을 만들었는데도 20MB 가까이 되는 .NET Framework 을 설치해야 한다는 것과 이것이 현재 닷넷의 큰 약점 중의 하나라는 것은 잘 알려진 사실이다.  .NET Framework위에서 돌아가는 방식은 분명 장점도 있겠지만 현재는 이 배보다 배꼽이 큰 문제가 심각할 수밖에 없다. Windows XP가 보급되기 전에 이 .NET Framework가 좀더 기반을 다지고 Windows XP에 .NET Framework가 함께 나왔다면 어떻게 되었을지 모르겠지만 현재로서는 아무리 Windows Vista에 이것을 넣고 Windows Update에 추가하고 하더라도 충분히 보급되기까지는 상당한 시간이 걸릴 것이다.
  그리고 Microsoft에서 만들다 보니 강력한 기능에도 불구하고 .NET Framework가 Windows기반에서만 돌아갈 수 있는 불상사(?)가 발생하여 JAVA와 비교해 아직은 부족하다.(Mono가 있지만 이것이 완전한 .NET Framwork라고 할 수 있을까?)
  이런 C#의 약점을 가지고 있지 않은 다른 언어는 없을까? 최근에 2009버전이 나온 Delphi가 있겠다. 어떠한 프레임워크 위에서 돌아가지 않으면서도 엄청나게 편리한 개발 환경과 최근 2009버전에서도 나타나는 강력한 언어적 기능 그리고 C,C++같은 어느 특정한 곳에서 독점하지 않는 것이 아니라 한 기업에서 독자적으로 밀고 있는 방식이라 그 발전 가능성과 발전 속도도 상당히 높다고 할 수 있다. 그러나 이 Delphi도 왠지 모를 비인기(상대적인 이야기이다.)와 처음 접하는 개발자는 좀 거북할 수 있는 문법 그리고 Windows개발쪽에서만 나타나는 강력함에서 완전하다고는 이야기 할 수 없다.
  아직까지는 RAD툴이 개발 방식의 대세라고는 이야기 할 수 없겠다. 그러나 언젠가는 이런 방식이 주류가 될 것이라고 난 믿는다. 완전하지는 않지만 분명 변화는 일고 있다. 강력한 언어 위의 강력한 개발 환경. 그런 변화가 언제쯤이면 일어날까 기대하며 이 글을 마친다.
Posted by 머리
Study- MSC/Computer2008. 10. 24. 19:48
  이번 포스팅에서는 동적할당을 객체의 생성쪽으로 확장해 보고자 한다. 먼저 말해두지만 이 포스팅은 포인터나 객체, 클래스를 설명하기 위한 포스팅이 아니다. 어디까지나 이런 사항에 대한 기본적인 지식은 알고 있다고 가정하고 진행하겠다. 우선 C++에서 Example이라는 클래스가 있고, 그것에 대한 객체를 생성해 보자.

Example ex;

  자. ex라는 객체가 생성되었다. 아마 특별한 문제 없이 제대로 돌아갈 것이다. 그리고 파괴도 잘 될 것이다. 하지만 이런 방식의 객체 생성은 권하고 싶지 않다. 대신 이런 객체의 생성을 권한다.

Example* pEx = new Example();

  위 방식은  Example라는 클래스 형식으로 메모리 공간에 할당을 한 후 그 주소를 pEx 포인터 변수에 넣어서 사용하게 하는 방식이다. 앞선 포스팅에서, 메모리의 어딘가에(HEAP) 공간을 할당한다고 했는데 위 방식도 바로 이런 방식이다. 이렇게 해 놓으면 이어서 이렇게도 가능하다

Example *pEx = new Example();
pEx = new Example();

  잘 이해가 가지 않을것이다. 무슨 이야기냐면 한 객체를 메모리에 생성하여 한 포인터에 주소를 기억시켰는데, 그 포인터를 재사용하여 또다른 객체를 또 생성하여 그 주소를 넣을 수 있다는 이야기이다. 물론 위 코드는 첫 객체의 해제에서 문제가 발생하지만 이런식으로 좀 더 코드에 유연성을 줄 수 있다. 그렇지 않으면 Example ex1,ex2; 등의 방식으로 객체를 생성해야 하는 문제가 발생한다.
  앞서 말한 유연성 외에도 이런 방식의 동적 할당을 통한 객체 생성은 맨 처음 말한 동적할당의 장점을 최대한 살릴 수가 있게 된다. 객체는 일반 변수보다 여기 저기서 사용될 가능성이 많다. 무슨 말이냐면 지역 변수 이상의 용도로 사용될 가능성이 많다는 이야기이다. 만약에 게임을 만들때 적을 표현하는 클래스가 있고 그 객체를 생성한다고 하면 상황에 따라 계속해서 적을 만들어 내야 하므로 동적 할당이 필요 할 수 밖에 없다.(int형으로 적을 표현할수는 없지 않은가?)
  이제까지는 객체를 동적할당 할 때 포인터를 이용하였다. 그 이유는 C++은 기본적으로 Call by Value 방식이기 때문이기 때문인데 이는 변수 및 객체의 사용을 한정적인 위치에서만 사용할 수 밖에 없게 만든다. 이 틀을 극복하기 위해서 메모리상의 주소로 읽기 위한 포인터가 사용되는데, 여기서 한단계 더 나가서 레퍼런스라는 개념이 나온다. 적어도 여기서는 Call by Reference와 Call by Address의 개념을 다르게 두자. Call by Address는 결론적으로는 포인터의 값을 이용한 Call by Value로 볼 수 있다. 엄밀하게 말하면 Call by Reference와는 다르다.(물론 내부적으로 이놈도 포인터를 쓰긴 쓴다.)
  말이 샜는데, C++ 이후의 객체 지향 언어는 기본 참조 방식을 Call by Value가 아니라 Call by Reference를 채택한 경우가 많다. JAVA가 그렇고, C#이 그러며, 심지어 Visual Basic도 Call by Reference가 기본이다.
  무슨 말이냐면 만약에

Example ex;

라는 코드가 있으면 C++에서는 ex가 객체 그 자체이지만 JAVA나 C#등에서는 저것은 그냥 참조를 위한 레퍼런스에 불과하지 객체 자체는 아니다. 즉 아무것도 못한다. 레퍼런스는 포인터처럼 메모리 상의 어떤 것을 가리켜야 그 의미가 있다. 즉

Example ex = new Example();

  와 같이 객체를 생성하고 그것을 참조하여야 한다.
  말이 많았다. 정작 하고 싶은 말은 '동적할당은 메모리 어딘가에 공간을 할당하고 포인터를 이용하여 그것을 참조한다, 그리고 이는 객체에서도 마찬가지이며 좀더 나아가 레퍼런스는 참조 없이는 아무런 의미가 없다'였는데 이것을 표현하기 위해 쓸데없는 말이 너무 많았던 것 같다.
  아무쪼록 이 글을 읽고 뭔가 '아!'하고 깨달음(?)을 얻는 프로그래머 지망생이 있으면 좋겠다. 그렇게 기원하면서 이상 3회에 걸친 포스팅을 마치고자 한다.
Posted by 머리
Study - Programming/C#2007. 11. 26. 01:00

사용자 삽입 이미지


using System;
using System.Windows.Forms;

class MyClass : Form
{
    Button[] btn = new Button[4];
    Form[] newMDICHild = new Form[10];
    string[] strData = { "수평", "수직", "계단식", "아이콘" };

    public MyClass(string strText)
    {
        this.Text = strText;
        this.IsMdiContainer = true;
        this.Load += new EventHandler(this.Form_Load);
        this.Closed += new EventHandler(this.Form_Closed);

        for (int i = 0; i < 4; i++)
        {
            btn[i] = new Button();
            btn[i].Text = strData[i];
            btn[i].SetBounds(50 * i, 10, 50, 50);
            btn[i].Click += new EventHandler(this.Btn_Click);
            this.Controls.Add(btn[i]);
        }

        this.Show();
    }

    public static void Main(string[] args)
    {
        Application.Run(new MyClass("MDI"));
    }

    private void Form_Load(object sender, System.EventArgs e)
    {
        Console.WriteLine("윈도우에 자식창을 생성");
        Form[] newMDIChild = new Form[10];
        for(int i = 0 ;i < 10 ; i++)
        {
            newMDIChild[i] = new Form();
            newMDIChild[i].Text = i + "번째 자식창";
            newMDIChild[i].MdiParent=this;
            newMDIChild[i].Closed += new System.EventHandler(this.Form_Closed);

            newMDIChild[i].Show();
        }
    }
    private void Form_Closed(object sender, System.EventArgs e)
    {
        Console.WriteLine(((Form)sender).Text + "윈도우가 Closed됩니다.");
    }

    private void Btn_Click(object sender, System.EventArgs e)
    {
        if ((Button)sender == btn[0])
        {
            this.LayoutMdi(MdiLayout.TileHorizontal);
            this.Text = "수평 바둑판 정렬";
        }
        else if ((Button)sender == btn[1])
        {
            this.LayoutMdi(MdiLayout.TileVertical);
            this.Text = "수직 바둑판 정렬";
        }
        else if ((Button)sender == btn[2])
        {
            this.LayoutMdi(MdiLayout.Cascade);
            this.Text = "계단식 정렬";
        }
        else if ((Button)sender == btn[3])
        {
            this.LayoutMdi(MdiLayout.ArrangeIcons);
            this.Text = "아이콘 정렬";
        }
    }
}

  후.. 요즘 윈도우 프로그래밍에 맛들여서.. 이런거 공부해 보는게 마냥 재미있네. 어쨋든 슬럼프였는데 갈길을 찾아서 다행이다. 시험 기간 제대로 돌입하기전에는 열심히 해봐야지.

  C#문법을 조금만 아는 사람이라면 금방 파악할 수 있을 것이다. 그만큼 쉽고 편리하게 구현하는게 가능하다. 실제 윈폼 구현은 다 IDE를 이용해서 하지만 콘솔로도 이렇게 간단하게 할 수가 있다. 특히 이벤트 구현을 저렇게 쉽게 해줄 수 있다니.. MFC/API를 사용할때와 비교해서 이렇게 차이가 난다. VB를 해보았다면 그때의 기억을 살리면서 신나게 해볼 수 있을 것이다. 아 앞으로 배울 것들이 엄청 기대된다.

Posted by 머리

DC 프갤에 올리기 위해 적어 본 글.

여기 올라오는 수많은 질문들의 대부분은 C이야기겠지만 가끔가다 VB도 보이더군. 특히 전과한 학생이거나 1학년 꼬꼬마들이 VB많이 묻더라.

  C같은건 그냥 소스 파일 대충 드래그해서 C & P 해주면 되겠지만, VB는 그렇게 했다가는 죽도 밥도 안된다. 소스파일만 달랑 보고서는 프로그램의 구조를 제대로 파악하기가 어렵기 때문이다. 여기 말고도 다른데 VB 관련 질문을 올리고 싶으면 이렇게 해라.

1. VB프로젝트의 구조.
  아시다시피 VB는 RAD툴이다. 이놈이 뭐하는 놈인지는 다 알겠지? 일단 VB프로젝트를(표준 EXE 기준) 하나 만들면 기본적으로 두 개의 파일이 생성된다. vbp라는 확장자를 가진 프로젝트 파일과 frm이라는 파일을 가진 폼 파일.

2. 각 파일의 용도 및 구조.
  프로젝트는 뭐하는 놈인지 알거다. 중요한 것은 frm파일이다. C의 소스 파일 확장자명이 .c라면 VB에서는 폼 파일 소스코드의 확장자명이 .frm이라는 것.
  그런데 이놈의 구조는 C와는 조금 다르다. 폼이라는 놈이 달랑 작성자가 입력한 코드만 가지고 있는게 아니라 폼에 추가된 컨트롤이나 기타 요소들의 프로퍼티들이 다 저장되어 있어서 눈에 보이는 것보다 훨씬 많은 정보들을 담고 있다.

사용자 삽입 이미지

  첫 번째 그림을 보자. 그림을 보면 위에는 폼 파일이고 밑에는 소스 코드이다. 별거 없다. 그런데 frm파일은 저기 코드만 가지고 있는게 아니라 훨씬 많이 가지고 있다. 한번 frm파일을 찾아서 한글같은 워드프로세서로 열어보자.

사용자 삽입 이미지

  글씨가 작아서 잘 안보이겠지만 맨 밑을 보면 우리가 친 소스코드가 보이지만 그 위에 많은 코드들이 더 있다. 내용을 보면 폼에 관한 정보들이다. 저게 바로 소스코드의 원문이다.

3. 무엇이 문제인가?
  문제는 냅다 폼 아무데나 더블클릭해서 전부 복사해서 붙여 넣는다는거다. VB는 컨트롤 이벤트를 중심으로 코드가 돌아가기 때문에 폼에 관한 정보 없이 그런 코드만 보면 알아보기가 정말 어렵다. 예를 들어
Private Sub cmdStart_Click()
txtShow.Text = "Hello,World!"
End Sub
  이렇게 해놨다고 치자. 저렇게 해놓으면 cmdStart가 커맨드 버튼인지 텍스트 박스인지 알리가 없고 txtShow가 레이블인지 버튼인지 폼인지 알리가 없다. 그나마 내가 이름 txt나 cmd로 해놔서 알 수 있는거지.
  그리고 당장 폼이 어떻게 생겼는지도 모르고 몇 개의 컨트롤이 필요한지 어디다 해야 그려 넣어야 하는지도 모르기 때문에 답변하기가 상당히 곤란하다.

4. 그럼 어떻게 해야 하는가?
  폼의 스크린샷 가지고는 부족하다. 컨트롤의 이름 등을 제대로 파악하기 어려우니까.
  읽는 사람 입장에서 가장 편한 방법은 프로젝트를 압축해서 올리는 거지만 너무 성의가 없다. 최소한 컨트롤의 스펙 정도는 알려 주자. 그리고 올리더라도 frm파일을 올려주면 보기 정말 편하다. 그렇다고 frm파일 원문을 통째로 C & P하면 아예 답변 받을 생각 하지 말기 바란다.
  그리고, 프로그래밍을 할때 제발 컨트롤이름도 신경써서 해 주자. 변수이름은 신경쓰면서 컨트롤 이름은 왜 죄다 form1, command1. text1, 이런건데? txtShow,cmdStart,cmbView 이런거면 얼마나 보기 좋아.
 

이상이다. 그냥 공강시간에 시간이 좀 많이 남아서 써봤다. 제일 좋은 방법은 혼자 해결하고 이런데 질문 올리지 않는 것이지만, 혹시라도 DC아닌 다른데 질문하게 되면 이정도는 최소한으로 지켜 주자.
Posted by 머리

인터넷 돌아다니는데 누가 VB관련 질문을 했길래 그냥 심심해서 1분만에 짜 본거 대충 문자열 자르는 거 구현하는 것이다.

진짜 VB오랫만에 하는구나.. 맨날 C만 하다가 VB하니 어색하다.. 왠지 씁쓸. 훨씬 VB를 오래 했는데..

다음은 소스.

Option Explicit


Sub main()
Dim b_input As String
Dim arry(10) As Integer
Dim cnt As Integer
Dim i As Integer


cnt = 0
b_input = InputBox("입력해봐", "입력")

If b_input <> "" Then
    For i = 1 To Len(b_input)
        If "," <> Mid(b_input, i, 1) Then
            arry(cnt) = Val(Mid(b_input, i, 1))
            cnt = cnt + 1
        End If
    Next i
Else
    MsgBox "제대로 입력해"
End If

For i = 0 To cnt - 1
    Debug.Print "arry(" & i & ") = " & arry(i)
Next i
End Sub

이거 쓰면서 자꾸만 C하던 습관이 나와서 고생했다.
예를 들어
if a = 1 then 이렇게 해야하는걸 if(a==1){}하려 했다건가
for i = 1 to 10 하려는걸 for(i = 1 ; i <= 10 ; i++)하려 하던가
끝에 세미콜론(;)을 붙이려 하려 했다던가..


웃긴건 C를 할때는 역으로 된 상황을 자주 겪는다.

그리고 또 하나 신기한거. VC++의 코드를 그대로 복사해서 딴데 붙여 넣으면 들여쓰기가 제대로 안되어서 나오는데 VB는 제대로 되는구나. 편하다.

Posted by 머리

커맨드 버튼 하나만 만들어 놓고 붙여넣기


나머지는 알아서 주석으로 해결~~


Option Explicit
'가변 인수 테스트
'Inputbox로 수를 입력받아 그 합을 구한다.


'UBound 함수 : 배열의 마지막 번호를 넘긴다
'LBound 함수 : 배열의 첫 번호를 넘긴다.
'ex : Dim exam(2 to 4) as Integer
'Debug.print LBound(exam) 결과 : 2
'Debug.print UBound(exam) 결과 : 4

Public Function Sum(ParamArray vArgs())

    Dim i As Integer '루프 변수
    Sum = 0
   
    For i = LBound(vArgs) To UBound(vArgs) '합계 구하는 루프
   
        Sum = Sum + vArgs(i)
   
    Next i
   
End Function

Private Sub Command1_Click()
Dim Args() As Integer '인자 배열
Dim InputNumber As Integer '입력 변수
Dim Count As Integer '첫 입력인지 확인
Dim i As Integer '출력값

Count = 0



Rem 입력 받는 루프, 0이 나올때까지 루프

Do
    InputNumber = Val(InputBox("수를 입력해 주세요(0 : 입력 종료)", "입력")) '입력 받는다
   
    If InputNumber <> 0 Then '입력 받은게 0이 아니라면 배열에 수를 넣는다.
       
        If Count = 0 Then '제일 처음 입력하는 것이면
            ReDim Args(1) As Integer '일단 배열 한개 만들고
            Args(0) = InputNumber '0번째 배열에 첫 수를 넣는다.
            Count = Count + 1 '카운트 추가 -> 사실 이거는 bool형으로 해서 처음이냐 아니냐만 체크해도 되는데.. 일단 이걸로 수도 셀수 있고 하니 놔둠.
       
        Else '처음 입력이 아니면
       
            ReDim Preserve Args(UBound(Args) + 1) As Integer '데이터를 보존하면서 배열 크기 재선언
            Args(UBound(Args) - 1) = InputNumber 'VB의 배열 틍징 -> 배열 크기를 1로 하면 공간이 2개 생긴다 -_-;; -> 그래서 마지막 번호 앞의 거에다가 입력 값을 넣는다
        End If
   
    End If
   
Loop While InputNumber <> 0 '0이 입력안되는동안 계속 루프

If Count <> 0 Then
    ReDim Preserve Args(UBound(Args) - 1) As Integer '이거 지우고 한번 debug.print로 배열 첨부터 끝까지 루프 돌려보면 안다,(UBound,LBound 참조) 맨 마지막에 배열 요소 하나가 남기 때문에 공간 하나를 없앤다.
End If

'출력
For i = LBound(Args) To UBound(Args)
    Debug.Print "Args(" & i & ") : " & Args(i)
Next i

'가변 인수 테스트
Debug.Print
Debug.Print Sum(1, 2, 3, 4, 5)
End Sub

Posted by 머리