(原創) 如何一個字元一個字元的印出字串? (C/C++) (C)
Abstract
若只能一個位元一個位元的印出字串,你會怎麼印呢?
Introduction
我同學要將字串送到硬體,但硬體所提供的API,一次只能送一個字元,在這裡我們模擬這個情境,一個字元一個字元的印出字串。
C語言
1 #include <stdio.h>
2 #include <string.h>
3
4 void func(char *s) {
5 int i;
6
7 for(i = 0; i < strlen(s); i++)
8 putchar(s[i]);
9 }
10
11 int main() {
12 char s[] = "Hello";
13 func(s);
14 }
2 #include <string.h>
3
4 void func(char *s) {
5 int i;
6
7 for(i = 0; i < strlen(s); i++)
8 putchar(s[i]);
9 }
10
11 int main() {
12 char s[] = "Hello";
13 func(s);
14 }
以上的程式絕對可以順利印出Hello沒問題,乍看之下也頗合理,若從其他語言的思考方式來寫C,很容易寫出以上程式碼。
問題出在strlen()。
根據The C Programming Language 2nd P.39,strlen()可能的實做為
int strlen(char s[]) {
int i;
i = 0;
while(s[i] != '\0')
++i;
return i;
}
int i;
i = 0;
while(s[i] != '\0')
++i;
return i;
}
或者如P.99的
int strlen(char *s) {
int n;
for(n = 0; *s != '\0'; s++)
n++;
return n;
}
int n;
for(n = 0; *s != '\0'; s++)
n++;
return n;
}
也就是說,為了得到字串長度,已經多跑了一次迴圈,但事實上,這個迴圈是多餘的,若改成以下寫法,就不須多跑這個迴圈。
C語言 / cstring_putchar.c
1 /*
2 (C) OOMusou 2008 http://oomusou.cnblogs.com
3
4 Filename : cstring_putchar.c
5 Compiler : Visual C++ 8.0
6 Description : Demo how to putchar without strlen()
7 Release : 04/16/2008 1.0
8 */
9 #include <stdio.h>
10 #include <string.h>
11
12 void func(char *s) {
13 while(*s)
14 putchar(*s++);
15 }
16
17 int main() {
18 char s[] = "Hello";
19 func(s);
20 }
2 (C) OOMusou 2008 http://oomusou.cnblogs.com
3
4 Filename : cstring_putchar.c
5 Compiler : Visual C++ 8.0
6 Description : Demo how to putchar without strlen()
7 Release : 04/16/2008 1.0
8 */
9 #include <stdio.h>
10 #include <string.h>
11
12 void func(char *s) {
13 while(*s)
14 putchar(*s++);
15 }
16
17 int main() {
18 char s[] = "Hello";
19 func(s);
20 }
C字串有一個非常好用的特性:最後是'\0'結尾,所以只要搭配pointer一直加1,直到最後為'\0'就停止,這樣就不需在呼叫strlen()了。
Conclusion
一個很小的地方,再次發現C語言字串設計機制的巧妙。
See Also
(原創) 一個關於C語言字串有趣的小題目 (C)
Reference
K&R, The C Programming Language 2nd, Prentice Hall