Lua 변수

어떤 계산을 할 때, 그 계산 결과를 기억하고 싶을 때가 있을 것이다. 이때 사용하는 것이 변수이다. 변수는 값을 저장할 수 있는 상자라고 생각할 수 있다.

변수의 타입

Lua에는 C언어처럼 변수의 타입이 존재하지만, 변수의 타입을 의식하지 않아도 되도록 설계되어 있다.

예를 들어, hoge라는 변수를 선언하면, 그 변수에는 어떤 값이라도 대입할 수 있다. 정수도 대입할 수 있고, 소수나 문자열도 대입할 수도 있다.

여기서 대입이란 변수, 즉, 상자 안에 값을 넣는 것을 말한다(이 표현은 정확하지 않지만, 지금 단계에서는 그렇게 생각해도 무방하다).

변수 만들기

이제 실제로 변수를 만들어 보자. 변수를 생성하려면 다음과 같이 한다.

hoge = 10

이는 hoge라는 이름의 변수를 만들라는 의미이다. 상자에 이름을 붙일 수 있다. 그리고 이 hoge에는 10이라는 값이 들어간다.

C언어와 달리 초기화하지 않은 변수는 만들 수 없다. 예를 들어, 다음과 같은 코드는 에러가 발생한다.

hoge --error

변수를 여러 개 선언하는 경우 다음과 같이 작성할 수도 있다.

foo = 10 bar = 20

위의 선언은 아래와 같은 의미이다.

foo = 10
bar = 20

그리고, 아래와 같은 경우도 같은 의미이다.

foo, bar = 10, 20

C 언어와 달리 변수는 어디서나 선언할 수 있다. 또한, 한 줄에 여러 개의 값을 한 줄에 재작성하는 다중 대입이 가능하다.

또한, 이 또한 중요한데, Lua의 변수는 특별한 지정이 없는 한 전역 변수가 된다. 전역 변수의 의미는 변수의 범위에서 설명한다.

변수 이름 지정 시 주의 사항

변수 이름을 지을 때 다음과 같은 규칙이 있다.

  • 시작은 영문자 또는 _(밑줄)로 시작해야 한다. 숫자는 안된다.
  • 기본적으로 같은 이름의 변수가 두 개 존재할 수 없다. 단, 변수의 범위가 다르면 같은 이름의 변수를 여러 개 만들 수 있다. 범위에 대한 설명은 생략한다.
  • 예약어는 사용할 수 없다

예약어(표 3.3)는 if, while 등 Lua 언어 문법의 일부이다.

표 3.3: 예약어 목록

and break do else
elseif end false for
function if in local
nil not or repeat
then true until while

변수에 값 대입하기

변수에 값을 대입해 보자. 예를 들어, 10이라는 값을 상자에 넣으려면 다음과 같이 한다.

hoge = 10

= 기호는 식의 오른쪽에 있는 값을 왼쪽에 대입하라는 의미이다. 수학의 등호를 의미하지 않으므로 주의해야 한다.

그렇다면, 수학에서 흔히 쓰이는 x = 10(x는 10이다)과 같이 정말 등호의 의미를 사용하고 싶을 때는 어떻게 해야 할까? 이것은 if문이라는 곳에서 자세히 설명하겠지만, 일단 간단히 설명하자면 ==라는 기호를 사용한다. 두 개의 등호를 연결하여 쓰면 수학에서 말하는 등호의 의미가 된다.

Lua에서는 다중 대입도 가능하다.

hoge, piyo = 10, 5

hoge에 10을 대입하고 piyo에 5를 대입하고 있다.

변수 값 표시하기

변수를 화면에 출력하고 싶다면 어떻게 하면 될까? 예를 들어, int 타입의 hoge라는 상자에 10이라는 값을 대입하여 상자의 내용을 화면에 표시해 보자.

hoge = 10
print(hoge)

이 프로그램을 실행하면 다음과 같이 화면에 표시될 것이다.

실행 결과:

10

여러 개의 값을 표시할 수도 있다.

hoge = 10
piyo = 20
print(hoge, piyo)

