ABookOnC Chapter 5 - 5.4
이름: 나영철[삭제] [수정] 2001-01-21 04:15:09
Chapter 5

Functions

The heart of effective problem solving is problem decomposition. Taking a problem and breaking it into small, manageable pieces is critical to writing large programs.
효과적인 문제 풀이의 본질은 문제 해체이다. 문제를 취하고 그것을 깨어뜨리는 것은 작은 것 안에서, 다루기 쉬운 조각들(작은 것)은 커다란 프로그램들을 써 가는데 중요하다.
(다루기 쉬운 조각들 그 작은 것 안에서 문제를 취하고 풀어 나가는 것은 커다란 프로그램들을 써 나가는 데에 있어 중요하다.)

In C, the function construct is used to implement this “top-down” method of programming. A program consists of one or more files, with each file containing zero or more functions, one of them being a main() function.
C에서는, 함수 구조물이 프로그래밍의 “top-down”(위에서 아래로, 하향식)을 논리적인 방식(method)으로 이행하기 위해(충족시키기 위해, implement) 사용되어 진다. 하나의 프로그램은 하나 또는 더 많은 파일들의 구성이다. 각각의 파일들은 함수가 없거나 더 많은 함수들을 가지고 있고, 그 가지고 있는 함수들 중에서 하나는 main() 함수가 된다.
(함수를 가지고 있지 않거나 (함수들 중에 하나는 main()함수가 되는) 더 많은 함수들을 가지고 있는 각각의 파일들 혹은 하나의 파일은 하나의 프로그램의 구성이 된다.)

Functions are defined as individual objects that cannot be nested. Program execution begins with main(), which can call other functions, including library functions such as printf() and sqrt().
함수들은 포개어 넣을 수 없는(독립적인 형태로 존재하는) 각각의 객체들로 정의되어 진다.프로그램의 수행은 main()과 함께 시작되어 지고, 그것은(main()은) printf()와 sqrt()와 같은 라이브러리 함수들을 포함하는 다른 함수들을 부를 수 있다.

Functions operate with program variables, and which of these variable at a particular place in a function is determined by scope rules. In this chapter we discuss function definition, function declaration, scope rules, storage classes, and recursion.
함수들은 프로그램 변수들과 움직이는데, 특별한 위치에 있는 이러한 변수들은 범위의 법칙들에(scope rules) 의해 정의되어 졌다.  이 챕터에서 우리는 함수정의(function definition), 함수선언(function declaration), 범위의 법칙(scope rules)들, 저장 클래스들(storage classes), 그리고 재귀(반복,회귀, recursion)에 대해서 논의 한다.

5.1 Function Definition

The C code that describes what a function does is called the function definition. It must not be confused with the function declaration. A function definition has the following general form:
함수가 무엇을 하는지 묘사하는 C code를 함수 정의(function definition)라 부른다. 그것은 함수선언(function declaration)과 혼동하지 말아야 한다. 함수정의는 다음의 일반적인 형태를 따른다.

type    function_name( parameter list ) { declaration    statements }

Everything before the first brace comprises the header of the function definition, and everything between the braces comprises the body of the function definition. The parameter list is a comma-separated list of declarations. An example of a function definition is
첫번째 중괄호 앞의 모든 것은 함수정의의 헤더파일로 이루어진다. 그리고 중괄호들 사이에 있는 모든 것은 함수정의(function declaration)의 몸체로 이루어진다. 매개변수(parameter) 목록은 콤마로 나누어져 선언한 것들의 목록들이 된다.( int I, product = 1, …. 이런 식으로 콤마로 나누어진 목록들이 매개변수의 목록이 된다는 얘기이죠^_^.)

int factorial (int n)              /* header */
{
int i, product = 1;
for (i = 2; i <= n; ++i)
product *= i;
return product;
}

The first int tells the complier that the value returned by the function will be converted, if necessary, to an int.
첫번째 int는, (만일 필요하다면 int로 변환되어질) 함수에 의해 돌려 받는 값을 컴파일러에게 얘기해 준다.

