(原創) 其實C語言使用char array當string也是有他的優點 (C/C++) (C)

沒有一個語言如C語言那樣,竟然沒有內建string型別,竟然要靠char array來模擬,不過今天我發現這種方式也是有他的優點。

C語言除了到處用pointer以外,第二個讓我不習慣的就是沒有內建string型別,竟然得用char array來模擬,不過今天發現,因為C語言array跟pointer綁在一起,若用pointer來處理char array,程式其實相當精簡。

本範例想對字串中的字元,一個字一個字來處理,實務上常常得對字串內容做加工的動作。

 1 ExpandedBlockStart.gif ContractedBlock.gif /**/ /* 
 2InBlock.gif(C) OOMusou 2006 http://oomusou.cnblogs.com
 3InBlock.gif
 4InBlock.gifFilename    : PointerParseCharStar.cpp
 5InBlock.gifCompiler    : Visual C++ 8.0 / ANSI C / ISO C++
 6InBlock.gifDescription : Demo how to parse string by C and C++
 7InBlock.gifRelease     : 01/05/2007
 8ExpandedBlockEnd.gif*/

 9 None.gif
10 None.gif#include  " stdio.h "
11 None.gif#include  < iostream >
12 None.gif#include  < string >
13 None.gif
14 None.gif using   namespace  std;
15 None.gif
16 ExpandedBlockStart.gifContractedBlock.gif int  main( void dot.gif {
17InBlock.gif  const char *s1 = "Hello C!";
18InBlock.gif  while(*s1) 
19InBlock.gif    putchar(*s1++);
20InBlock.gif
21InBlock.gif  cout << endl;
22InBlock.gif
23InBlock.gif  // By iterator
24InBlock.gif  string s2 = "Hello C++!";
25InBlock.gif  for(string::iterator c = s2.begin(); c != s2.end(); ++c) 
26InBlock.gif    cout << *c;
27InBlock.gif
28InBlock.gif  cout << endl;
29InBlock.gif  // By subscripting
30InBlock.gif  for(string::size_type ix = 0; ix != s2.size(); ix++
31InBlock.gif    cout << s2[ix];
32ExpandedBlockEnd.gif}


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#怎麼處理。

 1 ExpandedBlockStart.gif ContractedBlock.gif <% dot.gif @ Page Language="C#"  %>
 2 None.gif
 3 None.gif <! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
 4 None.gif
 5 ExpandedBlockStart.gifContractedBlock.gif < script  runat ="server" > dot.gif
 6ExpandedSubBlockStart.gifContractedSubBlock.gif  protected void Page_Load(object sender, EventArgs e) dot.gif{
 7InBlock.gif    string s = "Hello C#";
 8InBlock.gif    for (int i = 0; i != s.Length; ++i)
 9InBlock.gif      this.Label1.Text += s[i];
10ExpandedBlockEnd.gif  }

11None.gif
</ script >
12 None.gif
13 None.gif < html  xmlns ="http://www.w3.org/1999/xhtml" >
14 None.gif < head  runat ="server" >
15 None.gif   < title ></ title >
16 None.gif </ head >
17 None.gif < body >
18 None.gif   < form  id ="form1"  runat ="server" >
19 None.gif     < div >
20 None.gif       < asp:Label  ID ="Label1"  runat ="server" ></ asp:Label ></ div >
21 None.gif   </ form >
22 None.gif </ body >
23 None.gif </ 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值