Devin.KR

변수와 데이터 형식 - Option Strict 를 켜고

개발자KR 조회 0

이 장에서 배우는 것

앞 장에서 Visual Basic 콘솔 프로젝트를 만들고 화면에 문장을 출력했다. 이제 비품 이름, 보유 수량, 하루 대여료처럼 프로그램이 기억할 값을 마련한다. 같은 비품 정보라도 이름은 글자이고 수량은 정수이며 대여 여부는 참이나 거짓이다. 이 차이를 코드에 나타내면 계산할 수 있는 값과 글자로 표시할 값을 구분하기 쉬워진다.

변수(variable)는 이름을 붙여 값을 보관하고 필요할 때 바꾸는 수단이다. 데이터 형식(data type)은 그 변수에 어떤 종류의 값을 담을지 정하는 규칙이다. 이 장에서는 작은 사무실의 프로젝터 대여 기록을 변수로 표현하고, 수량과 대여 기간을 이용해 청구 금액을 계산한다. 사용자가 입력하는 기능은 아직 넣지 않는다. 정해 둔 값으로 실행하므로 매번 같은 결과를 확인할 수 있다.

  • Dim과 As로 변수를 선언하고, 선언과 값 대입의 차이를 설명한다.
  • Integer, Double, Decimal, Boolean, String, Date 중 정보에 알맞은 형식을 선택한다.
  • 형 변환 함수로 값의 형식을 명시적으로 바꾸고, 변환 과정에서 달라질 수 있는 값을 확인한다.
  • Option Strict On과 Option Explicit On을 적용해 형식과 변수 이름의 실수를 컴파일할 때 찾는다.
  • 날짜와 금액을 일정한 형식으로 출력하는 대여 기록 프로그램을 완성한다.

문제 상황

작은 사무실에서 프로젝터 세 대를 이틀 동안 대여한다고 가정한다. 하루 대여료는 한 대에 15,000원이며, 이번 대여에는 전체 금액의 10%를 할인한다. 담당자는 비품 이름, 대여 수량, 기간, 대여일, 대여 여부와 최종 청구 금액을 한 번에 확인하고 싶다.

이 정보를 모두 글자로 저장하면 화면에는 쉽게 표시할 수 있지만 곧 문제가 생긴다. 수량을 나타내는 "3"과 기간을 나타내는 "2"를 글자 연결 연산으로 합치면 "32"가 된다. 필요한 결과는 두 글자를 붙인 값이 아니라 대여료에 곱할 숫자다. 반대로 비품 이름인 "회의실 프로젝터"에는 곱셈을 적용할 이유가 없다.

금액과 측정값도 구분할 필요가 있다. 프로젝터의 무게 1.35kg은 소수로 표현하는 측정값이고, 15,000원은 금액이다. 소수점이 있다는 이유만으로 같은 형식을 고르기보다 계산 목적에 맞춰 형식을 선택해야 한다. 대여 여부에는 "대여 중"이라는 문장을 저장할 수도 있지만, 상태 자체는 참 또는 거짓으로 보관하고 표시 문장은 따로 만드는 편이 의미가 분명하다.

이번 프로그램은 이런 정보를 각각 알맞은 변수에 담는다. 수량과 기간은 Integer, 무게는 Double, 대여료와 할인율은 Decimal로 정한다. 비품 이름은 String, 대여일은 Date, 대여 여부는 Boolean으로 표현한다. 형식을 먼저 정해 두면 잘못된 값을 넣는 순간을 더 일찍 알아차릴 수 있다.

Dim과 As로 값을 담을 자리를 정한다

선언(declaration)은 변수의 이름과 형식을 코드에 알리는 일이다. Dim 다음에는 변수 이름을, As 다음에는 데이터 형식을 쓴다. 선언하면서 처음 사용할 값도 지정할 수 있다. 아래 문장은 quantity라는 이름의 Integer 변수를 만들고 값 3을 넣는다.

Dim quantity As Integer = 3

여기서 Dim은 선언을 시작하는 예약어다. 예약어는 언어가 특별한 뜻으로 사용하는 단어다. As Integer는 이 변수가 정수를 보관한다는 뜻이다. 오른쪽의 3은 코드에 직접 적은 값인 리터럴(literal)이다. 이 문장에서 등호는 양쪽 값이 같은지 묻는 기호가 아니라, 오른쪽 값을 왼쪽 변수에 넣는 대입(assignment)을 나타낸다.

