비주얼 베이직으로 프로그램 개발하는데...
매우 난감한 상황이 발생한다.

비주엘 베이직에서는, 대부분의 프로그래밍 언어가 그렇듯, 값을 전달할 때 참조에 의해 전달하는 것과 값 자체로 전달하는 두가지 방법을 사용할 수 있다.

문제는, 그럼에도 불구하고 "포인터"라는 개념이 없다는 것이다.

그 결과, = 연산자를 사용할 때, 이게 도대체 값으로 넘어가는건지 주소로 넘어가는건지 알 수 없게 되어 버리는 경우가 많다.
그리고 당연히 메모리 참조 오류가 발생하게 된다.

답답하다. -_-

그 다음으로 답답한건 배열의 선언과 사용이다.
배열은 다음과 같이 선언한다.
dim arr(10) as integer
자, 질문이다. 위와 같이 선언하면 사용할 수 있는 배열의 크기는 모두 몇칸일까?
정답은 "11"칸이다. 인덱스가 0부터 10까지 갈 수 있다. 내가 C에 익숙해서 그런건지는 모르겠지만, 저 사소한 차이가 개발에 아주 큰 어려움을 주고 있다. 대체 0부터 어디까지 세야 하는건지 쓸 때마다 헷갈린다.
딱 10개만 쓰고 싶으면 그냥 1부터 시작해서 쓰라고 "책"에는 나와 있지만, 숫자는 0부터 시작하는 것이 정석이다. -_-

생각해보니, 내가 만든 배열이야 0부터 쓰든 1부터 쓰든 문제가 없지만, 남이 쓴거 가져다 쓸 때는 골치아파지는 문제가 생길 수도 있다. 그 사람이 1부터 시작했는데 내가 0부터 시작하기로 한다거나, 그 사람이 9까지 쓰기로 했는데 내가 10까지 쓰기로 한다거나 하면 엉뚱한 값이 들어와 버릴 수도 있다. 즉, 애초에 0부터 10까지 11칸을 쓰기로 하는 것이 가장 정확하다는 뜻이다.

MS에서...C랑 다른 무언가를 만들려고 하다가 좀 삽질한 듯 싶다.

셋째로...
조건절 평가할 때 전부 다 계산해보고 한다. 이건 단점인지 장점인지 모르겠지만 불편하다. 예를들어
if Not (objData is nothing) and objData.someFlag then
    someFunction(objData)
end if

이렇게 쓰면 objData가 nothing(이라고 쓰고 Null이라고 읽는다) 인 경우에는 오류가 발생한다. 왜냐하면 objData.someFlag는 아직 정의되지도 않은 객체의 속성이기 때문에 객체 참조 오류가 나오는 것이다. 하지만 이미 objData가 nothing이라는 조건이 만족되었기 때문에 그냥 넘어가면 안되는 걸까? 끝까지 평가를 다 해봐야 아나...그것도 and로 이어진 조건들인데. 똑똑하지 못한 것 같다.

