アフィリエイト広告を利用しています

広告

posted by fanblog

2017年09月29日

《その56》 cstringライブラリ(p.306)


strlen関数
------------------------------------
文字列処理を行うライブラリ関数は、ヘッダで提供されています。
strlen関数は、文字列の長さを求めるための関数です。

ヘッダ #include <cstring>
形式  size_t strlen(const char* s);
解説  s が指す文字列の長さ(ナル文字は含まない)を求める。
返却値 求めた文字列の長さを返す。
------------------------------------p.306

この関数の実現例として、

------------------------------------
#include <cstddef>
size_t strlen(const char* s)
{
size_t len = 0;

while (*s++)
len++;
return len;
}
------------------------------------p.306

というコードが示されています。
#include <cstddef> は、size_t型 の定義のためと思われます。

この strlen関数の働きを確認するために、次のような簡単なプログラムを作りました。

// プログラム【1】
#include <cstddef>
#include <iostream>
using namespace std;

size_t strlen(const char* s)
{
size_t len = 0;

while (*s++)
len++;
return len;
}

int main()
{
char s[255];
cout << "文字列を入力 : "; cin >> s;
cout << "文字列\"" << s << "\"の長さ … " << strlen(s) << '\n';
}

c08_001.png

予想通りの結果です。

ところが!! 上のプログラムの関数strlen を除去してしまっても、プログラムが問題なく動作することに気付いてしまいました!
#include <cstring> を記述してないので、
ライブラリ関数strlen は使えないと思っていた
のですが・・・。

// プログラム【2】
#include <cstddef>
#include <iostream>
using namespace std;
/*
size_t strlen(const char* s)
{
size_t len = 0;

while (*s++)
len++;
return len;
}
*/

int main()
{
char s[255];
cout << "文字列を入力 : "; cin >> s;
cout << "文字列\"" << s << "\"の長さ … " << strlen(s) << '\n';
}

このプログラムで、全く同じ結果が得られてしまいます。

ということは、「ライブラリ関数strlen」 と 「プログラムに記述したstrlen関数」 が同居していたことになります。
では、最初の プログラム【1】では、いったいどちらの strlen関数が使われたのか。

それを確かめるために プログラム【1】 の strlen関数内に
   cout << "こっちだよ!/n";
という行を加えてみました。

// プログラム【3】
#include <cstddef>
#include <iostream>
using namespace std;

size_t strlen(const char* s)
{
size_t len = 0;
cout << "こっちだよ!\n";
while (*s++)
len++;
return len;
}

int main()
{
char s[255];
cout << "文字列を入力 : "; cin >> s;
cout << "文字列\"" << s << "\"の長さ … " << strlen(s) << '\n';
}


コンパイルは無事に成功しました。ですが、実行してみたところ・・・

c08_002.png

プログラム【3】で加えた
   cout << "こっちだよ!/n";
には、文法上のミスはないので、二つのstrlen関数が競合してしまったのでしょうか。

それを確かめるため、こんどは、strlen関数の名前を srtlen2 に変更してみました。それ以外は一切変更していません。

// プログラム【4】
#include <cstddef>
#include <iostream>
using namespace std;

size_t strlen2(const char* s)
{
size_t len = 0;
cout << "こっちだよ!\n";
while (*s++)
len++;
return len;
}

int main()
{
char s[255];
cout << "文字列を入力 : "; cin >> s;
cout << "文字列\"" << s << "\"の長さ … " << strlen2(s) << '\n';
}

c08_003.png

strlen2関数はちゃんと働きました。

以上のことから、プログラム【3】では、二つの strlen関数が競合していることがはっきりしました。
では、なぜプログラム【1】のときは、競合せずに動作したのでしょうか。

プログラム【1】とプログラム【3】の違いは、
   cout << "こっちだよ!/n";
の有無だけです。

ここから先は、あくまでも想像ですが・・・

プログラム【1】では、「ライブラリ関数strlen」 と「プログラムに記述したstrlen関数」 は、外から見て全く同じ動作をします。
一方、プログラム【3】では、「プログラムに記述したstrlen関数」が、「こっちだよ!」というメッセージを出力するので、二つのstrlen関数の動作が異なります。
それが、【1】が許されて【3】が許されない理由ではないでしょうか。
引数も返却値も同じなので、多重定義は許されないはずですが、「働きも同じなら、まあいいか」ということですかね。

長くなってしまったので、コードは書きませんが、
プログラム【1】のときに、「ライブラリ関数strlen」 と「プログラムに記述したstrlen関数」の どちらが使われたのかを調べてみました。
外から見た動作を変えるとプログラムが停止してしまうため、入出力のコードを書き加えることはできません。
なので、「プログラムに記述したstrlen関数」の中に for文で時間稼ぎのコードを入れてみたところ、プログラム【1】の動作が極端に遅くなりました。

プログラム【1】では、「ライブラリ関数strlen」ではなく、「プログラムに記述したstrlen関数」が使われたようです。



新版 明解C 入門編 (明解シリーズ)

新品価格
¥2,916から
(2017/8/30 21:02時点)









--
この記事へのコメント
コメントを書く

お名前:

メールアドレス:


ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバックURL
https://fanblogs.jp/tb/6754259
※ブログオーナーが承認したトラックバックのみ表示されます。

この記事へのトラックバック

 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


検索
<< 2018年08月 >>
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
プロフィール
こうすけさんの画像
こうすけ

 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


×

この広告は30日以上新しい記事の更新がないブログに表示されております。