(原創) 其實C語言使用char array當string也是有他的優點 (C/C++) (C)
沒有一個語言如C語言那樣,竟然沒有內建string型別,竟然要靠char array來模擬,不過今天我發現這種方式也是有他的優點。
C語言除了到處用pointer以外,第二個讓我不習慣的就是沒有內建string型別,竟然得用char array來模擬,不過今天發現,因為C語言array跟pointer綁在一起,若用pointer來處理char array,程式其實相當精簡。
本範例想對字串中的字元,一個字一個字來處理,實務上常常得對字串內容做加工的動作。
2(C) OOMusou 2006 http://oomusou.cnblogs.com
3
4Filename : PointerParseCharStar.cpp
5Compiler : Visual C++ 8.0 / ANSI C / ISO C++
6Description : Demo how to parse string by C and C++
7Release : 01/05/2007
8*/
9
10#include "stdio.h"
11#include <iostream>
12#include <string>
13
14using namespace std;
15
16int main(void) {
17 const char *s1 = "Hello C!";
18 while(*s1)
19 putchar(*s1++);
20
21 cout << endl;
22
23 // By iterator
24 string s2 = "Hello C++!";
25 for(string::iterator c = s2.begin(); c != s2.end(); ++c)
26 cout << *c;
27
28 cout << endl;
29 // By subscripting
30 for(string::size_type ix = 0; ix != s2.size(); ix++)
31 cout << s2[ix];
32}
16行使用char pointer的方式建立字串,由於s1指向的就是"Hello C!"字串第一個字元的記憶體位址,所以17行只要判斷*s1 != '\0'即可,因為C語言非0為true,所以可以省掉 != '\0'的判斷。18行使用putchar()模擬一個字元一個字元的處理,同時使用++將pointer指向下一個字元,程式相當精簡漂亮。
再來看看C++怎麼處理,C++的STL已經增加了string型別,string事實上是一個char vector,若要一個字元一個字元處理,只有使用for loop加上iterator的方式處理,程式明顯大了不少,使用subscripting方式亦可,這是string獨門的寫法。
再來看看C#怎麼處理。
2
3<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4
5<script runat="server">
6 protected void Page_Load(object sender, EventArgs e) {
7 string s = "Hello C#";
8 for (int i = 0; i != s.Length; ++i)
9 this.Label1.Text += s[i];
10 }
11</script>
12
13<html xmlns="http://www.w3.org/1999/xhtml">
14<head runat="server">
15 <title></title>
16</head>
17<body>
18 <form id="form1" runat="server">
19 <div>
20 <asp:Label ID="Label1" runat="server"></asp:Label></div>
21 </form>
22</body>
23</html>
C#也有內建string型別,若要一個字元一個字元處理,採用的是類似array的substring方式,程式也尚稱乾淨。
以前我一直是for的忠實擁護者,覺得for功能強大,沒有必要使用while(),但最近我的想法有改,覺得使用while()其實才是高手,while()語法比較乾淨,遞增的部份可以使用postfix increment ++,唯一while較弱的是沒有內建initialization機制,但pointer剛好不需initialize,因為pointer在宣告時就已確定,如array名稱就是第一個元素的記憶體位址,所以while + pointer其實是絕配。使用subscripting寫法的缺點是,一定得initialization index,這就只能靠for了。
這使我想到The C Programming Language P.93談到為什麼要使用pointer?
Because they are sometimes the only way to express a computation, and partly because the usually lead to more compact and efficient code than can be obtained in other way.
第一個理由,如pass by address,linked list一定得用到pointer才清楚,這會在其他文章討論,但第二個理由,在此範例可發現,pointer寫法的確程式較精簡,會比較難閱讀嗎?其實只要觀念清楚,程式並不難閱讀。套句The C Programming Language P.93的話,"With discipline, however, pointers can also be used to achieve clarity and simplicity." 所以pointer沒學好,結論就是"訓練不夠",:~)
Reference
C Primer Plus 5/e 中文版 P.481, 蔡明志 譯, 碁峰出版社
The C Programming Language P.93, Brain W. kernighan & Dennis M. Ritchie, Prentice Hall