한 번 선언한 변수의 값은 나중에 바꿀 수 있다. 값을 바꾸는 문장에는 Dim과 As를 다시 쓰지 않는다. 아래 코드를 위에서 아래로 실행하면 quantity의 값은 먼저 3이 되고, 다음 문장에서 4가 된다. 두 번째 문장의 오른쪽 quantity는 변경 전 값인 3을 가리킨다.

Dim quantity As Integer = 3
quantity = quantity + 1
Console.WriteLine(quantity)

변수 이름은 역할이 드러나게 정한다. quantity는 수량, loanDays는 대여 일수, dailyFee는 하루 대여료를 뜻하도록 사용한다. a나 b처럼 짧은 이름도 문법상 가능하지만, 여러 정보가 함께 있을 때 계산의 의미를 파악하기 어렵다. Visual Basic은 이름의 대소문자를 구분하지 않으므로 quantity와 Quantity는 같은 이름으로 취급한다. 그래도 작성할 때는 같은 표기를 유지하는 편이 읽기 쉽다.

값을 지정하지 않고 선언하는 것도 가능하다. Integer, Double, Decimal의 기본값은 0이며 Boolean의 기본값은 False다. String의 기본값은 빈 문자열이 아니라 Nothing이다. Nothing은 String에서는 문자열 객체가 없는 상태를 나타낸다. 빈 문자열은 글자 수가 0인 문자열인 ""로 따로 표현한다. Date의 기본값은 서기 1년 1월 1일 자정이다. 대여 기록에서는 기본값에 기대기보다 실제 사용할 값을 선언할 때 지정한다.

값이 바뀌더라도 변수의 선언된 형식은 유지된다. Integer 변수에 4를 넣는 것은 자연스럽지만, 비품 이름을 넣으면 형식이 맞지 않는다. 다음 그림은 변수 이름, 형식, 값의 역할을 구분한다. 실제 컴퓨터 내부의 저장 구조를 그린 그림은 아니며, 선언문을 읽는 순서를 나타낸다.

변수 선언은 이름과 데이터 형식을 정하고 처음 사용할 값을 넣는다

정보의 의미에 맞는 데이터 형식을 고른다

이번 대여 기록에 필요한 여섯 형식은 모두 Visual Basic에서 바로 사용할 수 있다. 먼저 값이 어떤 의미인지 생각하고, 그다음 형식을 선택한다. 특히 숫자처럼 보이는 정보가 항상 계산용 숫자는 아니다. 비품 관리 번호 "0037"은 앞의 0을 유지해야 하므로 String이 적합할 수 있다. 보유 수량 37은 더하거나 줄일 값이므로 Integer가 적합하다.

대여 기록에 쓰는 여섯 데이터 형식과 선택 기준
형식담는 값이 장의 예선택 기준
Integer32비트 정수대여 수량 3소수 부분 없는 개수나 일수
Double배정밀도 부동 소수점 수무게 1.35kg측정값과 근삿값 계산
Decimal십진수 기반의 수대여료 15000D금액과 십진 소수 계산
BooleanTrue 또는 False대여 여부 True두 가지 상태의 구분
String문자열"회의실 프로젝터"이름과 표시 문구
Date날짜와 시간#6/15/2026#달력 날짜와 시각

Integer는 개수, Double은 측정값에 쓴다

Integer는 -2,147,483,648부터 2,147,483,647까지의 정수를 표현한다. 여기서 32비트는 값을 표현하는 데 사용하는 이진 자리의 수다. 사무실 비품 수량에는 넉넉한 범위지만, 정수라고 해서 어떤 크기의 수든 담을 수 있는 것은 아니다. 소수 부분을 보관해야 하는 무게에는 다른 형식이 필요하다.