The parameter list consists of the declaration int n. This tells the compiler that the function takes a single argument of type int. An expression such as factorial(7) causes the function to be invoked, or called. The effect is to execute the code that comprises the function definition, with n having the value 7. Thus, functions act as useful abbreviating schemes. Here is another example of a function definition:
매개변수 목록(parameter list, (int n))은 int n 선언으로 구성되어져 있다. 이것은 컴파일러에게 함수가 int 형의(type int)의 하나의 독립변수를 취한다는 것을 말해준다. factorial(7)과 같은 한 표현은 함수를 가져오거나 부르게 한다. 그 결과는 n이 7이라는 값을 가지는 함수정의를 포함하는 코드를 실행하는 것이다. 이와 같이, 함수들은 유용하게 간략한 계획들을 행하는 역할을 한다. 여기 또 다른 함수 정의의 예가 있다.

void wrt_address(void)
{
printf(“%s\n%s\n%s\n%s\n%s\n\n”,
“            ********************”,
“             **   SANTA CLAUS     *”,
“             **   NORTH POLE      *”,
“             **   EARTH                 *”,
“             ********************”,);
}

The first void tells the compiler that this function returns no value; the second void tells the compiler that this function takes no arguments. The expression
첫번째 void 는 컴파일러에게 이 함수는 값을 되돌리지 않는다고 말한다; 두 번째 void는 컴파일러에게 어떠한 독립변수(arguments,앞으로는 그냥 argument라고 쓰는 게 좋겠어요.) 들도 취하지 않는다는 것을 말해준다.

wrt_address()

causes the function to be invoked. For example, to call the function three times we can write

wrt_address() 라는 표현은 함수를 불러들이게 한다. 예를 들어서, 함수를 세 번 불러들이기 위해 우리는 다음처럼 쓸 수 있다.

for (i = 0; i< 3; ++i)
wrt_address();

A function definition starts with the type of the function. If no value is returned, then the type is void. If the type is something other than void, then the value returned by the function will be converted, if necessary, to this type.
함수 정의는 함수의 형(type)과 함께 시작된다. 만약 값을 되돌려 받지 않으면 형(type)은 void 가 된다. 만일 void 가 아닌(밖의) 다른 어떤 형(type)이라면, 만약 그 형(type)을 필요로 한다면 함수는 그 형(type)으로 변환되어 질 것이며 그에 따른 값을 되돌린다.

The name of the function is followed by a parenthesized list of parameter declarations. The parameters act as placeholders for values that are passed when the function is invoked. Sometimes, to emphasize their role as placeholders, these parameters are called the formal parameters of the function. The function body is a block, or compound statement, and it too may contain declarations. Some examples of function definitions are
함수의 이름은 괄호()가 쳐진 매개변수(parameter)선언의 목록에 의해 따라오게 된다. 매개변수(parameter)는 함수가 불러들여졌을 때 받아진 값들을 장소잡이의(저장하는,placehoders) 행동을(역할을) 한다.  때때로, placeholders의 역할을 강조하기위해, 이러한 매개변수(parameters) 들은 함수의 형식적인 매개변수(parameters) 로 불리워 진다.
함수의 몸체는 block({}) 혹은 문장(statement)의 결합으로 되어 있다. 그리고 그것은 꽤 많은 선언들을 포함한다. 함수 정의들 중에 어떤 예들이 있다.

void nothing(void) {}          /* this function does nothing */

double twice(double x)
{
return (2.0 * x);
}


int all_add(int a, int b)
{
int c;
....


return (a + b + c);
}

If a function definition does not specify the function type, then it is int by default. For example, the last function definition could be given by
만약 함수정의(function definition)가 함수형(type)을 지정하지 않았다면, 그러면 그 형(type)은 default 값으로 int 가 된다. 예를 들어, 마지막에 있는 함수정의는 (아래 식에)의해서 주어질 수 있을 것이다.