이렇게 쉼표로 구분하여 여러 값을 표시할 수 있다.

실행 결과:

10	20

또한, 문자와 숫자 등도 함께 표시할 수 있다. 문자열과 숫자, 또는 문자열과 문자열을 결합하여 표시하려면 연결 연산자 .. 를 사용한다.

Lua에는 C 언어의 printf 함수와 비슷한 것이 존재한다. 바로 string.format() 함수이다.

이 함수는 문자열의 서식을 지정하여 화면에 표시한다. 서식 지정자 목록은 표 3.2와 같다.

표 3.2: 서식 지정자

기호 의미
%d 정수를 10진수로 출력
%u 부호 없는 정수를 10진법으로 출력
%o 정수의 8진법으로 출력
%x 정수를 16진수로 출력
%f 소수점 표시
%c 1문자 출력
%% % 출력

string.format() 함수를 사용하여 숫자를 출력해 보자.

hoge = 10
print( string.format( "hoge의 10진수 값은 %d이다" ,hoge) )
print( "hoge의 16진수 값은 " ...
string.format("%x", hoge) .. "이다")

실행 결과:

hoge의 10진수 값은 10이다
hoge의 16진수 값은 a이다

이 외에도 다양한 시도를 해보자.

hoge = 10
piyo = 20
foo = 30.256

print(string.format("hoge의 값은 %d이다", hoge))
print(string.format("piyo의 값은 %d이다", piyo))
print(string.format("값은 %d이다.", 50))
print(string.format("hoge는 %d piyo는 %d이다", hoge, piyo))
print(string.format("foo의 값은 %f이다", foo))
print(string.format("hoge의 값은 %f이다", hoge))
print(string.format("foo의 값은 %d이다", math.floor(foo)))

여기서 math.floor(x) 함수는 버림 함수이다. 실행 결과:

hoge의 값은 10이다
piyo의 값은 20이다
값은 50이다.
hoge는 10 piyo는 20이다
foo의 값은 30.256000이다
hoge의 값은 10.000000이다
foo의 값은 30이다

연산

사칙연산

수학에서 익숙한 사칙연산, 즉 ‘덧셈’, ‘뺄셈’, ‘곱셈’, ‘나눗셈’을 Lua 언어에서도 할 수 있다.

표3.3: 사칙연산

기호 의미
+ 덧셈
- 뺄셈
* 곱셈
/ 나누셈

간단한 계산 예시

x = 10
y = 20
print("x + y는 " .. x + y .. "이다")
y = y - x
print("y의 값은 " .. y .. "이다")

이 프로그램의 실행 결과는 다음과 같다.

실행 결과:

x + y는 30이다
y의 값은 10이다

기타 연산

값의 부호를 반전시키려면 다음과 같이 한다.

x = 10
print("반전된 값은 " .. -x .. "이다")

실행 결과:

반전된 값은 -10이다

나눗셈의 나머지, 즉 나눗셈의 나머지를 구하려면 다음과 같이 하면 된다.

x = 10 y = 3
print("나머지는 " .. x % y .. "이다")

실행 결과:

나머지는 1이다

제곱 계산

제곱은 예를 들어 x의 2 제곱, 즉 x*x을 말한다. Lua에서 제곱을 계산하려면 2^3처럼 ^를 사용하여 표현한다. 2^3은 2의 3제곱을 의미한다.

print("2의 제곱은 " .. 2 ^ 3 .. "이다")

실행 결과:

2의 제곱은 8.0이다

동적 변수의 타입

Lua는 변수의 타입을 의식하지 않아도 된다고 설명했다. 하지만 변수의 타입은 존재한다. 표 3.7에 표시된 8가지 기본 타입이 그것이다.

표3.7: 변수의 타입

유형 의미
nil nil
boolean 논리형
number 숫자 값
string 문자열
function 함수
userdata 사용자 정의형
thread 스레드
table 테이블

nil은 아무것도 없는 값이라는 뜻으로, C 언어나 JAVA에서 말하는 null과 같은 의미이다.