Double은 부동 소수점(floating point) 방식으로 수를 표현한다. 소수점 위치를 고정하지 않고 수의 크기와 유효한 자릿수를 함께 저장하는 방식이다. 넓은 범위의 수를 다룰 수 있지만, 많은 십진 소수는 이진 표현에서 정확하게 저장되지 않아 가까운 값으로 보관된다. 예를 들어 코드에 적은 1.35도 내부에서는 근삿값이다. 측정값을 다룰 때 유용하지만, 모든 소수 계산이 십진수 기준으로 정확하다고 가정하면 안 된다.

Dim quantity As Integer = 3
Dim weightKg As Double = 1.35R

숫자 뒤의 R은 해당 숫자 리터럴을 Double로 지정하는 형식 문자다. 일반적인 소수 리터럴도 기본적으로 Double이지만, 여기서는 형식을 눈으로 확인하도록 R을 붙인다. R은 숫자의 단위가 아니므로 화면에 출력되지 않는다.

Decimal은 대여료와 할인율에 쓴다

Decimal은 십진 소수 계산에 적합하다. 표현 범위와 자릿수 안에서 0.1처럼 유한한 십진 소수를 정확하게 담을 수 있다. 금액 계산에서 Double의 이진 근삿값이 섞이지 않게 하려면 대여료와 할인율을 처음부터 Decimal로 정한다. Decimal도 범위와 정밀도가 유한하므로 모든 계산 결과를 끝없이 정확하게 담는 형식은 아니다. 1을 3으로 나누는 결과처럼 소수가 계속되는 값에는 표현 한계가 있다.

Dim dailyFee As Decimal = 15000D
Dim discountRate As Decimal = 0.1D

D는 Decimal 리터럴을 나타내는 형식 문자다. Visual Basic에서 D는 Double을 뜻하지 않는다. 변수 왼쪽에 As Decimal을 적고 오른쪽에는 0.1처럼 Double 리터럴을 쓰면, Option Strict On에서 허용하지 않는 변환이 필요해질 수 있다. 0.1D로 적으면 처음부터 원하는 형식의 값이 된다.

할인율 0.1은 10%를 계산에 사용하기 위한 값이다. 금액에 0.1을 곱하면 할인 금액을 구할 수 있다. 이 장의 예에서는 모든 결과가 정수 금액으로 떨어진다. 표시 자릿수를 정하는 일과 실제 청구 금액의 반올림 규칙을 정하는 일은 별개라는 점도 기억한다.

Boolean, String, Date로 상태와 기록을 나타낸다

Boolean에는 True와 False 두 값이 있다. 이번 예에서는 isLoaned가 True이면 대여된 상태라는 뜻으로 정한다. Boolean 자체에 "대여 중"이라는 한국어 문구가 들어 있는 것은 아니다. 상태 값의 의미는 변수 이름과 프로그램의 사용 방식으로 정한다.

String은 문자들이 이어진 문자열(string)을 담는다. 코드에서는 큰따옴표로 감싸서 적는다. 문자열 안에 큰따옴표를 넣으려면 큰따옴표를 두 번 쓴다. 예를 들어 "비품 ""프로젝터"""는 비품 "프로젝터"라는 문자열이다. 두 문자열을 연결할 때는 &를 사용한다. 이 장에서는 계산에 쓰는 +와 글자 연결에 쓰는 &를 구분해 작성한다.

Dim itemName As String = "회의실 프로젝터"
Dim isLoaned As Boolean = True
Dim loanDate As Date = #6/15/2026#

Date는 날짜뿐 아니라 시간도 담는다. 위 날짜 리터럴은 #으로 감싸며 2026년 6월 15일을 뜻한다. 시간을 적지 않았으므로 시각은 자정이다. Date 값 자체에 화면 표시 방식이 붙어 있는 것은 아니다. 같은 날짜라도 출력할 때 형식을 지정하면 2026-06-15처럼 일정하게 표시할 수 있다. 이번 예의 Date에는 시간대 정보가 포함되어 있지 않다.

Option 설정과 명시적인 형 변환

형 변환(conversion)은 값을 다른 데이터 형식으로 바꾸는 일이다. 정수 수량을 소수 계산에 사용하거나, 문자열에 담긴 숫자를 실제 숫자로 계산할 때 필요하다. 변환이 자동으로 이루어지는 경우도 있지만, 값의 정보가 줄어들 수 있는 변환은 코드를 작성한 사람이 직접 드러내는 편이 안전하다.

