참고 : 값을 생성하는것과 변수를 정의하는 것을 혼동하지 맙시다. 값이라고 해서 꼭 변수와 연관 지어지는 것은 아닙니다.
writeln과 같은 함수 또한 부작용을 가지고 있으므로 표현입니다. writeln의 경우, 순작용은 문자들을 배열하여 스트림으로 출력 하는 것입니다. 우리가 이제것 제작했던 프로그램을 또 다른 예로 들자면, 변수 지정 또한 표현이 될 수 있는데, 순기능은 값을 왼쪽 변수에 지정 하는 것입니다.
값을 생성 해 낸다는 측면에서 표현은 다른 표현 안에 포함 될 수도 있습니다. 때문에 간단한 표현에서 부터 복잡한 표현을 만들어 내는 것도 가능합니다. 예를 들면 currentTemperature()라는 함수가 있고, 이 함수는 현재의 공기 온도를 도출한다고 가정합시다. 이 함수가 도출하는 값은 writeln표현에 바로 적용 될 수 있습니다:
writeln("It's ", currentTemperature(), " degrees at the moment.");
- "It' s "
- currentTemperature()
- " degrees at the moment."
- 위 세개를 이용하는 writeln 표현
더 나아가기 전에, 지정 연산자의 좌변과 우변에 촛점을 맞추어 다시 한번 더 언급 하자면: 지정 연산자(=)는 표현의 오른쪽에 있는 값을 왼쪽의 값에 할당합니다.(즉 변수에 할당)
temperature = 23 // temperature's value becomes 23
논리 표현
논리 표현은 불리언 연산에서 사용되는 표현입니다. 논리 표현은 "만약 답변이 '예' 라면 파일을 저장 하겠다" 와 같이 컴퓨터가 결정을 하도록 하는 표현입니다.논리 표현은 오로지 2가지 값만을 가집니다:false는 거짓을 나타내는 값이며, true는 참을 나타냅니다. 예를 들면, "지중해는 바다다" 라는 표현은 true가 되며, "지중해는 호수다" 라는 표현은 false가 되겠습니다.
다음 예제에서 writeln을 사용하겠습니다. 만약 줄의 맨 끝에 true가 출력된다면, 출력된 줄은 참이라는 것을 의미 합니다. 비슷하게, false가 출력되면 그 줄은 거짓이라는 의미 입니다. 예를 들면, 프로그램의 출력이 다음과 같다면,
커피가 있다: true
커피가 있다: false
논리 표현은 조건문, 루프(loop), 함수 인자 등에서 매우 광범위하게 사용됩니다. 이러한 것들이 어떻게 구동하는지 이해하는 것은 매우 중요합니다. 다행히도, 논리 표현은 설명하기도, 사용하기도 매우 쉽습니다.
논리 표현에서의 논리 연산자는 다음과 같이 표현 됩니다:
- ==연산자는 "왼쪽과 오른쪽은 같나?"라는 질문에 답을 합니다. 같으면 true를 출력하고 다르면 false를 출력합니다. 정의상, ==가 출력 하는 값 또한 논리 표현 입니다.
예를 들면 다음과 같이 2개의 변수가 있다고 가정 합시다:
int daysInWeek = 7; int monthsInYear = 12;
daysInWeek == 7 // true monthsInYear == 11 // false
- != 연산자는 "같지 않은가?" 라는 질의에 따라 양변의 표현을 비교하여 == 연산자와는 반대되는 출력을 합니다.
daysInWeek != 7 // false monthsInYear != 11 // true
||논산자를 사용하여 표현 할 수 있는 경우들과 결과들을 다음 표에서 정리하였습니다.
Left expression | Right expression | Result |
---|---|---|
거짓 | 거짓 | false |
거짓 | 참 | true |
참 | 거짓 (연산 안함) | true |
참 | 참 (연산 안함) | true |
import std.stdio; void main() { // false means "no", true means "yes" bool existsCoffee = false; bool existsTea = true; writeln("There is warm drink: ", existsCoffee || existsTea); }
- &&연산자는 영어로는 "and", 한국어로는 "그리고"를 나타내며, 양 변의 논리 표현이 모두 참일 경우에만 true를 출력합니다.
만약 왼쪽의 논리 표현이 false라면, 오른쪽 표현은 연산 하지 않고 바로 false를 출력합니다. 만약 왼쪽 표현이 true이라면 오른쪽 표현의 결과를 출력합니다.(참일 경우 true, 거짓일 경우 false)
이 연산자는 영어의 "and"와 비슷하며 한국어의 "그리고"와 비슷합니다:왼쪽, 그리고 오른쪽의 값이 모두 참일경우, true를 출력합니다.
왼쪽표현 | 오른쪽표현 | 결과 |
---|---|---|
false | false (not evaluated) | false |
false | true (not evaluated) | false |
true | false | false |
true | true | true |
writeln("I will drink coffee: ", wantToDrinkCoffee && existsCoffee);
(역자 주 : 물론 직접 만든 연산자나 연산자 오버로딩(operation overloading)으로 만든 경우에는 사용자의 마음에 달렸겠죠.)
- ^연산자는 "이것 혹은 저것?"을 나타냅니다. 이 연산자는 하나의 표현만 참일 경우 true를 출력하며, 둘 다 참일 경우 false를 출력합니다.
왼쪽표현 | 오른쪽 표현 | 결과 |
---|---|---|
false | false | false |
false | true | true |
true | false | true |
true | true | false |
writeln("I will play chess: ", jimShowedUp ^ bobShowedUp);
- <연산자는 "오른쪽보다 작은가?"(혹은 "순서상에서 먼저 나오는가?")를 나타냅니다.
writeln("We beat: ", theirScore < ourScore);
- >연산자는 "오른쪽보다 큰가?"(혹은 "순서상으로 나중에 나오는가?")를 나타냅니다.
writeln("They beat: ", theirScore > ourScore);
- <=연산자는 "오른쪽보다 작거나 같은가?"(혹은 "오른쪽과 순서가 같거나 먼저 나오는가?")를 나타냅니다. >연산자와 정 반대입니다.
writeln("We were not beaten: ", theirScore <= ourScore);
- >=연산자는 "오른쪽보다 크거나 같은가?"(혹은 "오른쪽과 순서가 같거나 나중에 나오는가?")를 나타냅니다. <연산자의 정 반대입니다.
writeln("We did not beat: ", theirScore >= ourScore);
- !연산자는 "오른쪽의 반대의"라는 의미입니다. 다른 논리연산자들과는 다르게, 오직 하나의 표현만을 받으며, 만약 그 표현이 false라면 true를, false라면 true를 출력합니다.
writeln("I will walk: ", !existsBicycle);
그룹 표현(Grouping expressions)
표현들을 연산하는 순서는 괄호로 묶어서 정리 할 수 있습니다. 여러 표현들 중에서 괄호로 묶여 있는 표현이 존재 한다면, 괄호로 묶여 있는 표현들을 먼저 연산합니다. 예를 들면, 만약 커피나 차가 있다면, 그리고 쿠키랑 빵이 있다면;그럼 행복하겠네" 라는 문장은 다음과 같이 코드로 변환 할 수 있습니다:
writeln("I am happy: ",
(existsCoffee || existsTea) && (existsCookie || existsScone));
writeln("I am happy: ",
existsCoffee || existsTea && existsCookie || existsScone);
writeln("I am happy: ",
existsCoffee || (existsTea && existsCookie) || existsScone);
논리 입력 읽기
위에서 사용한 모든 논리값들은 자동적으로 "false" 혹은 "true"로 출력됩니다. 하지만 그 반대는 되지 않습니다: 문자열 "false" 혹은 "true"는 자동적으로 bool 타입의 "false"나 "true"로 변경되지 않습니다. 그렇기 때문에, 입력을 먼저 문자열로 입력 받은 뒤에 bool 타입으로 변경되어야 합니다.
아래의 연습문제들중 하나는 "false" 혹은 "true"를 표준입력으로 받아야 하는 프로그램을 만들어야 하는데, 아직 설명하지 않은 내용을 사용하였습니다. 입력을 bool 값으로 변경하는 함수를 제작하였습니다. std.conv의 to를 호출하였습니다.(만약 잘못된 값을 넣으면 ConvException 에러가 출력됩니다.)
적어도 main 함수에 있는 내용들은 이해하였으면 좋겠습니다. read_bool() 은 아직 배우지 않는 내용을 다루고 있기에, 설명을 첨부 하였지만 지금은 무시 하셔도 좋습니다. 그래도 컴파일하려면 필요한 부분이기에 코드에 첨부 하셔야 합니다.
연습문제
- 위에서 설명 하였듯이, <랑 > 는 하나의 값이 다른 값보다 큰지 작은지 결정하는 연산자 입니다; 하지만 "중간값인가?" 라는, 어떤 값이 다른 두 값 사이에 있는지 결정하는 연산자는 없습니다.
value라는 값이 10과 20 사이에 있는지 결정하는 프로그램을 만들었다고 가정 합시다. 하지만 아래의 코드는 컴파일이 되지 않습니다:
import std.stdio; void main() { int value = 15; writeln("Is between: ", 10 < value < 20); // ← compilation ERROR }
괄호를 넣어 봤지만:
writeln("Is between: ", (10 < value < 20)); // ← compilation ERROR
그래도 컴파일 되지 않습니다.
해결법을 찾던 도중, 다음과 같은 괄호 사용법이 컴파일이 되도록 하다는 것을 알아 냈습니다:
해결법을 찾던 도중, 다음과 같은 괄호 사용법이 컴파일이 되도록 하다는 것을 알아 냈습니다:
writeln("Is between: ", (10 < value) < 20); // ← compiles but WRONG
이제 프로그램은 의도 했던대로 "true"를 출력합니다. 하지만 안타깝게도 답은 틀렸습니다. 프로그램에 버그가 있군요. 이 버그를 확인 하기 위해 15를 20보다 큰 값으로 바꿔서 컴파일 해봅시다:
int value = 21;
- 다음과 같은 조건을 만족한다면 해변에 간다고 가정합시다:
- 거리가 10 이하면 모두 자전거를 타고 해변에 갑니다.
- 인원이 6명 미만이고, 차가 있고, 운전면허가 있다면 해변에 갑니다.
아래 프로그램은 항상 "true"를 출력합니다. 위의 조건들이 만족하는 경우에만 "true"를 표현하도록 고쳐 봅시다.(프로그램을 실행했을때, "false"혹은 "true"를 받는 질문은 항상 "입니까?"로 끝나야 합니다.). read_bool()를 포함해야 한다는것을 잊지 맙시다:
21은 20보다 크지만 "true"를 출력 하는군요.
힌트: 논리 표현의 타입은 bool 입니다. bool 값이 20보다 작은지 큰지 결정하는것은 의미가 없습니다.
논리 표현에서 "중간값인가" 라는 표현은 "하한값보다 큰가?. 그리고 상한값보다 작은가?" 라고 바꿔야 합니다.
표현을 위의 논리에 따라 변경하고 컴파일을 해서 "true"를 나타내는지 확인 해 봅시다. 추가로, 다른 값을 넣었을때도 잘 작동하는지 확인 해 봅시다: 예를 들면 value를 50이나 1로 바꾸어 봅시다. 그렇다면 "false"가 출력 되어야 하겠죠. 12를 넣는다면 "true"'를 출력해야 합니다.
힌트: 논리 표현의 타입은 bool 입니다. bool 값이 20보다 작은지 큰지 결정하는것은 의미가 없습니다.
논리 표현에서 "중간값인가" 라는 표현은 "하한값보다 큰가?. 그리고 상한값보다 작은가?" 라고 바꿔야 합니다.
표현을 위의 논리에 따라 변경하고 컴파일을 해서 "true"를 나타내는지 확인 해 봅시다. 추가로, 다른 값을 넣었을때도 잘 작동하는지 확인 해 봅시다: 예를 들면 value를 50이나 1로 바꾸어 봅시다. 그렇다면 "false"가 출력 되어야 하겠죠. 12를 넣는다면 "true"'를 출력해야 합니다.
import std.stdio; import std.conv; import std.string; void main() { write("How many are we? "); int personCount; readf(" %s", &personCount); write("How many bicycles are there? "); int bicycleCount; readf(" %s", &bicycleCount); write("What is the distance to the beach? "); int distance; readf(" %s", &distance); bool existsCar = read_bool("Is there a car? "); bool existsLicense = read_bool("Is there a driver license? "); /* Replace the 'true' below with a logical expression that produces the value 'true' when one of the conditions listed in the question is satisfied: */ writeln("We are going to the beach: ", true); } /* Please note that this function includes features that will be explained in later chapters. */ bool read_bool(string message) { // Print the message write(message, "(false or true) "); // Read the line as a string string input; while (input.length == 0) { input = chomp(readln()); } // Produce a 'bool' value from that string bool result = to!bool(input); // Return the result to the caller return result; }
여러가지 값들을 넣어보고 의도했던대로 동작하는지 확인 해 봅시다.
No comments:
Post a Comment