【第1部】C言語(K&R検証)編
0029.文字列をコピーする
今項のサンプルは、char型ポインタを使って、文字列をコピーするサンプルです。
ソース紹介
CPPファイルに記述
#include <iostream>
#include <cstdio>
using namespace std;
/*
文字列をtからsにコピーする(配列添え字版)
*/
void strcpy2(char* s,const char* t) {
int i = 0;
while ((s[i] = t[i]) != '\0') {
i++;
}
}
/*
strcpy2のテスト
*/
int main()
{
char buff[100];
strcpy2(buff, "hello");
cout << buff << endl;
return 0;
}
出力
サンプル説明
K&Rではこのサンプルは
strcpy()関数として紹介されています。
しかし
VS2019で実装した場合
標準ライブラリのstrcpy()関数がデフォルトで
見えちゃってるためにエラーになります。
なので
strcpy2()関数と別名で実装しました。
また、コピー元は
constを付けないとエラーになります。これは
セキュリティ強化の観点です。
このように
引数を配列ではなくポインタを使う場合、いろんな場所で
K&Rの時代と変わってきた部分があります。
もう一つ、このサンプルには重要なポイントがあります。
呼び出し側
main()関数を見てください。
とあります
コピー元に
"hello"と記載されています。
これは
C/C++の
文字列リテラル(つまり " と " にはさまれた記述)は
その先頭のポインタをあらわすという文法があるからです。
ですから
という記述が可能です(あんまり意味はないですが)。これは、文字
cをあらわします。
続いて
ポインタ版の
strcpy2()関数を紹介します。
ソース紹介
CPPファイルに記述
/*
文字列をtからsにコピーする(ポインタ版)
*/
void strcpy2(char* s,const char* t) {
while ((*s = *t) != '\0') {
s++;
t++;
}
}
サンプル説明
このバージョンは
ポインタは変数であるという特徴を生かしています。
変数なので
加算が可能です。また添え字の
i は、もう必要ではありません。
さらに、もう一歩進んだバージョンを紹介します。
ソース紹介
CPPファイルに記述
/*
文字列をtからsにコピーする(ポインタ版2)
*/
void strcpy2(char* s,const char* t) {
while ((*s++ = *t++) != '\0')
;
}
サンプル説明
このバージョンは
後置インクリメントを使うことで、コード行数を減らしています。
さらにさらに、
C/C++では
while文などの条件式では
真か偽かのみが問われます。そして、
偽は0に評価される値で、真は偽でないものという定義があります。ここは
JavaやC#と大きく違うところです。(JavaやC#は条件式は
boolもしくは
booleanでなければならない)
ですので、以下の様に書けます。
CPPファイルに記述
/*
文字列をtからsにコピーする(ポインタ版3)
*/
void strcpy2(char* s,const char* t) {
while (*s++ = *t++)
;
}
ちょっとびっくりですよね。
K&Rでの記述
元になったのは
第5章:ポインタと配列に記述されています。
文字ポインタと関数の説明のところです。