Option Strict On은 컴파일러가 형식 사용을 더 엄격하게 검사하도록 한다. 컴파일러(compiler)는 실행 전에 소스 코드의 문법과 형식을 검사하고 실행 가능한 형태로 바꾸는 도구다. Option Strict On에서는 값을 잃을 가능성이 있는 암시적 축소 변환을 허용하지 않는다. 형식을 Object로 암시적으로 정하는 일부 선언과, 실행 시점에 대상 기능을 찾아 호출하는 늦은 바인딩도 제한한다. 이번 프로그램에서는 모든 변수에 As를 적고 직접 형 변환 함수를 호출하므로 형식 관계가 코드에 드러난다.

Option Explicit On은 변수를 선언한 뒤 사용하도록 요구한다. quantity를 선언했는데 quantitty라고 잘못 쓰면 선언되지 않은 이름이라는 오류를 확인할 수 있다. 두 설정은 역할이 다르다. Explicit은 선언 여부를, Strict는 형식 사용의 규칙을 확인한다. 파일 맨 위에 두 줄을 적으면 이 파일에서 적용할 규칙이 분명해진다.

Option Strict On
Option Explicit On

이 옵션은 Module Program보다 앞에 둔다. dotnet run은 실행에 필요한 빌드도 수행하므로, 규칙을 어긴 코드가 있으면 프로그램 출력 전에 컴파일 오류를 보여 준다. Option Strict On은 오류를 숨기는 기능이 아니라, 실행하기 전에 수정할 지점을 알려 주는 규칙이다.

이 장에서 사용하는 형 변환 함수와 주의점
함수결과 형식예주의점
CIntIntegerCInt("3")소수는 반올림하며 범위 제한이 있다
CDblDoubleCDbl(quantity)십진수의 정확성이 줄어들 수 있다
CDecDecimalCDec(quantity)변환 전 계산에서 잃은 정보를 복원하지 않는다
CBoolBooleanCBool("True")임의의 상태 문구를 변환하는 함수는 아니다
CStrStringCStr(quantity)날짜와 소수의 표현은 문화권의 영향을 받는다
CDateDateCDate(dateText)문자열 날짜 해석은 문화권의 영향을 받는다

축소 변환은 실제로 작은 값이 들어 있더라도 형식 전체의 관계를 기준으로 판단한다. 예를 들어 Double 변수에 3.0만 들어 있어도 Integer로 자동 대입할 수는 없다. Double은 소수나 Integer 범위를 벗어나는 수도 담을 수 있기 때문이다. CInt를 쓰면 정수로 바꾸겠다는 의도를 명시한다. 다만 변환 함수를 적었다고 모든 값의 변환이 성공하는 것은 아니다.

CInt는 소수 부분을 단순히 버리지 않는다. 가장 가까운 정수로 반올림하고, 정확히 중간인 경우에는 가까운 짝수로 맞춘다. CInt(2.5R)는 2이고 CInt(3.5R)는 4다. 비품 수량에 소수가 들어온 상황에서 CInt로 조용히 반올림해도 되는지는 업무 규칙에 따라 판단해야 한다. 이 장의 수량 문자열은 처음부터 "3"으로 정해 두므로 이런 판단이 필요하지 않다.

Option Strict On에서는 Double을 Integer로 바꿀 때 명시적 변환이 필요하며 CInt는 반올림한다

문자열 변환은 문자열의 내용에도 좌우된다. CInt("3")은 숫자로 바꿀 수 있지만 CInt("세 대")는 실행 중 실패한다. CBool("True")는 참으로 바꿀 수 있지만 CBool("대여 중")은 업무 문구를 해석해 주지 않는다. 잘못된 입력을 처리하는 기능은 뒤에서 다룰 주제이므로, 이번 완성 코드에서는 변환 가능한 값만 사용한다.

소수와 날짜를 문자열에서 읽거나 문자열로 표시할 때는 문화권(culture)도 고려한다. 문화권은 날짜 순서나 소수점 기호 같은 표현 관례를 정하는 정보다. 이 장의 코드에서는 문화권에 따라 달라지는 날짜 문자열을 CDate로 읽지 않고 날짜 리터럴을 사용한다. 금액, 무게, 날짜를 출력할 때는 CultureInfo.InvariantCulture를 지정한다. 이것은 실행 컴퓨터의 지역 설정과 독립된 공통 형식으로 표시하기 위한 설정이다.

