-
Notifications
You must be signed in to change notification settings - Fork 4
/
charstr.tex
237 lines (215 loc) · 9.69 KB
/
charstr.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
\chapter{Characters and Strings} \label{chap:charstr}
% chapter 8: charstr
C has no built-in string type; by convention, a string is represented as an
array of characters terminated with '\verb+\0+'. Furthermore, C hardly has
a character type; a character is represented by its integer value in the
machine's character set. Because these representations are laid bare and are
visible to C programs, programs have a tremendous amount of control over how
characters and strings are manipulated. The downside is that to some extent,
programs \EM{have} to exert this control: The programmer must remember
whether a small integer is being interpreted as a numeric value or as a
character (see question \ql{8.6}) and must remember to maintain arrays (and
allocated blocks of memory) containing strings correctly.
See also question \ql{13.1} through \ql{13.7}, which cover library functions for
string handling.
\begin{faq}
\Q{8.1} % 8.1 COMPLETE
왜 다음 코드는 실행이 안되는 것일까요?
\begin{verbatim}
strcat(string, '!');
\end{verbatim}
\A
문자열과 문자는 큰 차이가 있습니다. \TT{strcat()} 함수는 문자열을
이어주는 함수입니다.
\verb+'!'+와 같은 문자 상수(character constant)는 한 문자를 나타냅니다.
문자열(string literal)은 쌍따옴표로 둘러싼, 대개 여러 글자의 문자로
구성됩니다. \verb+"!"+와 같은 문자열은 하나의 문자를 나타내는 것처럼
보이지만, 실제로 \verb+!+ 문자와, 문자열 끝을 나타내는 \verb+\0+, 두
개의 문자로 구성됩니다.
C 언어에서 문자는 문자 집합(character set)에서 그 문자가 나타내는
작은 정수 값으로 표현됩니다 (질문 \ql{8.6}을 참고하기 바랍니다).
문자열은 문자들의 배열로서 표현됩니다; 문자열을 다룰 때에는
보통 문자 배열의 첫 요소를 가리키는 포인터를 써서 합니다.
% 다음 문장 번역,
It is never correct to use one when the other is expected.
문자열에 \verb+!+를 이어 붙이려면 다음과 같이 해야 합니다.
\begin{verbatim}
strcat(string, "!");
\end{verbatim}
질문 \ql{1.32}, \ql{7.2}, \ql{16.6}을 참고하기 바랍니다.
\R
\cite{ctp} \S\ 1.5 \Page{9--10}
\end{faq}
\begin{faq}
\Q{8.2} % 8.2 COMPLETE
문자열이 어떤 특정한 값과 같은지 검사하려고 합니다. 다음과 같이
코드를 만들었는데 왜 동작하지 않을까요?
\begin{verbatim}
char *string;
...
if (string == "value") {
/* string matches "value" */
...
}
\end{verbatim}
\A
C 언어는 문자열을 문자의 배열로 처리합니다. 그리고 C 언어에서는
배열 전체에 대해 어떤 연산을 (대입, 비교 등) 직접 할 수 있는
방법은 없습니다. 위의 코드에서 \verb+==+ 연산은
피연산자인 포인터의 값을 비교합니다 --- 즉 변수 \TT{string}의
포인터 값과 문자열 \verb+"value"+를 가리키는 포인터 값을
비교합니다 ---
따라서 두 개의 포인터가 같은 곳을 가리키는지를 비교합니다.
대개의 경우 이 값이 같게 될 경우는 거의 없으므로, 이 비교는
거의 항상 같지 않다고 나옵니다.
두 문자열을 비교하는 방법으로 라이브러리 함수인 \TT{strcmp()}를 쓰는
것이 가장 좋습니다:
\begin{verbatim}
if (strcmp(string, "value") == 0) {
/* string matches "value" */
...
}
\end{verbatim}
\end{faq}
\begin{faq}
\Q{8.3} % 8.3 COMPLETE
다음과 같이 할 수 있다면:
\begin{verbatim}
char a[] = "Hello, world!";
\end{verbatim}
\noindent 왜 이렇게는 할 수 없을까요?
\begin{verbatim}
char a[14];
a = "Hello, world!";
\end{verbatim}
\A 문자열은 배열입니다. 그리고 배열에는 직접 대입 연산을 쓸 수
없습니다. \TT{strcpy()} 함수를 쓰기 바랍니다:
\begin{verbatim}
strcpy(a, "Hello, world!");
\end{verbatim}
질문 \ql{1.32}, \ql{4.2}, \ql{6.5}, \ql{7.2}를 참고하기 바랍니다.
\end{faq}
\begin{faq}
\Q{8.4} % 8.4 COMPLETE
왜 \TT{strcat}이 동작하지 않을까요? 아래 코드처럼 했는데, 잘
안됩니다:
\begin{verbatim}
char *s1 = "Hello, ";
char *s2 = "world!";
char *s3 = strcat(s1, s2);
\end{verbatim}
\A
질문 \ql{7.2}를 보기 바랍니다.
\end{faq}
\begin{faq}
\Q{8.5} % 8.5 COMPLETE
아래 두 초기화 문장의 차이가 있나요?
\begin{verbatim}
char a[] = "string literal";
char *p = "string literal";
\end{verbatim}
\noindent 제 프로그램에서 \TT{p[i]}에 어떤 값을 대입하려 하면
프로그램이 비정상적으로 끝나버립니다.
\A
질문 \ql{1.32}를 보기 바랍니다.
\end{faq}
\begin{faq}
\Q{8.6} % 8.6 COMPLETE
문자에 해당하는 수치 (ASCII 또는 다른 문자 set code)) 값을
어떻게 얻을 수 있죠?
또 그 반대로 수치 값에서 그 값에 해당하는 문자를 어떻게 얻을 수 있죠?
\A
C 언어에서 문자는 (컴퓨터의 문자 셋의) 문자 코드 번호로 작은
정수로서 표현됩니다. 따라서 질문한 것과 같은 변환이 필요없습니다;
즉 문자를 가지고 있다면, 그 자체가 값이 됩니다. 예를 들어, 다음 코드는:
\begin{verbatim}
int c1 = 'A', c2 = 65;
printf("%c %d %c %d\n", c1, c1, c2, c2);
\end{verbatim}
ASCII를 쓰는 시스템에서, 다음과 같은 출력을 만들어 냅니다:
\begin{verbatim}
A 65 A 65
\end{verbatim}
\noindent \seealso{\ql{8.9}, \ql{20.10}}
\end{faq}
\begin{faq}
\Q{8.7} % 8.7 COMPLETE
C 언어에서, 다른 언어에서 제공하는 것처럼, 문자열의 일부를 뽑아내는,
``substr''와 같은 기능이 있나요?
\A
질문 \ql{13.3}를 보기 바랍니다.
\end{faq}
\begin{faq}
\Q{8.8} % 8.8 COMPLETE
사용자가 입력한 문자열을 읽어서 배열에 저장한 다음, 나중에 출력하려고
합니다. 사용자가 \verb+\n+와 같은 문자를 입력한 경우, 왜 제대로
처리되지 않을까요?
\A
\verb+\n+와 같은 문자 시퀀스(character sequence)들은 컴파일할 때
해석됩니다. 문자 상수나 문자열에 백슬래시가 나오고 바로 뒤에
\verb+n+이 나오면, 한 글자, newline 문자로 해석됩니다.
(다른 character escape sequence도 비슷한 방법으로 처리됩니다.)
사용자나 파일에서 문자열을 읽을 때는 이와 같은 해석이 적용되지 않습니다:
즉, 백슬래시는 다른 문자와 전혀 다를게 없이 취급되며, 하나의 문자로
간주됩니다. (run-time I/O가 일어날 때, newline 문자를 위해 어떤
번역 작업이 이뤄질 수 있지만, 이 것은 전혀 다른 문제입니다. 질문
\ql{12.40}을 보기 바랍니다.) \seealso{\ql{12.6}}
\end{faq}
\begin{faq}
\Q{8.9} % 8.9 COMPLETE
제 컴파일러에 버그가 있습니다. \verb+sizeof('a')+의
값이 \verb+sizeof(char)+인 1로 나오지 않고, 2가 나옵니다.
\A
놀랍게도, C 언어에서 문자 상수(character constant)의
타입은 \TT{int}입니다.
따라서 \verb+sizeof('a')+는 \verb+sizeof(int)+와 같습니다.
(C++에서는 조금 다릅니다.) \seealso{\ql{7.8}}
\T
참고로 C++에서 문자 상수의 타입은 \TT{char}입니다. 즉,
\verb+sizeof('a')+는 \verb+sizeof(char)+와 같습니다.
\R
\cite{ansi} \S\ 3.1.3.4 \\
\cite{c89} \S\ 6.1.3.4 \\
\cite{hs} \S\ 2.7.3 \page{29}
\end{faq}
\begin{faq}
\Q{8.10} % 8.10
I'm starting to think about multinational character sets. Should I
worry about the implication of making \TT{sizeof(char)} be 2 so that
16-bit character sets can be represented?
% 여러 언어를 처리할 수 있는 문자 세트(multinational character set)를
% 생각하고 있습니다. 16-bit 문자 세트를 지원하기 위해,
% \verb+sizeof(char)+가 2가 되는 것을 기대할 수 있을까요?
% TODO: 맞게 번역한 건가?
\A
만약 \TT{char}가 16 bit가 된다고 해도, \TT{sizeof(char)}는 여전히
1이 됩니다. 대신 \verb+<limits.h>+에 정의된, \verb+CHAR_BIT+이
16이 됩니다. 이 경우에는 한, 8-bit 오브젝트를 선언하는 것은 (또,
\TT{malloc}으로 할당하는 것도) 불가능합니다.
전통적으로, 한 바이트가 꼭 8 bit일 필요는 없습니다. 단지, 한 글자를
저장하기에 충분한, 작은 크기의 메모리 공간이면 됩니다. C 표준에서도
이 방식을 따르며, 따라서 \TT{malloc}이나 \TT{sizeof}에서 쓰이는
바이트가 8 bit 이상일 수도 있습니다.\footnote{전문 용어로, 8 bit로
표현되는 바이트를 ``octet''이라고 합니다.} (대신 표준에서, 바이트가
8 bit 이상되어야 한다고 정해 놓았습니다.)
Multinational character set을 처리하기 위해서는 \TT{char} 이상의
어떤 타입이 필요하고, ANSI/ISO C 표준에서는 이를 위해, 더 큰 범위를
포함할 수 있다는 뜻의 ``wide'' 문자 타입인, \verb+wchar_t+를
제공합니다. 또한 이 타입으로 처리하는 wide 문자 상수, wide 문자열,
또 wide 문자 및 문자열을 처리할 수 있는 함수들을 제공합니다.
\seealso{\ql{7.8}}
\R
\cite{ansi} \S\ 2.2.1.2, \S\ 3.1.3.4, \S\ 3.1.4, \S\ 4.1.5, \S\ 4.10.7,
\S\ 4.10.8 \\
\cite{c89} \S\ 5.2.1.2, \S\ 6.1.3.4, \S\ 6.1.4, \S\ 7.1.6, \S\ 7.10.7,
\S\ 7.10.8 \\
\cite{rationale} \S\ 2.2.1.2 \\
\cite{hs} \S\ 2.7.3 \Page{29--30}, \S\ 2.7.4 \page{33},
\S\ 11.1 \page{293}, \S\S\ 11.7, 11.8 \Page{303--10}
\end{faq}
%
% Local Variables:
% coding: utf-8
% fill-column: 78
% End:
%