[C&Go프로그래밍 입문] #2. 구구단 프로그램

반복작업은 반복문으로

by 지은 x NULL

이번 시간에 알아볼 내용은 반복문입니다.


<학습목표>

- 같은 내용을 반복해서 출력시킬 수 있다.

- C&Go로 구구단 프로그램을 작성할 수 있다.

+ 원하는 단수까지 확장할 수 있다.


<레벨>

- 난이도 : 하 / ★ / 1점

- 중요도 : 최상

- 학습소요시간 : 30분~2시간


<기타 정보>

- 선수강의 : 안녕, 세계 (코딩환경 준비 外)

- 배워볼 개념 : 반복 패턴 확인 및 코드로 대체


<키워드>

- for문(반복문)

- 줄바꿈, 개행, new line(\n)





제가 생각하는 프로그래밍의 백미는 뭐니뭐니해도 반복의 제거입니다. a.k.a 자동화(automation)

반복되는 작업 중 가장 흔하면서 쉬운 예제인 구구단을 출력해주는 프로그램을 만들어보겠습니다.


그 전에,

구구단을 손으로 한번 적어보세요.
2단만 써도 50글자이고
2단부터 9단까지 모두 적으면 대략 450글자 이상입니다.

이걸 어떻게 대신할 수 있는지 알아보죠.

우선 제일 쉬운 2단부터 해보겠습니다.


<여기서 잠깐>
소프트웨어 세계에서는
문제를 해결하기 위해 하나의 정답만 있는 것은 아닙니다.
최적화, 최적해(optimal) 등이 있을 수 있지만
프로그래머가 아닌, 문제해결 '도구'를 배우려는 사람들에게는 아직 필요치 않은 부분입니다.
원하는 결과를 얻을 수 있는 다양한 접근을 제시할 요량이니, 그 중 편한 것을 택해 사용하면 되겠습니다.




Approach 1


안녕, 세계편을 익히셨다면 지금 당장 여러분도 할 수 있는 가장 쉬운 방법입니다.

그냥 한줄한줄 정성스레 print 해주면 돼요.


※ 처음에만 캔버스라고 할 수 있는 기본 코드를 포함하여 전체를 게시합니다.

이후부터는 해당 코드는 유지한 채로 볼드로 표시한 부분만 바꿔주세요.


#include <stdio.h>

int main()

{

printf("2 x 1 = 2");

printf("\n");
printf("2 x 2 = 4");
printf("\n");
printf("2 x 3 = 6");
printf("\n");
printf("2 x 4 = 8");

printf("\n");
printf("2 x 5 = 10");
printf("\n");
printf("2 x 6 = 12");
printf("\n");
//(중략)

printf("2 x 9 = 18");
return 0;

}




package main

import (

"fmt"

)

func main() {

fmt.Printf("2 x 1 = 2")

fmt.Printf("\n")
fmt.Printf("2 x 2 = 4")
fmt.Printf("\n")
fmt.Printf("2 x 3 = 6")
fmt.Printf("\n")
fmt.Printf("2 x 4 = 8")

fmt.Printf("\n")
fmt.Printf("2 x 5 = 10")
fmt.Printf("\n")
fmt.Printf("2 x 6 = 12")
fmt.Printf("\n")
//(중략)

fmt.Printf("2 x 9 = 18")

}


완성됐습니다.

실행을 해보면 가지런히 출력이 됩니다.

2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10
2 x 6 = 12
2 x 7 = 14
2 x 8 = 16
2 x 9 = 18

결과를 얻긴 했는데 이건 좀 아닌 것 같죠?

저도 여러분의 이해를 돕기 위해 타이핑을 하면서도 이럴려고 코딩을 하나 자괴감이 들고 괴로...워서 당장 고쳐봐야겠습니다.


좀 더 쉽게요.




Approach 2


코드를 보면 반복되는 부분이 눈에 들어오기 시작할 겁니다.

저걸 없앨 수 있을까요?


printf("2 x 1 = 2\n2 x 2 = 4\n2 x 3 = 6\n2 x 4 = 8\n2 x 5 = 10\n2 x 6 = 12\n2 x 7 = 14\n2 x 8 = 16\n2 x 9 = 18\n");




fmt.Printf("2 x 1 = 2\n2 x 2 = 4\n2 x 3 = 6\n2 x 4 = 8\n2 x 5 = 10\n2 x 6 = 12\n2 x 7 = 14\n2 x 8 = 16\n2 x 9 = 18\n")


네, 가능합니다.

이제 딱 한 줄이면 됩니다! (만세!)


하지만 여전히 직접 쓰는 게 편해보이죠.

직접 타이핑 하면 printf, 괄호, 따옴표 같은 거 안 써도 되니까요.




Approach 3


반복되는 print 명령을 한 번만 써서 코드를 비약적으로 줄였지만

구구단 자체에 여전히 반복되는 패턴이 있고 뭔가 일정한 변화를 함축시킬 수 있어 보입니다.


여러분도 '반복'을 찾으셨나요?


.

.

.


2단이니까 "2 x ? = ?\n"처럼 곱할 숫자와 결과값 말고는 항상 똑같네요.

바로 적용해봅시다.


for(int j=1; j<10; j++){

printf("2 x %d = %d\n", 2*j);

}




for j := 1; j < 10; j++ {

fmt.Printf("2 x %d = %d\n", 2*j)

}



갑자기 엄청난 것들이 쏟아져 나왔습니다.