boolean은 논리형, 즉 truefalse의 두 가지 값을 가지는 것이다.

number는 숫자를 담을 수 있는 것이다.

string은 문자열을 나타낸다. 다른 타입에 대해서는 현재로서는 설명하지 않는다.

Lua의 경우 변수가 타입을 가지는 것이 아니라 값이 타입을 가진다.

즉, 변수에 넣는 값에 따라 타입이 동적으로 변화하는 것이다. 이제 현재 변수가 어떤 타입인지 알아보기 위해 type() 함수를 사용하여 타입을 알아보자.

hoge = nil
print("hoge의 현재 타입은 " .. type(hoge) .. "이다")
hoge = "Hello"
print("hoge의 현재 타입은 " .. type(hoge) .. "이다")
hoge = 33
print("hoge의 현재 타입은 " .. type(hoge) .. "이다")
hoge = true
print("hoge의 현재 타입은 " .. type(hoge) .. "이다")

실행 결과:

hoge의 현재 타입은 nil이다
hoge의 현재 타입은 string이다
hoge의 현재 타입은 number이다
hoge의 현재 타입은 boolean이다

이렇게 입력하는 값에 따라 타입이 동적으로 변한다.

키보드에서 값 불러오기

키보드에서 어떤 값을 입력하여 변수에 대입하고 싶은 경우가 있을 수 있습니다. 이럴 때 사용하는 것이 io.read() 함수이다.

hoge = nil
print("문자열을 입력하세요:")
hoge = io.read()
print("입력된 문자는 " .. hoge .. "이다")

이 프로그램은 Visual Studio으로 실행 시키면, 입력이 되지 않는데, 커멘트(또는 터미널)을 켜고 아래과 같이 집접 입력하길 바란다.

실행 결과:

% lua HelloWorld.lua
문자열을 입력하세요:
devkuma
입력된 문자는 devkuma이다
% lua HelloWorld.lua
문자열을 입력하세요:
33
입력된 문자는 33이다

예제

미터를 피트로 변환하는 프로그램

미터를 피트로 변환하는 프로그램을 작성해보자. 미터에 3.2를 곱하여 피트를 구할 수 있다.

io.write("미터 값을 입력하세요:")
meter = io.read()
answer = meter * 3.2
print( meter .. "미터는" .. answer .. "피트이다.")

io.write() 함수는 print 함수와 사용법은 동일하다. 단, io.write() 함수는 문장 끝에 줄바꿈이 자동으로 추가되지 않는다.

실행 결과:

% lua HelloWorld.lua
미터 값을 입력하세요:25
25미터는80.0피트이다.

두 값을 교환하는 프로그램

변수 hoge에는 10이, piyo에는 5가 할당되어 있다. 이 두 값을 교환하라.

hoge, piyo = 10, 5
print("hoge의 값은 " .. hoge .. "이고,  piyo의 값은 " .. piyo .. "이다.")
tmp = hoge
hoge = piyo
piyo = tmp
print("hoge의 값은 " .. hoge .. "이고,  piyo의 값은 " .. piyo .. "이다.")

해결 방법은 한 가지가 아니다. 다중 대입을 사용하면 tmp 변수를 사용하지 않아도 된다.

hoge, piyo = 10, 5
print("hoge의 값은 " .. hoge .. "이고, piyo의 값은 " .. piyo .. "이다.")
hoge, piyo = piyo, hoge
print("hoge의 값은 " .. hoge .. "이고, piyo의 값은 " .. piyo .. "이다.")

실행 결과:

hoge의 값은 10 piyo의 값은 5이다.
hoge의 값은 5 piyo의 값은 10이다.

연습문제

문제1

분을 시간으로 변환하는 프로그램을 작성하시오. 예를 들어, 사용자가 180을 입력하면 3으로 표시하는 프로그램이다.

문제 2

섭씨 온도를 화씨 온도로 변환하는 프로그램을 작성하시오. 섭씨 온도(F)와 화씨 온도(C)에는 도(C)는 다음과 같은 관계가 있다.

\(F = {9 \over c}C + 32\)




최종 수정 : 2024-04-22