Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 31d7b8c

Browse files
committed
✏ 부족한 설명 보완
1 parent 137b529 commit 31d7b8c

File tree

1 file changed

+36
-9
lines changed

1 file changed

+36
-9
lines changed

‎8-functions/README.md

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,32 @@
66

77
지금까지는 컴퓨터가 단순히 메모리와 연산장치가 있다고만 생각했었는데요, 사실 연산장치에도 계산하고 있는 값을 임시로 저장하기 위한 메모리가 하나 더 있습니다. 지금까지 우리가 다룬 주소값이 있는 메모리는 흔히 램이라고 부르는 `임의 접근 메모리(Random-access memory; RAM)`이고, 연산장치에 있는 계산 중인 값을 저장하기 위한 메모리는 `레지스터(register)`입니다.
88

9+
덧셈, 뺄셈 같은 산술 연산이든, 논리곱, 논리합 같은 논리 연산이든, 연산장치가 값을 계산하기 위해선 피연산자들이 반드시 레지스터에 들어있어야 합니다. 연산장치가 RAM 안의 공간에 대해서 할 수 있는 연산은 불러오기와 저장하기 밖에 없습니다. 다음 예시를 봐주세요.
10+
11+
```c
12+
int main()
13+
{
14+
int a = 2, b = 5;
15+
int c = a + b;
16+
}
17+
```
18+
이런 코드를 지금까지는
19+
```
20+
프로그램이 시작했을 때,
21+
1. 적절한 공간을 a와 b라고 이름짓고 2와 5을 집어넣습니다.
22+
2. 적절한 공간을 c라고 이름짓고 a와 b에 들어있는 값의 합을 집어넣습니다.
23+
```
24+
이렇게 분석했지만, 실제 컴파일 결과는
25+
```
26+
프로그램이 시작했을 때,
27+
1. 적절한 공간을 a와 b라고 이름짓고 2와 5을 집어넣습니다.
28+
2. 레지스터 ecx에 b의 값을 불러옵니다.
29+
3. 레지스터 eax에 a의 값을 불러옵니다.
30+
4. eax에 ecx와 eax에 들어있는 값의 합을 집어넣습니다.
31+
5. 적절한 공간을 c라고 이름짓고 eax에 들어있는 값을 집어넣습니다.
32+
```
33+
이렇게 된다는 것입니다.
34+
935
연산장치 입장에서 레지스터는 RAM보다 가까운 곳에 있기 때문에 더 쉽고 빠르게 접근할 수 있습니다. 그래서 자주 변하는 값은 레지스터에 저장하는 것이 좋습니다. 프로그래머가 C 코드를 통해 변수를 생성하게 되면, 컴파일러는 자체적인 판단에 따라 그 변수를 RAM 또는 레지스터에 고정시킵니다. 그 변수에 주소 연산자를 사용한 경우가 있으면 RAM에 고정시켜야겠지만, 그런 경우가 없으면 레지스터에 고정시켜도 괜찮을 것입니다.
1036