값 뒤에 .ToString을 붙이는 표기는 해당 값의 문자열 표현을 만드는 기능을 호출한다. 괄호에는 표시 형식과 문화권을 전달할 수 있다. "F2"는 소수점 아래 두 자리, "F0"는 소수점 아래 없이 표시하는 형식이다. 날짜의 "yyyy-MM-dd"는 네 자리 연도, 두 자리 월, 두 자리 일을 뜻한다. 날짜 형식에서 MM은 월이고 mm은 분이므로 대소문자도 의미가 있다.

완성 코드

앞 장에서 만든 프로젝트의 Program.vb 내용을 아래 코드로 바꾼다. 새 프로젝트가 필요하면 실행 결과에 제시한 생성 명령을 사용한다. 이 코드는 Program.vb 한 파일에 들어가며 별도의 입력이나 파일을 요구하지 않는다. Module Program과 Sub Main은 앞 장에서 사용한 실행 틀이다. 지금은 그 안에서 변수를 선언하고 계산하는 부분에 집중한다.

Option Strict On
Option Explicit On

Module Program
    Sub Main()
        Dim itemName As String = "회의실 프로젝터"
        Dim quantityText As String = "3"
        Dim quantity As Integer = CInt(quantityText)
        Dim loanDays As Integer = 2
        Dim weightKg As Double = 1.35R
        Dim dailyFee As Decimal = 15000D
        Dim discountRate As Decimal = 0.1D
        Dim isLoaned As Boolean = True
        Dim loanDate As Date = #6/15/2026#

        Dim totalFee As Decimal = dailyFee * CDec(quantity) * CDec(loanDays)
        Dim discountAmount As Decimal = totalFee * discountRate
        Dim payableFee As Decimal = totalFee - discountAmount
        Dim quantityLabel As String = CStr(quantity)

        Console.WriteLine("비품: " & itemName)
        Console.WriteLine("대여 수량: " & quantityLabel & "대")
        Console.WriteLine("대여 기간: " & CStr(loanDays) & "일")
        Console.WriteLine("무게: " & weightKg.ToString("F2", System.Globalization.CultureInfo.InvariantCulture) & "kg")
        Console.WriteLine("하루 대여료: " & dailyFee.ToString("F0", System.Globalization.CultureInfo.InvariantCulture) & "원")
        Console.WriteLine("대여 여부: " & CStr(isLoaned))
        Console.WriteLine("대여일: " & loanDate.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture))
        Console.WriteLine("할인 전 금액: " & totalFee.ToString("F0", System.Globalization.CultureInfo.InvariantCulture) & "원")
        Console.WriteLine("할인 금액: " & discountAmount.ToString("F0", System.Globalization.CultureInfo.InvariantCulture) & "원")
        Console.WriteLine("청구 금액: " & payableFee.ToString("F0", System.Globalization.CultureInfo.InvariantCulture) & "원")
    End Sub
End Module

대여 수량을 일부러 quantityText라는 문자열로 먼저 준비했다. 이를 CInt로 바꿔 계산용 quantity에 넣는다. 외부에서 읽은 값이 글자일 수 있다는 상황을 작은 예로 보여 주기 위한 구성이다. 실제 사용자 입력을 읽는 문장은 없으므로 실행은 대기하지 않고 끝난다.

줄별 해설