all_add(int a, int b)
{
....

However, it is considered good programming practice to specify the function type explicitly.
하지만 좋은 프로그래밍 습관은 함수(type)형을 명확하게 지정하는 것으로 고려되어 진다.

Any variables declared in the body of a function are said to be “local” to that function. Other variables may be declared external to the function. These are called “global” variables. An example is
함수의 몸체 안에서 선언된 어떤 변수들은 함수에 대한 지역(local)변수라고 얘기되어 진다.
나머지 다른 변수들은 함수 밖에서 선언될 수 있을런지도 모른다. 이러한 것들을 포괄적인(전역, global) 변수라고 불려진다. 한 예를 들면

#include

int a = 33;           /* a is externel and initialized to 33 */
int main(void)
{
int b = 77;

printf(“a = %d\n”, a);
printf(“b = %d\n”, b);
return 0;
}

In traditional C, the function definition has a different syntax. The declarations of the variables in the parameter list occur after parameter list itself and just before the first brace. An example is
전통적인 C에서는, 함수정의가 다른 구분법(문장법, syntax)을 가지고 있다. 매개변수(parameter)목록에서 변수들의 선언은 매개변수(parameter) 목록 자신과 첫번째 중괄호의 바로 앞에서 발생한다.
한 예를 들면

void f(a, b, c, x , y)
int   a, b, c;
double   x, y;
{
....

The order in which the parameters are declared is immaterial. If there are no parameters, then a pair of empty parentheses is used. ANSI C compiler will accept this traditional syntax as well as the newer syntax. Thus, traditional code can still be compiled by an ANSI C compiler.
선언된 parameter 들의 순서는(the order) 중요하지 않다. 만약 parameter들이 필요하지 않다면, 비어 있는 괄호()한 쌍이 사용되어 진다. ANSI C 컴파일러는 새로운 문법 만큼이나 전통적인 문법 또한 받아들일 것이다. 따라서, 전통적인 코드는 여전히 ANSI C 컴파일러에 의해서 컴파일 될 수 있다.

There are several important reasons to write programs as collections of many small functions. It is simpler to correctly write a small function to do one job. Both the writing and debugging are made easier. It is also easier to maintain or modify such a program.
많은 작은 함수들의 집합체로 프로그램을 쓰는(짜는,write) 몇 가지 중요한 이유들이 있다. 한 작업을 하기 위해 정확하게 작은 함수를 쓰는 것이 더 쉽다. 쓰는(짜는) 것과 디버깅(debugging, 버그 잡는 일)하는 일 두 가지 모두가 더 쉽게 만들어진다. 그러한 프로그램은 또한 유지하고 수정하기에도 더 쉽다.

One can readily change just the set of functions that need to be rewritten, expecting the rest of the code to work correctly. Also, small functions tend to be self-documenting and highly readable. A useful heuristic for writing good programs is to write each function so that its code fits on a single page.
알맞은 작업을 위해 코드의 나머지 부분을 기대하고 있는, 다시 쓰여질 필요가 있는 함수들의 쓰임새(배치,모습 set)를 손쉽게 바꿀 수가 있다. 또한, 작은 함수들은 스스로 문서화되는 그리고 상당히 읽기 쉬운 경향을 지닌다. 좋은 프로그램들을 쓰는 유용한 발견적 교수법(heuristic)은 하나의 페이지 위에 그 함수들의 코드가 맞추어지도록 각각의 함수들을 쓰는 것이다.
(한 페이지가 넘어가지 않도록 짧게 그 함수의 코드를 작성하고 그러한 각각의 함수들로 이루어진 프로그래밍이 좋으며 유용하다는 뜻이다.)

5.2 The return Statement

The return statement may or may not include an expression.
리턴 문은 하나의 표현을 포함할 수도 있고 그렇지 않을 수도 있다.

return_statement ::= return; | return expression;

Some examples are
어떤 예들이다

return;
return ++a;
return (a * b);

The expression being returned can be enclosed in parentheses, but this is not required. When a return statement is encountered, execution of the function is terminated and control is passed back to the calling environment.
되돌려지는(리턴받는) 표현(retrun 뒤에오는 위에서는 ++a, (a*b) 이런것들)은 괄호() 안에 닫혀질 수 있다. 하지만 이것은 요구되어 지는 것은 아니다. 리턴 문을 마주치게 되었을 때, 함수의 실행은 끝이 나고 제어(control)는 환경을 부르기 위해 뒤로 소멸되어(사라져, 전달되어, passed) 간다.
(리턴 문이 오게 되면 함수는 그 실행을 끝마치고 제어(control)도 끝이 나면서 원래의 환경(함수의 영향을 받지 않는 환경)으로 돌아간다는 얘기 입니다.)

If the return statement contains an expression, then the value of the expression is passed back to the calling environment as well. Moreover, this value will be converted, if necessary, to the type of the function as specified in the function definition.
만약 리턴 문이 하나의 표현을 포함하면, 그 표현의 값은 불려지는 환경에게 뒤로 전달(passed)되어진다. 더욱이, 이 값은 그것이 필요하다면, 함수정의에서 지정한 함수의 형(type)으로 변환되어진다.

float f(char a, char b, char c)
{
int i;
....

return i;           /* value returned will be converted to a float */
}                       /* 값은 float으로 변환되어져 돌려졌다. */

There can be zero or more return statements in a function. If there is no retrun statement, then control is passed back to the calling environment when the closing brace of the body is encountered. This is called “falling off the end.” The following function definition illustrates how two return statements might be used:
함수는 영(0)개의 혹은 더 많은 리턴문 들이 있을 수 있다. 만약 리턴문(return statement)이 없다면, 콘트롤(제어,control)은 함수의 몸체를 닫는 중괄호}를 만나게 되었을 때 환경을 부르며 뒤로 전달(사라지게passed)되어진다. 이것은 “마지막을 끝내는 것,(falling off the end.)” 이라고 불려진다. 다음에 적혀있는 함수정의는 어떻게 두개의 리턴 문이 쓰여질 수 있는지 설명한다.

double absolute_value(double x)
{
if (x >= 0.0)
return x;
else
return -x;
}

Even though a function returns a value, a program does not need to use it.
비록 함수가 리턴 값을 갖는다고 해도, 한 프로그램이 그것을 사용할 필요는 없다.

while (…….) {
getchar();             /* get a char, but do nothing with it */
c = getchar()        /* 문자를 얻는다, 하지만 그것과 함께 아무것도 하지 않는다.
....                        /* c will be processed */
}

(그러니까 리턴 값을 갖는다 해도 그것을 당장에 사용하지 않을(리턴 시키지 않을)수도
있다는 얘기인 것 같습니다.)

5.3 function prototypes

Functions should be declared before they are used. ANSI C provides for a new function declaration syntax called the function prototype. A function prototype tells the compiler the number and type of arguments that are to be passed to the function and the type of the value that is to be returned by the function. An example is
함수는 그것을 사용하기 전에 선언 되어야만 한다. ANSI C 는 함수 기본형(함수 원형, function prototype)이라고 불려지는 새로운 함구 선언 구문 법을 제공한다. 함수 기본형(함수 원형, function prototype) 은 컴파일러에게 고정변수(arguments) 들의 형(type)과 숫자를 얘기해준다. 고정변수(arguments) 들은 함수에게 전달되어지고 그 값의 type(형)은 함수에 의해 되돌려 받는다. 한 예가 있다.

double sqrt(double);

This tells the compiler that sqrt() is a function that takes a single argument of type double and returns a double. The general form of a function prototype is
이것은 컴파일러에게, sqrt()는 함수인데 그것은 double 형의(type double) 변수 하나를 취하고 double을 되돌린다고 얘기해 준다.  함수 기본형(function prototype)의 일반적인 형태는 아래에 있다.

type function_name (parameter type list);

The parameter type list is typically a comma-separated list of types. Identifiers are optional; they do not affect the prototype. For example, the function prototype
매개변수 형(parameter type)목록은 전형적으로 콤마로 나누어진 형(types)들의 목록이다.
인식자는(char c, int i에서, c와 i에 해당되는 것들) 선택적인 것들이다; 그들은 기본형(prototype)에 영향을 미치지 않는다. 예를 들면, 함수 원형은

void f(char c, int i);       is equivalent to         void f(char, int);

The identifiers such as c and i that occur in parameter type lists in function prototypes are not used by the compiler. Their purpose is to provide documentation to the programmer and other readers of the code. The keyword void is used if a function takes no arguments.
c와 i와 같이 함수 기본형(function prototypes)들 안에 있는 매개변수의 형(type)의 목록에서 발생되는 인식자(identifier)들은컴파일러에 의해서 쓰이지 않는다. 그들의 목적은 코드를 읽는 독자들과 프로그래머들에게 문서로(문서의 의미로,documanetation) 제공하기 위한 것이다. 키워드(keyword) void는 만약 함수가 어떠한 고정변수(arguments)들도 취하지 않으면 사용되어 진다.

Also, the keyword void is used if no value is returned by the function. If a function takes a variable number of arguments, then the ellipses(…) are used. See, for example, the function prototype for printf() in the standard header file stdio.h.
또한, keyword void는 함수에 의해 값을 되돌려 받지 않을 때도 사용되어진다. 만약 함수가 많은 수의 고정변수(arguments) 들의 변수(vriable)를 취하면(a variable number of arguments), 그러면 생략기호(ellipses)가 사용되어 진다. 표준 헤더파일인 stdio.h 안의 printf()  함수의 함수 기본형(function prototype)을 보아라.

Function prototypes allow the compiler to check the code more thoroughly. Also, values passed to functions are properly coerced, if possible. For example, if the function prototype for sqrt() has been specified, then the function call sqrt(4) will yield the correct value. Because the compiler knows that sqrt() takes a double, the int value 4 will be promoted to a double and the correct value will be returned. (See exercise 5, on page 236, for further discussion.)
함수 원형들은 컴파일러가 코드를 더욱 완전하게 체크 하게 한다. 또한, 만약 가능하다면, 함수로 전달된 값들은 적절하게(정확하게, 철두철미하게, properly) 지배된다. 예를 들면, sqrt() 함수를 위해 함수 기본형(function prototype)이 정의되어 졌다면, 그렇다면 sqrt(4)라는 이름의 함수는 정확한 값을 따르게(양보하게, 굴복하게, 내어주게, yield) 될 것이다. 왜냐하면 컴파일러는 sqrt()함수가 double(형)을 취한다는 것을 알고 있다. int(정수) 형의 값인 4는 double 형으로(type)로 바뀌어서 수행되어(맞추어져서 진행되어,진급되어,진척되어 promote)질 것이고 정확한 값은 돌려질 것이다.

In traditional C, parameter type lists are not allowed in function declarations. For example, the function declaration of sqrt() is given by
전통적인 C에서는, 매개변수 목록(parameter list)이 함수 선언들 안에서 허락되어 지지 않았다. 예를들면, sqrt()함수의 선언은 다음과 같이 주어졌다.

double sqrt();                       /* traditional C style */

Even though ANSI C compilers will accept this style, function prototypes are preferred. With this declaration, the function call sqrt(4) will not yield the correct value.(See exercise 5, on page 236.)
비록 ANSI C 컴파일러들은 함수 기본형(function prototype)들이 선택해 버린 이러한 스타일을 받아들이겠지만. 이러한 선언과 함께 한다면, sqrt(4)라는 함수는 바른 값을 양보해주지(따라주지, 내어주지, yield) 않게 될 것이다.

Function Prototypes in C++

In C++, function prototypes are required, and the use of void in the parameter type list in both function prototypes and function definitions is optional. Thus, for example, in C++
C++ 안에서는, 함수 기본형(function prototype)들이 요구되어지고, 함수 기본형(function prototype) 과 함수 정의들(function definition) 둘 모두 안에 존재하는 매개변수 형(parameter type)안에서 void 의 사용이 써도 되고 안 써도 되는 마음대로 해도 되는 것이 된다.

void f()             is equivalent to              void f(void)

Note carefully that this results in a conflict with traditional C. In traditional C, a function declaration such as
신중하게 노트해라. 이것의 결과는 결국 전통적인 C 와의 충돌이다. 전통적인 C에서의 함수 선언은 다음과 같다.

int f();

means that f() takes an unknown number of arguments. In traditional C, void is not a keyword. Thus, it cannot be used in a parameter list in a function declaration or function definition.
int f(); 는 f()가 고정변수 들의(arguments) 알 수 없는 수를(알 수 없는 변수, 변수 형)취하는 것을 의미한다. 전통 C에서는, void는 keyword 가 아니다. 따라서, 그것은(void는) 함수 선언이나 함수정의 안에 존재하는 매개변수 목록(parameter list)에서 쓰여질 수 없었던 것이다.

5.4 An Example: Creating a Table of Powers

In this section, we give an example of a program that is written using a number of functions. For simplicity, we will write all the functions one after another in one file. The purpose of the program is to print a table of powers.

이번 섹션에서는, 많은 함수들을 사용해서 쓰여진 한 프로그램의 예를 준다. 간단하게, 우리는 하나의 파일안에 하나의 함수 뒤에 또다른 하나의 함수가 오도록 모든 함수들을 쓸 것이다. 프로그램의 목적은 ‘a table of powers’를 프린트 하는 것이다.

#include

#define    N    7

long    power(int, int);
void    prn_heading(void);
void    prn_tbl_of_powers(int);

int main(void)
{
prn_heading();
prn_tbl_of_powers(N);
return 0;
}

void prn_heading(void)
{
printf(“\n:::::    A TABLE OF POWERS    :::::\n\n”);
}

void prn_tbl_of_powers(int n)
{
int    i,   j;

for (i = 1; i<= n; ++i) {
for (j =1; i <= n; ++j)
if (j == 1)
printf(“%ld”, power(i, j));
else
printf(“%9ld”, power(i, j));
putchar(‘\n’);
}
}

long power(int m. int n)
{
int    i;
long    product = 1;

for (i = 1; i <= n; ++i)
product *= m;
return product;
}

Here is the output of the program:

:::::    A TABLE OF POWERS    :::::
1    1    1    1    1    1    1
2    4    8    16    32    64    128
3    9    27    81    243    729    2187
…..

Note that the first column consists of integers raised to the first power, the second column consists of integers raised to the second power, and so forth. In our program we have put the function prototypes near the top of the file. This makes them visible throughout the rest of the file. We used the type long so that the program will produce the same output whether the machine has 2- or 4-byte words. Note that the function power() computes the quantity m(n), which is m raised to the nth power.
첫번째 열은 1 제곱된 정수들로(raise to the first power,  여기서 power란 제곱(멱)을 의미합니다.) 구성되어 있다. 두번째 열은 2제곱된 정수들로 구성되어져 있다. 그리고 so forth(계속, 등등). 우리들의 프로그램 안에 우리는 그 파일의 꼭대기에 가까운 곳에 function prototypes 들을 집어 넣었다. 이것은 그들을 그 파일의 나머지부분을 통틀어서 볼 수 있게 만들어 준다. 우리는 long 형을 사용했는데 그것은 2바이트나 4바이트 단어들을 가진 머신에서 (둘 중 어느 것이든 간에) 같은 output을 출력해 낼 것이다. power()라는 함수는 m의 n승(제곱)의 양을 계산하는데, 그것은 m이 n번째 제곱된 값으로 증가되어 지는 것이다.

Our program illustrates in a very simple way the idea of top-down design. The programmer thinks of the tasks to be performed and codes each task as a function. If a particular task is complicated, then that task, in turn, can be subdivided into other tasks, each coded as a function. An additional benefit of this is that the program as a whole becomes more readable and self-documenting.
우리의 프로그램은 top-down (하향식) 디자인의 아이디어를 매우 간단하게 설명한다. 프로그래머는 수행 되어지기 위한 과업,과제(tasks)들을 생각하고 함수와 같이 각각의 과업, 과제(task)를 코드화 한다. 만약, 특별하게 복잡하게 된 과제라면, 그렇다면 그 과제는 돌려서, 함수처럼 각각 코드화된 다른 과제들 속으로 subdivided(낮게 나누어지게, 작은 단위로 나누어지게) 할 수 있다. 이것의 부가적인 이득은 프로그램 전체가 더 자기 스스로 문서화 되고 더 읽을 수(읽기 쉽게)있게 된다.
  이 름  암 호  보안코드  
번호작성자날짜조회제    목
77onion2001-02-023042   [잡담] Counter이상 있는거 아닙니까...? (3)
76onion2001-02-023038   [잡담] 하웅......퇴근해야지....
75onion2001-02-012845   [잡담] 햐아..밤새버렸습니다...후훗..
74onion2001-01-302817   [잡담] 대문이 바뀌었다아... (4)
73GoodWolf2001-01-293603   NeXT에서 아파치랑 php랑 MysQL..어떻게 하나여?? (1)
72최승희2001-01-294824   야동 가는길.... 그것이 200m나 ??
71나영철2001-01-213911   ABookOnC 를 올린 이유
70나영철2001-01-213562   ABookOnC Chapter 6 - 6.2 Source code 까지
69나영철2001-01-213229   ABookOnC Chapter 5 - 5.4
68나영철2001-01-214355   ABookOnC Chapter 1 - 1.3
67onion2001-01-162969   [잡담] 아이 XX팔려라....캬캬캬...
66최승희2001-01-163007   심각한 고민..이걸 어떻게 풀어야 하지? (1)
65나영철2001-01-162944   왜 제 글에 대한 답은 안해주시나요?? (1)
64onion2001-01-153367   [잡담] 간단하게 한글 사용법을 제 홈에 올렸습니다.. (1)
63onion2001-01-143939   [질문] openstep 에서 한글이요... (11)
[≪] [<] [51] [52] [53] [54] [55] [56] [57] [58] [59] [60]