1137
레지스터들은 계산 중인 값을 저장하는 것 말고도 여러가지 목적을 위해 사용됩니다. 그래서 연산장치를 만드는 회사들은 레지스터들을 목적에 맞게 분류하고, 그 분류에 따라 연산장치의 알맞은 곳에 레지스터를 배치해놓습니다. 컴파일러를 만드는 회사들은 이런 분류에 맞추어 변수가 알맞은 레지스터에 고정되도록 합니다.
@@ -24,16 +50,17 @@ int main()
2450
}
2551
```
2652

27-
여기서 `i` 같은 변수를 `루프 카운터(loop counter)`라고 부르는데요, 레지스터에 고정되는 예시 중 하나입니다. `i``ebx`라는 레지스터에 고정되고, `d`가 800\~804를 차지한다고 가정했을 때, 위 코드를 해석해보면,
53+
여기서 `i` 같은 변수를 `루프 카운터(loop counter)`라고 부르는데요, 레지스터에 고정되는 예시 중 하나입니다. `d`가 800\~804를 차지한다고 가정했을 때, 위 코드를 해석해보면,
2854

2955
```
3056
1. 800번을 d라고 이름짓습니다.
3157
2. 사용자의 입력을 받아 d가 차지하고 있는 공간에 정수를 넣습니다.
32-
3. ebx에 0을 집어넣습니다.
33-
4. ebx가 d에 들어있는 값보다 작으면 5로 이동하고, 아니면 for문을 종료합니다.
34-
5. ebx에 들어있는 값을 출력합니다.
35-
6. ebx에 들어있는 값을 1 증가시킵니다.
36-
7. 4로 이동합니다.
58+
3. 레지스터 ebx에 0을 집어넣습니다.
59+
4. 레지스터 ecx에 d의 값을 집어넣습니다.
60+
5. ebx < ecx의 결과가 1이면 6로 이동하고, 아니면 for문을 종료합니다.
61+
6. ebx에 들어있는 값을 출력합니다.
62+
7. ebx에 들어있는 값을 1 증가시킵니다.
63+
8. 5로 이동합니다.
3764
```
3865

3966
이렇게 해석될 수 있습니다.
@@ -131,7 +158,7 @@ goto <레이블 이름>;
131158

132159
선언문을 제외한 임의의 문장에 레이블로 이름을 달 수 있는 것을 알 수 있습니다.
133160

134-
> 사실 `선언문(declaration)``문장(statement)` 아니지만, 선언문을 문장으로 보면 이해하기 더 쉬운 경우가 있기 때문에(`int main { ... }`안에는 항상 문장만 들어간다고 생각할 수 있는 등) 둘을 혼용해서 설명했었습니다. 이 경우는 선언문과 문장이 서로 다르게 취급되는 몇 안되는 경우입니다. 앞으로 설명의 편의를 위해 **선언****선언문**이라는 용어를 혼용하겠습니다. 둘 다 declaration을 번역한 용어라고 생각해주세요.
161+
> 사실 `선언문(declaration)``문장(statement)` 아니지만, 선언문을 문장으로 보면 이해하기 더 쉬운 경우가 있기 때문에(`int main { ... }`안에는 항상 문장만 들어간다고 생각할 수 있는 등) 둘을 혼용해서 설명했었습니다. 이 경우는 선언문과 문장이 서로 다르게 취급되는 몇 안되는 경우입니다. 앞으로 설명의 편의를 위해 **선언****선언문**이라는 용어를 혼용하겠습니다. 둘 다 declaration을 번역한 용어라고 생각해주세요.
135162
136163
예제를 보겠습니다.
137164

@@ -212,7 +239,7 @@ end:;
212239

213240
`end:` 다음에 세미콜론이 있는 것에 주목해주세요. 레이블 다음엔 반드시 문장이 와야하기 때문에, `end:` 다음에 아무것도 안 한다면 빈 문장으로 세미콜론 하나를 적어야 합니다.
214241

215-
goto문은 너무 많이 사용하면 코드가 읽기 힘들어지기 때문에, goto문을 사용해야하는가에 대한 논쟁이 많이 있었습니다. [이건](https://stackoverflow.com/questions/46586/goto-still-considered-harmful) StackOverflow의 한 질문인데, 무려 49개의 답변이 달린 것을 알 수 있습니다. goto가 정확히 어떤 일이 일으키는지 알고 쓰면 괜찮을 수 있지만, 실수를 일으키기 좋고 대부분의 경우 대체할 수 있는 방법이 있다라는 의견이 많이 보입니다. 즉, "위험성은 큰데 얻을 수 있는 건 적다"는 겁니다. 특히 이중에는 "goto문이 유일한 해법인 것처럼 보이는 경우는 사실 다른 부분의 디자인도 별로인 경우"라고 주장하는 사람도 있었습니다. 그래서 goto문은 되도록 사용을 지양하는 것이 좋을 것 같습니다.
242+
goto문은 너무 많이 사용하면 코드가 읽기 힘들어지기 때문에, goto문을 사용해야하는가에 대한 논쟁이 많이 있었습니다. [이건](https://stackoverflow.com/questions/46586/goto-still-considered-harmful) StackOverflow의 한 질문인데, 무려 49개의 답변이 달린 것을 알 수 있습니다. "goto가 정확히 어떤 일을 일으키는지 알고 쓰면 괜찮을 수 있지만, 실수를 일으키기 좋고 대부분의 경우 대체할 수 있는 방법이 있다"라는 의견이 많이 보입니다. 즉, "위험성은 큰데 얻을 수 있는 건 적다"는 겁니다. 특히 이중에는 "goto문이 유일한 해법인 것처럼 보이는 경우는 사실 다른 부분의 디자인도 별로인 경우"라고 주장하는 사람도 있었습니다. 그래서 goto문은 되도록 사용을 지양하는 것이 좋을 것 같습니다.
216243

217244
물론 goto가 좋다고 생각되는 경우도 몇몇 있습니다. 반복문 안에 반복문을 쓴 경우가 그 예입니다. 3행 3열의 표에 숫자를 저장하되, 대각선 위에 있는 칸에는 음수를 저장하지 않는 프로그램을 만들고 싶습니다. 대각선 위에 있는 칸에 음수를 입력하면 프로그램을 강제종료하고자 합니다.
218245

@@ -275,6 +302,6 @@ int main()
275302
}
276303
```
277304

278-
이렇게 복잡하게 적어야합니다. `if (!valid) break;`가 없으면 `2 2`에서 음수를 입력했어도 `3 1`이동했을 것입니다.
305+
이렇게 복잡하게 적어야합니다. `if (!valid) break;`가 없으면 `2 2`에서 음수를 입력했어도 `3 1`이동합니다.
279306

280307
> C++에선 RAII라는 것 때문에, goto를 쓰고 싶어도 쓰면 컴파일 오류가 발생하는 경우가 많습니다. RAII에 대해선 나중에 다루도록 하겠습니다.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /