티스토리 뷰
변수의 수명 관리
이번에는 리습 생성 시 사용되는 변수를 임시로 만들 것인지 영구 변수로 사용할 것인지에 대해 알아보자.
1. 변수저장에 대해서 알아보자.
캐드 명령 창에서 아래와 같이 입력해 보자.
(setq a 1)
이렇게 입력하게 되면 a=1 값을 가지고 기억하고 있다.
a값이 얼마인지 알아보려면 캐드 텍스트 창에서
!a 라고 쳐보자.
그러면 '1' 이라는 답이 텍스트 창에 보일 것이다.
몇 가지 더해보자.
<예제1>
(setq b "TEST STRING")
!b; b값을 보여줘라.
<예제2>
(setq c (ssget)); 캐드 화면에서 성분을 선택한다.
!c; c값을 보여준다.
2. 리습에서의 변수 기억
(defun c:test1(/ e f g)
(setq e 1 f 2 g 3)
)
위의 test 1 뒤의 (/ e f g) 에서 e f g 는 각각 변수 이름이고
'/'기호는 임시변수라는 뜻이다.
'/ e f g'를 지금까지는 생략하고 강의했다.
생략하게 되면 영구변수로 자리 잡아 캐드를 종료하기 전까지는
그 변수값을 기억하게 되나 (/ e f g)같이 변수명을 다 써주면
리습이 종료됨과 동시에 변숫값은 지워진다.
위의 리습을 실행시킨후
각각 !e, !f, !g라고 캐드 텍스트 창에 타이핑해보면 결괏값이 각각 nil 일 것이다.
아래의 두가지 예를 비교하겠다.
(setq c:test2(/ tt) (setq tt 45) ) ;..........예제1
(setq c:test3() (setq rr 35) ) ;..........에제2
예제1은 리습을 실행하고 나면 tt 값이 nil 이 된다.
예제2는 리습을 실행하고 나서도 rr 값을 35로 유지한다.
3. 정리
리습을 완성하기 전까지는 영구 변수로 사용하여 중간중간 변숫값이나 에러 부분을 체크하는 것이 좋으며
리습이 완성되면 임시변수값으로 변경하여 혹시 있을 리습의 변수 충돌을 방지하고
메모리 확보 차원에서도 임시변수값으로 변경하는 것이 좋다.
영구 변수로 만들어 주면 메모리를 그 만큼 차지하기 때문이다.
하지만 상호 변수값을 참조할 경우에는 어쩔 수 없이 영구 변수를 활용해야 해야 한다.
문자의 처리
(ascii <문자>) <문자>의 ASCII 문자 CODE를 반환한다.
(chr <정수>) <정수>를 해당 ASCII문자를 반환한다.
(atof <문자>) <문자>를 실수로 변환한다.
(atoi <문자>) <문자>을 정수로 변환한다.
(itoa <정수>) 정수를 문자로 변환한다.
(rtos <숫자>[<모드> <소숫자리>]) 숫자를 문자로 변환한다.
(strcase <문자> [<t>]) <string>을 대문자 또는 소문자로 변환한다.
(strcat <문자1> <문자2> ...) 나열된 <문자1>, <문자2> ...를 연결한다.
(strlen <문자>) <문자>의 글자수를 반환한다.
(substr <문자> <시작위치> [<길이>]) <문자>를 <시작위치>부터 <길이>의 문자를 반환한다.
(ascii 문자) 와 (chr 정수)
'ascii' 란 무엇인가?
'ascii' 는 "!,@,#...a,b,c...A,B,C" 등과 같은 문자 또는 특수문자의
고유한 번호이다. 컴퓨터는 문자로 인식하지 않고 이 고유의 번호로
처리하므로 ascii code 를 알아두면 편리하게 사용될 수 있다.
(chr 정수)와 상반되는 개념이다.
(ascii "A") 라고 캐드 명령 창에 타이핑해보자.
97 이란 답이 나올것이다.
"A"의 ascii code 값은 97번이다.
(chr 97) 이라고 캐드 명령 창에 타이핑해보자.
"A" 라고 답이 나올 것이다.
즉 (ascii "A") -> 97 , (chr 97) -> "A" 서로 상반되는 내용이다.
-. 예제
왜 이런 명령이 필요한지 예제를 통해 알아보자.
한 글자를 입력받아서 숫자인지 확인하여 숫자이면 숫자를 문자이면 "Not Number"라는 메시지를 출력해보자.
(입력 메시지에 꼭 한 글자만 치고 엔터를 해야 한다.)
(defun c:test1(/ number)
(Setq number (getstring "Input String : "))
(if (and (>= (ascii number) 48) (<= (ascii number) 57))
(progn
(prompt "\nO.K. Number = ")
(prompt number)
)
(prompt "Not Number")
)
(princ))
숫자의 ascii code 는 48~57 사이이다. 이 사이를 벗어나면 문자로 판단하는 것이다.
ascii code를 사용하면 소문자를 대문자로 아니면 대문자를 소문자로 변환한다던가 첫 자가 대문자로 하고 나머지는 소문자로... 이런 것들의 처리가 가능해진다.
(atof)
이 함수는 숫자로 구성된 문자를 실수로 변환하는 함수다.
그 예제를 보자.
리습을 만들기 전에 캐드 명령 창에서 아래를 따라해 보자.
(atof "123.456")
그 결과값은 123.456 이다.
(defun c:test1(/ var1 var2)
(setq var1 "100.234"); var1 은 "100.234"인 문자이다.
(setq var2 (atof var1)); var2 는 연산이 가능한 숫자 100.234 이다.
)
(atoi)
이 함수는 숫자로 구성된 문자를 무조건 정수로 바꾸는 함수다.
소수점 이하는 반올림되지 않고 그냥 버림이 되는 걸 유의하자..
(atoi "123.987")
이 결과값은 123이다. 버림이 된다는 것을 주의
(itoa)
이 함수는 정수를 문자로 바꾸는 함수다. (atoi)와 상반되는 함수다
(itoa 123)
이 결과값은 "123"인 문자 값이다.
(rtos)
이 함수는 숫자를 문자로 변환하여 주는 함수이다.
(itoa)는 정수만을 문자로 변환하여 주지만, 이 함수는 실수 형태로 다양하게 변환하여 준다.
(rtos <숫자> <모드> <소숫점자리>)
<모드>는 아래와 같이 5가지를 적용할 수 있다.
1 Scientific
2 Decimal
3 Engineering (feet and decimal inches)
4 Architectural (feet and fractional inches)
5 Fractional
우리는 십진수에 익숙하기 때문에 2번(decimal)을 주로 사용한다.
(rots 24.4568 2 3) 라고 타이핑해보자.
그러면 결과값은 "24.457"인 문자 값으로 반올림되어 표시된다.
아래에 소수점 자리수를 바꾸어 가면서 예제를 더 보여주겠다.
(rtos 12.345678)
결과값 : "12.3456" (사용자에 따라 다름)
-> 현재 설정되어 있는 units에 따라 표시
(rtos 12.345678 2)
결과값 : "12.3456" (사용자에 따라 다름)
-> 십진수(Decimal)로 표현하고 소수점은 units에서 설정한 값을 따라감
(rtos 12.345678 2 0)
결과값 : "12"
-> 소수점 이하 표시 안 함
(rtos 12.345678 2 1)
결과값 : "12.3"
-> 소수점 이하 첫째짜리 까지 표시
(rtos 12.345678 2 2)
결과값 : "12.35"
-> 소수점 이하 둘째짜리까지 표시
(rtos 12.345678 2 3)
결과값 : "12.346"
-> 소수점 이하 셋째짜리 까지 표시
!주의사항!
dim 명령중에 dimzin 이 있다. 만약 이것이 8로 되어 있다면
소수점 이하의 결괏값이 0 이면 소수점 이하 자릿수는 표시되지 않는다.
원하는 소숫점 자릿수를 표시하고 싶다면
(setvar "dimzin" 0)
이것을 꼭 리습 앞쪽에 기재해야 한다.
(strcase)
문자를 대문자로 또는 소문자로 바꾸어 줍니다.
(strcase "teST")결과값 : TEST
(strcase "teST" T)결과값 : test
뒤의 옵션인 T를 써주면 소문자로 없으면 대문자로 해줍니다.
(defun c:test1(/ a b)
(setq a "TesdfER")
(setq b (strcase a))
) ;b= tesdfer
(strcat)
문자를 서로 붙여줍니다.
!주의사항으로는 숫자와 문자를 붙이려면 에러가 납니다.
숫자의 형태는 꼭 문자형태로 (rtos)등으로 변환해 사용해야 합니다.
(defun c:test2(/ a b c d e)
(setq a "I am")
(setq b "a boy")
(setq c 1054235);c 값은 숫자인 형태
(setq d (rtos c 2 0)) ;숫자를 문자로 변환
(setq e (strcat a b d)) ;a+b+d로 합침
)
위의 e값은 "I am a boy 1054235"이다.
(strcat <문자1> <문자2> ....)의 <문자1> <문자2> 등과 같이
문자의 갯수는 상관없이 붙여준다.
(strlen)
문자의 갯수를 [정수]로 반환한다.
(strlen "asdfg")
결괏값은 5이다. 글자 수가 5개이기 때문이다.
이 함수의 적용 예를 보자.
(defun c:test3(/ str n c)
(setq str (getstring "Input String : ")) ; 문자를 입력받는다.
(setq n (strlen str)) ; 문자수를 n으로 정의
(repeat n; 문자의 갯수만큼 * 표시
(prompt "*")
)
(prompt "\nstring length = ")
(princ n); 화면에 문자의 갯수 표시
(princ) ; 이 표시를 안해주면 갯수가 두번 찍힐 것이다.
)
(substr <문자> <시작위치> [<길이>])
<문자>를 <시작위치>부터 <길이>의 문자를 반환한다.
1. 예제
(substr "I am a boy" 3 2)
이렇게 타이핑 해보자..
결괏값은 "am"이다..
위에서 3번째 글자부터 2글자를 취하라는 뜻이므로
"am"이 결과값이 된다. 빈칸도 한자로 처리함을 주의하자.
(substr "I am a boy 6 4) 결괏값은 "a bo"
!주의사항!
<시작 위치>와 <길이>를 더한 값이 <문자>의 길이를 초과하면 에러가 난다.
(substr "I am a boy" 11 3)
문자의 길이는 10자인데 시작 위치가 11이므로 문자길이 10보다 크므로 에러다.
(substr "I am a boy" 8 5)
시작위치 8부터 5자가 넘지 않기 때문에 에러다.
8번째 글자는 "b"인데 3자인 "boy"만 존재하고 4번째, 5번째 글자는 없으므로 에러가 난다.
위와 같이 문자를 보면서 하면 에러가 보이지만 문자 대신 변수를 사용하다 보면 어떤 경우에는 버그가 생기기 마련이다.
아래와 같이 에러에 대처할 코드를 구현해놓는 것이 좋은 프로그램이다.
3번째 글자부터 5개의 문자를 취하는 리습에 선택한 글자가 없으면 "not string"를 표시한다.
(defun c:test1(/ str len a b c)
(setq str (getstring "\nInput String : ") ;문자를 입력받는다.
len (strlen str);문자의 길이
a 3 ;시작위치
b 5 ;취할 문자의 길이
)
(if (< len (+ a b)) (prompt "not string"); 취할 문자길이를 비교
(setq c (substr str a b))
) (princ)
)
시스템 변수
(getvar <시스템 변수>)
(setvar <시스템 변수> <변수값>)
<시스템변수> 값을 얻어오거나 변경할 때 사용합니다.
1. (getvar)
시스템 변숫값을 얻어올 때 사용합니다.
(1) 캐드 명령 창에 setvar를 타이핑해보자
(2) ? 타이핑
(3) * 타이핑
위에처럼 타이핑해보면 현재의 시스템 변숫값을 볼 수 있다.
그중에서 어느 한 부분 값을 알아볼 때 사용하는 명령이다.
<예제>
(getvar "acadver") ;캐드의 버전을 얻어오는 리습
(getvar "osmode");현재의 osnap 설정값을 가져오는 리습
2. (setvar)
시스템 변숫값을 변경할 때 사용한다.
시스템 변숫값이 <읽기 전용>이 아닌 경우 모든 변숫값을 변경할 수 있습니다.
<예제>
(setvar "osmode" 0) ;현재의 osnap 설정을 모두 해제한다.
(setvar "dimzin" 8) ;소수점 이하의 0의 표현은 삭제한다.
(setvar "dimzin" 0) ;소수점 이하의 0의 표현을 모두 한다