-- while文とプレ/ポストインクリメント --
下記のソースは文字列を対象バッファにコピーするサブルーチンです。
1 #include <stdio.h>
2
3 int strcp(char *src, char *dst)
4 {
5 char *stp;
6
7 stp=src;
8 while((*dst++ = *src++) != 0);
9
10 return (src - stp);
11 }
12
13 int main( )
14 {
15 char *sp = "This is source string.";
16 char dst[100];
17 int l;
18
19 l=strcp(sp, dst);
20 printf("Copy String=[%s] len=%d\n",dst,l);
21
22 return 0;
23 }
このソースには注意すべき点がいくつかあります。
一つは、strcp 関数が main関数より前に宣言されている点です。こうすることで関数の型を別途プロトタイプ宣言で宣言する必要がなくなります。もしもmain関数より後で宣言する場いや別ファイルで定義する場合は
int strcp(char *src,char *dst);
というプロトタイプ宣言を関数を参照しているmain関数より前に入れる必要があります。
次に8行目にある(*dst++ = *src++)です、これを(*++dst = *++src) と書くと意味合いが違ってきます。
dst++ はdst に入っている文字列へのポインタが参照された後にポインタ値が増加します。これをポストインクリメントといいます。
++dst は文字列へのポインタ値を増加させた後の値を参照するためコピーバッファを1つ飛ばしてしまうことになります。
これをプレインクリメントといいます。それぞれ動作が異なるので注意を要します。
それと、( )囲まれた式はコンマで区切ることが出来それ自体値を持ちます。
例えば、(*dst++ = *src++, *dst) とするとこのカッコの値は *dst の値が帰るため1文字移した時点でwhile文を出てしまいます。
ただし、引数のdstバッファは自動変数dでスタック上に配置されるため0詰めとは限らない不定値であることに注意!!このような書き方は大きなバグの原因となりえる
最後に10行目の(src - stp)の部分です。これはポインタ同士の引算を行うと型が int 型になることを意味しています。