C++第3版 20章 練習問題解答

目次へ戻る

20.1

string Cat1(string s,string t){return s+ '.' + t;}
void Cat2(const char* s,const char* t,char* o){sprintf(o,"%s.%s",s,t);}
char* Cat3(const char* s,const char* t)
    {static char r[80]; sprintf(r,"%s.%s",s,t); return r;}
char* Cat4(const char* s,const char* t)
    {char* p = (char*)malloc(strlen(s)+strlen(t)+2);
    sprintf(p,"%s.%s",s,t); return p;}
Cat1 は string を使ったもの、Cat2,Cat3,Cat4 は char* を使ったものである。 比較基準としては、メモリ管理と実行効率であろうか。効率はどれも変わらないと思う。 メモリ管理については、Cat1 は問題無い。 Cat2 は、確保場所をユーザが用意する必要がある。 Cat3 は、関数側で確保するが、同時には使えないし、他に比べてメモリ効率が悪い。 (起動中ずっと確保し続けるので。)また、バッファあふれの可能性もある。 Cat4 は、関数側で確保するが、ユーザ側でリリースする必要があり、面倒である。

20.2

パス。

20.3

パス。

20.4

パス。

20.5

#include <string>
#include <algorithm>
#include <iostream>
using namespace std;

namespace std {
template <>
class back_insert_iterator<string> {
    string*     m_str;
public:
    back_insert_iterator(string& s) : m_str(&s) {}
	back_insert_iterator& operator*(){return *this;}
	back_insert_iterator& operator++(){return *this;}
	back_insert_iterator  operator++(int){return *this;}
	back_insert_iterator& operator=(char c){*m_str += c; return *this;}
};
}
int main()
{
    char*   p = "abc";
    string  s;
    copy(p,p+3,back_inserter(s));
    cout << s << endl;
}

20.6

パス。

20.7

パス。

20.8

パス。

20.9

パス。

20.10

パス。

20.11

isalpha は char でも正しく動くと思うのだが。問題の意図が良く分からない。

20.12

パス。

20.13

etime.h は8.6を参照のこと。
#include <string>
#include <iostream>
#include "etime.h"
using namespace std;

int main()
{
    string      s,      t = "test data for copy";
    char        p[80], *q = "test data for copy";
    CETime      e;
    int         i, n = 1000000;
    e.Reset();
    for (i=0;i<n;++i) s = t;
    cout << e.Sec() << endl;
    e.Reset();
    for (i=0;i<n;++i) strcpy(p,q);
    cout << e.Sec() << endl;
}
結果は、string の方が数倍遅い。これは、意外であった。 ちなみに、文字列の長さを長くすると、string のコピーは変わらないが、 strcpy は遅くなる。

20.14

etime.h は8.6を参照のこと。
#include <string>
#include <iostream>
#include "etime.h"
using namespace std;

string complate_name(const string& s,const string& t)
{
    string  r = s;
    r += ' ';
    r += t;
    return r;
}
string complate_name2(const string& s,const string& t)
{
    string  r = t;
    r.insert(r.begin(),' ');
    r.insert(0,s);
    return r;
}
string complate_name3(const string& s,const string& t)
{
    return s + ' ' + t;
}
struct _String {
    allocator<char> a;
    char*           ptr;
    size_t          len,res;
    _String(const char* p,int l,const char* q,int m){
        len = res = l+m+1; ptr = new char[len+1];
        *ptr = 0; ++ptr; memcpy(ptr,p,l);
        ptr[l] = ' '; memcpy(ptr+l+1,q,m);}
};
string complate_name4(const string& s,const string& t)
{
    _String     r(s.data(),s.size(),t.data(),t.size());
    return *(string*)(&r);
}
int main()
{
    CETime      e;
    string      s = "Mike", t = "Smith";
    int         i, n = 100000;
    e.Reset();
    for (i=0;i<n;++i) complate_name (s,t);
    cout << e.Sec() << endl;
    e.Reset();
    for (i=0;i<n;++i) complate_name2(s,t);
    cout << e.Sec() << endl;
    e.Reset();
    for (i=0;i<n;++i) complate_name3(s,t);
    cout << e.Sec() << endl;
    e.Reset();
    for (i=0;i<n;++i) complate_name4(s,t);
    cout << e.Sec() << endl;
}
「考えられる限り最高速」ということで complate_name4 を作ったが、 注意して欲しいのは、VC++5 でしか動かないということである。 スピードは、complate_name より倍以上速くなっている。 但し、完全に正しいかどうかの自信はない。

20.15

パス。

20.16

#include <string>
#include <sstream>
#include <iostream>
using namespace std;

string itos(int i)
{
    stringstream    ss;
    ss << i;
    return ss.str();
}
int main()
{
    cout << itos(123) << endl;
}

前章目次次章