(괜찮아요? 많이 놀랬죠?)

지난 시간까지 "Hi"만 했다가
"How are you?
I'm fine, thank you.
And you?"

세 마디를 한 셈인데요.

*어렵지만 쉬운 거(?)라는 말을 하고 싶었습니다.


코드가 단 세 줄로, 엄청나게 짧아졌습니다.

※ 각 부분별로 어떤 역할을 하는지 굳이 설명드리지 않아도 어느정도 파악이 되실 텐데요,
예상이 맞는지 확인하시려면 직접 숫자나 부등호(<>) 등을 바꿔보면서 실행해보시는 걸 추천드립니다.
'이 부분을 고치면 이렇게 되겠구나'라는 감을 잡는 것이 회화부터 시작하는 프로그래밍의 포인트입니다.

공백을 포함하느냐 안 하느냐에 따라 60~80바이트(Byte)쯤 되네요.


어라? 2단 전체가 50글자쯤 된다고 했는데 60바이트가 넘는다니요.(*영문/숫자는 한 개당 1B를 차지합니다.)

손으로 쓰는 게(타이핑 하는 게) 더 빠르겠다 싶겠죠.


네, 맞습니다. 이정도 반복이라면 굳이 코딩하실 필요가 없습니다.


- 강좌 끝 -





...이 아니고,

구구단이 2단만 있어서는 안 되겠죠.


우리가 흔히 쓰는 2~9단까지 모두 출력해보겠습니다.

아무리 문법 말고 회화라지만 갑작스레 진도가 너무 나가는 것 같아 중간다리가 되어줄 코드를 하나 더 추가합니다.




Approach 3'


아직 익숙지 않아서 전체 그림이 안 그려지실까봐 캔버스를 포함한 코드 전체를 다시 가져와봤습니다.

위 코드에서 달라진 부분은 단수 2의 역할을 하는 i가 추가되었다는 점이죠.



#include <stdio.h>

int main()

{

int i=2;

for(int j=1; j<10; j++){

printf("%d x %d = %d\n", i, j, i*j);

}

return 0;

}




package main

import (

"fmt"

)

func main() {

i := 2

for j := 1; j < 10; j++ {

fmt.Printf("%d x %d = %d\n", i, j, i*j)

}

}


각 부분이 무슨 역할을 하는지 감이 안 잡히거나 그밖에 더 궁금한 부분이 있다면,

질문/댓글은 언제든 환영입니다 :)


무리 없이 따라오실 수 있으실 거예요.




Approach 4


자, 다 왔습니다.


for(int i=2; i<10; i++){

for(int j=1; j<10; j++){

printf("%d x %d = %d\n", i, j, i*j);

}

}




for i := 2; i < 10; i++ {

for j := 1; j < 10; j++ {

fmt.Printf("%d x %d = %d\n", i, j, i*j)

}

}



실행 결과창(C언어)

이번에는 그렇게 놀라지는 않으셨을 거라고 믿습니다.

3'에서 딱 한 줄을 수정했고, 마지막 닫는 괄호(})를 하나 추가했을 뿐이니까요.


2단의 두 배도 안 되는 코드로 9단까지 완성했습니다.

글자 수는 굳이 안 세어봐도 되겠죠?

*아홉 번이 아닌, 수십, 수백 번을 반복하는 작업이라면 더더더욱 효과적이겠죠.




Tip
적은 글자로 코딩을 완성하는 게 목표인 분야(?)도 있습니다. 타수를 줄이는 게임에서 착안, 코드 골프라고 부르는데요, 단순히 재미만은 아니고 메모리(저장공간)가 극히 적은 임베디드 시스템에 실제 유용하기도 하고, 코드 난독화 기법으로 쓰이기도 합니다.







해설
한줄씩 살펴보자.
반복을 시켜주는 "for문"이다.
for(초기식;조건식;증감식)형태로 이루어지며,
풀어 쓰면,
1. 초기식 : i는 1이다.
2. 조건식 : i가 10보다 작으면(if 1 less than 10)
3. 코드를 실행=지난 시간에 안녕 세계!를 외쳤던 그 방법으로 구구단 한줄을 출력한다.
3'. 크면 6번으로 간다.
4. 증감식 : i에 1을 더한다.
5. 2번으로 간다.
6. 종료

원하는 결과를 얻기 위해 어느 부분을 고치면 될지 감이 오는가?
(안 오면 안 되는데...)
마치 패턴을 통해 회화를 익히듯이 문법을 눈에 익히도록 하자.
'초기식'이 무엇이고 '증감'이 어떻고 일일이 외울 필요가 없다.
(노파심에 강조하지만 여러분은 이 강좌를 통해 개발자가 되려는 것이 아니다!)
저 패턴과 흐름 속에서 숫자나 문자처럼 필요한 부분을 고쳐서 원하는 결과를 얻으면 된다.


<연습문제>

단 구분 없이 줄줄이 이어지다보니 보기가 힘들다. 각 단의 시작부분에 제목을 추가해보자. (예: "[2단]")

인도에서는 20단이 기본이라고 한다. 구구단을 1단부터 20단까지 출력해보자.
※ 힌트 : 최종 코드에서 세 군데만 고치면 된다.





연습문제까지 아주 쉽게 성공했다면,
이쯤되면 프로그래밍에 한걸음 더 다가간 것입니다.

시작이 반이라고 했으니 반은 한 거죠.


sticker sticker


다음 차시 예고입니다.

- 별(*)그림 그리기




keyword