*추가 : and 대신에 andAlso 연산자를 쓰면 앞에서 조건이 만족되면 뒤쪽은 계산하지 않는다.
by snowall 2009. 7. 24. 22:27
  • NoSyu 2009.01.20 15:54 ADDR EDIT/DEL REPLY

    그러고보니 비베에는 레퍼런스 개념이 없던 것으로....
    잘 기억이 안나네요.
    고딩 때 배우고나서 그 뒤로는 전혀 쓰지 않다보니...
    그리고 그 때는 그런 개념없이 그냥 막 썼으니까....OTL.......

    제 기억으로는 MSDN을 통해 알 수 있었던 듯도 싶습니다만, 아닌가요??;;;;

    • snowall 2009.01.20 16:00 신고 EDIT/DEL

      왜 고수들이 VB를 허접하다고 하는지 알 것 같아요...
      게다가, 저야말로 라면 코딩의 진수를 보여주고 있기 때문에...-_-;

    • NoSyu 2009.01.20 17:19 EDIT/DEL

      그래도 GUI를 간단히 만들 때는 VB만한 것이 없더군요.
      그래서 C로 DLL을 만들어 연결해 썼던 기억이..;;;
      (사실 Win32 API는 배웠지만 MFC는 배우지 않았기에..;; )
      최근 C# 및 닷넷 프로그래밍이 상당히 편하고 좋다고들 하던데 거기 안에 들어있는 VB도 그러한가요??;;;
      그렇다면 많이 낭패군요.OTL....

    • snowall 2009.01.20 17:31 신고 EDIT/DEL

      듣자하니, MS가 닷넷으로 오면서 VB는 포기했다던데요...-_-
      (되긴 잘 되지만...)

      제가 좀 정석대로 개발한다면 좋겠는데, 야매로 독학해서 배운지라 가면 갈수록 코드가 꼬입니다...
      1000줄 정도 작성했는데, 처음부터 다시 해야 할 듯 싶어요...ㅜ_ㅜ

  • NoSyu 2009.01.20 17:44 ADDR EDIT/DEL REPLY

    어떤 프로그램을 만드시는지 모르겠지만, Perl이나 Python도 괜찮지 않을까요?
    MS가 VB를 포기했다니 놀랍네요.;;;;
    그만큼 GUI 구현이 쉬워진 것인가...
    (이런 것도 모르는 나는 과연 컴공과인가... 먼산...)

    그보다 확실히 저렇게 헷갈리는 것 오랜만에 보네요.
    사실 MATALB으로 코딩할 때 index가 1부터 시작해서 많이 난감했습니다.OTL....
    C에서 index가 0부터 시작하는 이유를 알고 거기에 맞춰 배열을 이해하다보니 다른 언어에서도 자동으로..OTL.....

    • snowall 2009.01.20 18:24 신고 EDIT/DEL

      음...뭐, 그냥 소문으로 들은거라...-_-;
      진짜 포기했는지는 모르겠네요...;;

      Python은 강제 들여쓰기 때문에 보자마자 안쓰기로 한 언어라...;;
      Perl은 배우고는 싶은데 못 배웠구요...

      아무튼, 다른 언어로 개발하고 싶어도 못하는 사정이 있어요.
      음...제가 지금 개발중인게, 디지털 오실로스코프에서 데이터를 받아와서 그래프로 뿌려주는 프로그램인데, 이게 디지털 오실로스코프의 VB Automation을 지원합니다. 즉, VB에 최적화 되어 있죠.
      이걸 다른 언어로 구현하려면, VB Automation 부분만 떼어내서 DLL로 만들든 모듈로 만들든 뭔가 해야 하는데, 그 시점에서 이미 제가 공부한 영역을 넘어서 버립니다...

      지금 Automation만 갖고도 삽질 중인지라...-_-;;;

      개인적으로는, 배열 선언할 때 쓴 숫자는 배열의 갯수가 되어야 한다고 생각합니다. arr(10)으로 선언했으면 10칸짜리 배열을 선언했다고 생각하고 싶어요. 인덱스가 0부터 9까지든, 1부터 10까지든.
      (VB는 양쪽 다 수용한다는 차원에서 0부터 10까지로 한 것 같지만, 헷갈리게 되었죠...)

      저의 주전공은 물리학이고, 또다른 주전공이 수학입니다. 전산은...그냥 취미였는데...-_-; 본업이 되었으니 삽질할수밖에요.

    • NoSyu 2009.01.20 18:37 EDIT/DEL

      아.. VB Automation을 지원한다면 그렇게해야겠네요.

      예전 1학년 때 컴공과를 간다고 하자 물리학과 박사과정인 사촌형이 '후에 도움 좀 받을 수 있겠다.'라고 얘기해서 어리둥절했던 기억이 납니다.
      저보다 수학도 잘하고 물리도 잘하는 사촌형인데 컴공과인 저에게 무슨 도움을 받겠다는건지...;;;;
      이제야 조금 감이 잡히네요.;;;

      사실 저도 Python은 들여쓰기로 구분한다는 점에서 배우는 것을 포기했습니다. 어차피 들여쓰기를 하기에 별 상관은 없지만, 그래도 괄호 닫기 이후 주석을 적는 것으로 반복문이나 조건문의 끝을 이해하기에 Python은 너무 새롭더군요.;;;

      제 생각에는 성능은 그리 크게 신경쓰지 않아도 되지 않나 싶습니다. 전에 어느 잡지에서 성능을 좋게 한다며 6개월간을 알고리즘과 코드 최적화에 힘 쓰다가 결국 결과물을 내는데 실패했다는 글을 보았습니다. 따라서 10칸이든 11칸이든 설령 쓰지 않는 노는 것이 있더라도 돌아가기만 하면 되지 않을까 생각해봅니다.(아.. 전혀 다른 문제인가요?OTL....)

    • snowall 2009.01.20 19:44 신고 EDIT/DEL

      어차피 성능은 신경 안씁니다 -_-;
      헷갈린다는 점이 문제라는 거죠...

  • ㄹㄹㄹ 2009.07.25 02:16 ADDR EDIT/DEL REPLY

    6.0 쓰시나요? 정확히 포인터는 아니지만 비베에도 ByRef 있구요. 이런 식이라면 Java도 포인터가 없지요. 코드를 직접 보고 primitive type인지 판단한 후 byval이지 byref인지 판단해야 하니깐요. 아무튼 아직도 VB 6.0을 쓰는 사람이 있다는 것은 그만한 이유가 있기 때문인데요. 숙달만 되면 정말 대단한 생산성이 나옵니다. 어떻게 보면 언어의 대부분이 COM wrapper수준으로 전락해 버렸다고 볼 수도 있지만 한편으로 엄청나게 단순하게 COM을 다룰 수 있게 되었기 때문에 무지 강력해 진거죠 ㅎㅎ

    • snowall 2009.07.25 06:05 신고 EDIT/DEL

      VS2005쓰고 있습니다.
      ByRef를 모르는건 아닙니다. 근데 그게 포인터가 아니라는게 문제죠 -_-;;; 변수에다가 어떤 값을 대입했을 때 주소가 넘어가는지 값이 넘어가는지 항상 헷갈린다는게 상당히 곤란합니다.

      그리고 지금 생각난 건데 =과 ==의 구별이 없는것도 꽤 난감한 문제네요.

      사실 지금 가장 답답한건 포인터가 아니라 배열이 되었습니다. 배열에다가 for문 쓸때 배열의 길이대로 돌리면 에러가 난다는 사실이 문제죠. 뭐, 아시겠지만 설명하자면...
      가령
      for i = 0 to dataArray.Length
      someFunction(dataArray(i))
      next

      이런식으로 코드를 쓰면 에러가 납니다. dataArray.Length는 0부터 세기 때문에 인덱스에서 허용하는 수보다 항상 1이 더 크거든요. 따라서 언제나

      for i = 0 to dataArray.Length -1
      someFunction(dataArray(i))
      next

      이런 식으로 써줘야만 합니다. C에서는 아시다시피
      for(i=0;i<dataArray.Length;i++){
      someFunction(dataArray(i));
      }
      이렇게 쓰면 되지요. 그럼 i가 dataArray.Length보다 같은 경우에는 실행이 되지 않기 때문에 언제나 정확하게 작동합니다. 배열의 길이에 대한 개념과 for문을 돌릴때 "To"라는 개념으로 쓰기 때문에 불편한 점이 있습니다. 즉, C로 친다면
      for(i=0;i=dataArray.Length;i++){
      someFunction(dataArray(i));
      }
      이렇게 밖에 코딩을 못하는, 그런 상황입니다. 틀릴수밖에 없죠 -_-;
      for(i=0;i=dataArray.Length -1 ;i++){
      someFunction(dataArray(i));
      }
      만약 C에서 위와 같이 코딩을 한다면 "넌 왜 그렇게 코딩하냐?"라고 고수들이 항상 지적할 겁니다.

      물론 While ... End While을 쓰면 C처럼 할 수도 있긴 합니다.
      i = 0
      While i < dataArray.Length
      someFunction1(dataArray(i))
      someFunction2(dataArray(i))
      i+=1
      End While

      이런식으로 하면 되는데, 이건 End While 직전에 i = 0 이라는 정의도 해줘야 하고 i+=1이라는 인덱스 증가도 따로 해줘야 하기 때문에 for문 돌리는 것 보다 불편하죠. 코드의 가독성도 떨어집니다.
      마찬가지로 Do ... Loop 도 같은 방식이므로 어쩔 수 없습니다.

      사실 VB Automation만 아니면...이 언어는 쓰레기라고 생각하고 싶네요. 코드가 헬 오브 지옥입니다. 짜장면 코드랄까요...(스파게티는 하얗게라도 보이지만 이놈은 새카맣죠...)