아래 줄 번호는 완성 코드의 빈 줄도 포함해 센 번호다. 긴 출력 문장은 화면에서 접혀 보이더라도 코드에서는 한 줄이다. 선언, 계산, 출력 순서로 읽으면 각 변수가 언제 만들어지고 어디에 쓰이는지 따라갈 수 있다.

  1. 1~2줄은 형식 검사를 엄격하게 하고 선언되지 않은 변수 사용을 막는다. 이 파일의 규칙을 실행 틀보다 먼저 정한다.
  2. 4~5줄은 Module Program과 Sub Main으로 프로그램의 시작 부분을 연다. Main 안의 문장은 위에서 아래로 실행된다.
  3. 6줄은 비품 이름을 String으로 저장한다. 7줄의 "3"도 큰따옴표로 감쌌으므로 숫자가 아니라 문자열이다.
  4. 8줄은 CInt(quantityText)로 문자열을 Integer로 바꾸고 quantity에 넣는다. quantityText의 형식이나 내용은 바뀌지 않는다. 변환 결과를 별도 변수에 저장한다.
  5. 9줄은 대여 기간을 정수 2로 저장한다. 10줄은 무게를 Double로 저장한다. 1.35R의 R은 리터럴의 형식을 지정한다.
  6. 11~12줄은 대여료와 할인율을 Decimal로 저장한다. 두 리터럴에 D를 붙였으므로 계산에 쓸 값이 처음부터 Decimal이다.
  7. 13줄은 대여 여부를 True로, 14줄은 대여일을 2026년 6월 15일로 지정한다. 숫자, 상태, 날짜를 서로 다른 형식으로 표현한다.
  8. 16줄은 하루 대여료에 수량과 일수를 곱한다. 별표는 곱셈 기호다. CDec로 수량과 일수를 Decimal로 바꿔 15000 × 3 × 2를 계산한다. Integer에서 Decimal로의 이 변환은 자동으로도 허용되지만, 여기서는 계산에 참여하는 형식을 드러내려고 직접 썼다.
  9. 17줄은 90,000원에 할인율 0.1을 곱해 9,000원을 구한다. 18줄은 할인 전 금액에서 할인 금액을 빼 최종 청구 금액 81,000원을 저장한다.
  10. 19줄은 수량을 표시할 문자열로 바꾼다. 계산용 quantity는 그대로 남아 있고, quantityLabel에는 "3"이 들어간다.
  11. 21~23줄은 이름, 수량, 기간을 출력한다. &는 설명 문구와 변수의 문자열 표현을 연결한다. CStr(loanDays)는 정수를 표시용 문자열로 만든다.
  12. 24~25줄은 무게를 소수 두 자리, 하루 대여료를 소수 없이 표시한다. 공통 문화권을 지정해 무게의 소수점 기호가 실행 환경에 따라 바뀌지 않도록 한다.
  13. 26줄은 Boolean을 문자열로 바꾸므로 True가 출력된다. 27줄은 Date 값을 연도-월-일 순서로 표시한다. 날짜를 저장하는 형식과 보여 주는 형식을 구분한다.
  14. 28~30줄은 세 금액을 소수 없이 출력한다. 31~32줄은 Main과 Program을 닫는다. 추가 입력을 기다리는 문장이 없으므로 출력 후 종료된다.

계산한 값을 출력문 안에서 반복해서 계산하지 않고 별도 변수에 담은 이유도 살펴본다. totalFee, discountAmount, payableFee라는 이름은 각각 할인 전 금액, 할인 금액, 청구 금액의 역할을 설명한다. 같은 숫자라도 의미를 구분해 두면 할인율이나 대여 기간을 바꿀 때 어느 부분이 영향을 받는지 파악하기 쉽다.

실행 결과

.NET 10 SDK가 설치된 macOS 또는 Linux에서 새 프로젝트를 만들려면 다음 명령을 순서대로 실행한다. SDK는 프로젝트 생성과 빌드에 필요한 개발 도구 모음이다. 폴더로 이동한 뒤 Program.vb를 완성 코드로 바꾼다.

dotnet new console -lang VB -n OfficeLoanTypes
cd OfficeLoanTypes

프로젝트 폴더에서 다음 명령으로 실행한다.

dotnet run

프로그램이 출력하는 내용은 다음과 같다. 날짜는 현재 날짜를 읽지 않고 지정한 값을 사용하며, 소수와 금액의 표시에는 공통 문화권을 지정했다. 따라서 같은 코드를 실행하면 아래와 같은 결과를 얻는다.

비품: 회의실 프로젝터
대여 수량: 3대
대여 기간: 2일
무게: 1.35kg
하루 대여료: 15000원
대여 여부: True
대여일: 2026-06-15
할인 전 금액: 90000원
할인 금액: 9000원
청구 금액: 81000원

이번 예에서는 계산에 사용한 금액에 소수 부분이 없으므로 F0 출력이 계산 결과의 일부를 숨기지 않는다. 나중에 소수 금액이 생기면 표시 형식만 바꾸는 것으로 청구 규칙을 대신하지 말고, 어떤 단위로 반올림할지 따로 정해야 한다.

실무에서 자주 틀리는 것

아래의 틀린 코드는 해당 실수를 보여 주기 위한 짧은 조각이다. 완성 코드에 그대로 추가하는 코드가 아니다. 컴파일이 막히는 실수와 실행되지만 의도와 다른 결과를 내는 실수를 함께 살펴본다.

Decimal 변수에 Double 리터럴을 넣는다

다음 문장의 0.1은 Double이다. Decimal로의 암시적 축소 변환이 필요하므로 Option Strict On에서 오류가 된다.

Dim discountRate As Decimal = 0.1

금액 계산에 쓸 십진 소수라면 리터럴에 D를 붙인다. 변환 함수를 추가하기보다 값의 출발 형식을 목적에 맞추는 방법이다.

Dim discountRate As Decimal = 0.1D

문자열 숫자를 연결해서 계산 결과라고 생각한다

아래 코드는 컴파일되지만 result는 "32"가 된다. &는 숫자 덧셈이 아니라 문자열 연결이기 때문이다. 이런 의미의 실수까지 Option Strict가 알아서 판단해 주지는 않는다.

Dim quantityText As String = "3"
Dim extraText As String = "2"
Dim result As String = quantityText & extraText

두 수량을 합하려면 먼저 숫자로 바꾸고 +로 더한다. 아래 totalQuantity의 값은 5다. 계산 결과를 담는 변수도 Integer로 정한다.

Dim quantityText As String = "3"
Dim extraText As String = "2"
Dim totalQuantity As Integer = CInt(quantityText) + CInt(extraText)

CInt가 소수 부분을 버린다고 생각한다

3.5에서 소수 부분을 버려 3을 얻으려는 의도로 다음 코드를 쓰면 실제 값은 4가 된다. CInt는 반올림한다.

Dim measuredDays As Double = 3.5R
Dim wholeDays As Integer = CInt(measuredDays)

업무 규칙이 소수 부분을 버리는 것이라면 그 의도를 먼저 적용한다. Math.Truncate는 소수 부분을 제거한 값을 반환한다. 반환 형식이 여전히 Double이므로 CInt로 Integer를 만든다. 아래 결과는 3이다. 실제 대여 기간을 올림할지 버릴지는 업무 규칙에 따라 정한다.

Dim measuredDays As Double = 3.5R
Dim wholeDays As Integer = CInt(System.Math.Truncate(measuredDays))

변수 이름의 철자를 바꿔 쓴다

다음 코드에서 quantitty는 선언된 quantity와 다른 이름이다. Option Explicit On이면 선언되지 않은 이름이라는 컴파일 오류를 확인할 수 있다.

Dim quantity As Integer = 3
quantitty = 4

원래 변수를 변경하려는 의도라면 이름을 고친다. 오류를 없애려고 비슷한 이름의 변수를 새로 선언하면 수량을 둘로 나눠 관리하게 되어 원래 목적과 달라질 수 있다.

Dim quantity As Integer = 3
quantity = 4

한눈에 보기

변수 선언부터 표시까지의 작성 규칙
목적작성 예읽는 방법
변수 선언Dim quantity As Integer = 3정수 수량을 만들고 3을 넣는다
값 변경quantity = 4기존 변수의 값을 바꾼다
형식 검사Option Strict On암시적 축소 변환 등을 제한한다
이름 검사Option Explicit On선언한 변수만 사용한다
십진 소수 지정0.1DDecimal 리터럴로 만든다
숫자로 변환CInt("3")문자열을 Integer로 바꾼다
표시용 변환CStr(quantity)수량의 문자열 표현을 만든다
글자 연결"수량: " & CStr(quantity)문구와 수량 표시를 연결한다

변수를 선언할 때는 이름, 형식, 초기값을 함께 확인한다. 계산에서는 숫자 형식을, 표시에서는 문자열 표현을 사용한다. 형 변환은 필요할 때 명시하되, 변환이 성공하는지와 값이 어떻게 달라지는지는 별도로 판단한다. Option 설정은 이런 구분을 코드에 유지하도록 돕는다.

연습 문제

  1. 완성 코드에서 대여 수량을 4대, 대여 기간을 3일, 하루 대여료를 12,000원으로 바꾼다. 할인율은 10%로 유지한다. 바꿔야 할 선언문과 할인 전 금액, 할인 금액, 청구 금액을 적는다.
  2. 노트북 이름, 보유 수량 8, 무게 1.42kg, 하루 대여료 18,000원, 대여 여부 False, 대여일 2026년 7월 2일을 각각 변수로 선언한다. 이 장에서 배운 여섯 형식을 하나씩 사용하고, 소수 리터럴의 형식 문자도 적는다.
  3. Option Strict On에서 Dim quantity As Integer = "5"가 허용되지 않는 이유를 설명하고 수정한다. 이어서 CInt(4.5R)와 CInt(5.5R)의 결과를 각각 적는다.
  4. 관리 번호 "0042"를 Integer로 바꿨다가 CStr로 다시 문자열로 만들면 어떤 결과가 되는지 적는다. 앞의 0을 유지해야 하는 관리 번호에 적합한 선언문도 작성한다.

정답과 해설

대여 조건을 바꾸고 금액을 확인한다

완성 코드의 세 선언문을 다음과 같이 바꾼다. quantity는 quantityText를 변환해 만들어지므로 수량을 바꿀 때는 문자열의 초기값을 수정한다. 할인율과 계산식은 그대로 사용한다.

Dim quantityText As String = "4"
Dim loanDays As Integer = 3
Dim dailyFee As Decimal = 12000D

할인 전 금액은 12000 × 4 × 3으로 144,000원이다. 할인 금액은 144000 × 0.1로 14,400원이며, 청구 금액은 129,600원이다. 출력 형식에 자릿수 구분 기호를 넣지 않았으므로 프로그램에는 각각 144000원, 14400원, 129600원으로 나타난다.

여섯 형식으로 노트북 정보를 선언한다

아래 선언문은 각 정보의 의미에 맞춰 형식을 지정한다. 무게는 Double, 금액은 Decimal이며, 대여 여부에는 문자열 "False"가 아니라 Boolean 값 False를 넣는다.

Dim itemName As String = "업무용 노트북"
Dim stockQuantity As Integer = 8
Dim weightKg As Double = 1.42R
Dim dailyFee As Decimal = 18000D
Dim isLoaned As Boolean = False
Dim loanDate As Date = #7/2/2026#

위 날짜 리터럴은 2026년 7월 2일을 뜻한다. 날짜를 화면에 일정하게 보여 주려면 완성 코드와 같이 ToString의 날짜 형식과 공통 문화권을 지정한다.

문자열을 명시적으로 바꾸고 반올림을 구분한다

"5"는 String이므로 Integer에 자동으로 대입하려면 암시적 변환이 필요하다. Option Strict On은 이 변환을 허용하지 않는다. CInt를 사용하면 숫자로 바꾸려는 의도를 명시할 수 있다.

Dim quantity As Integer = CInt("5")

CInt(4.5R)의 결과는 4이고 CInt(5.5R)의 결과는 6이다. 두 값 모두 정수 사이의 정확한 중간에 있으므로 가까운 짝수로 반올림한다. 변환 함수의 이름만 보고 소수 부분을 버린다고 판단하면 결과를 잘못 예상할 수 있다.

관리 번호의 앞자리 0을 보존한다

CInt("0042")의 값은 정수 42다. 이를 CStr로 바꾸면 "42"가 된다. 정수 값에는 처음에 0을 몇 개 적었는지에 대한 정보가 없으므로 문자열 변환만으로 원래 표기를 되찾을 수 없다.

Dim assetCode As String = "0042"

관리 번호는 계산할 수량이 아니라 비품을 구분하는 표기다. 따라서 String으로 유지하는 것이 이 요구에 맞다. 비품 이름과 관리 번호는 글자로, 수량과 기간은 정수로, 금액은 Decimal로 나누어 담으면 기록과 계산의 목적을 코드에서도 확인할 수 있다.

댓글 0

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

댓글을 남기려면 로그인이 필요합니다.