C++第3版 11章 練習問題解答
-
11.1 , 11.2 , 11.3 ,
11.4 , 11.5 , 11.6 ,
11.7 , 11.8 , 11.9 ,
11.10 , 11.11 , 11.12 ,
11.13 , 11.14 , 11.15 ,
11.16 , 11.17 , 11.18 ,
11.19 , 11.20 , 11.21 ,
11.22
目次へ戻る
問題の意図がよくわからない。
#include <iostream>
using namespace std;
struct X {
int i;
X(int){cout << " X::X(int)\n";}
X operator+(int){cout << " X::oper+(int)\n"; return *this;}
};
struct Y {
int i;
Y(X){cout << " Y::Y(X)\n";}
Y operator+(X){cout << " Y::oper+(X)\n"; return *this;}
operator int(){cout << " Y::oper int()\n"; return 0;}
};
X operator*(X x,Y){cout << " oper*(X,Y)\n"; return x;}
int f(X){cout << " f(X)\n"; return 0;}
X x = 1;
Y y = x;
int i = 2;
int main()
{
cout << "i+10\n"; i+10;
cout << "y+10\n"; y+X(10);
cout << "y+10*y\n"; y+X(10*static_cast<int>(y));
cout << "x+y+i\n"; x+y+i;
cout << "x*x+i\n"; x*x+i;
cout << "f(7)\n"; f(7);
cout << "f(y)\n"; f(X(y));
cout << "y+y\n"; y+y;
cout << "106+y\n"; 106+y;
}
|
パス。
class INT {
int i;
public:
INT(int i0 = 0) : i(i0) {}
operator int(){return i;}
int operator+=(int i0){return i+=i0;}
// -= 等は省略
};
struct X {X(int){}};
void f(int i){}
void g(int& i){}
void h(X x){}
int main()
{
int i;
INT j, k = 2;
j += 4 * k;
f(i);
f(j);
g(i);
g(j); // エラー
h(i);
h(j); // エラー
}
|
「int と全く同じように動作する」とは、どこまで言うのだろう?
まさしく四則演算しか定義しなかったので、無理矢理結果を見ている。
#include <iostream>
using namespace std;
class RINT {
friend int operator+(const RINT& r,const RINT& s);
friend int operator-(const RINT& r,const RINT& s);
friend int operator*(const RINT& r,const RINT& s);
friend int operator/(const RINT& r,const RINT& s);
friend int operator%(const RINT& r,const RINT& s);
int i;
public:
RINT(int i0 = 0) : i(i0) {}
int operator+(){return i;}
int operator-(){return -i;}
};
int operator+(const RINT& r,const RINT& s){return r.i+s.i;}
int operator-(const RINT& r,const RINT& s){return r.i-s.i;}
int operator*(const RINT& r,const RINT& s){return r.i*s.i;}
int operator/(const RINT& r,const RINT& s){return r.i/s.i;}
int operator%(const RINT& r,const RINT& s){return r.i%s.i;}
int main()
{
RINT j, k = 2;
j = 1 + 4 * -k;
cout << *reinterpret_cast<int*>(&j) << endl;
}
|
前問で int を __int64 にする。(VC の場合)
正確に言えば任意の精度ではない。(size_t の桁数しかだめ)
また、効率は重視していないし、問題もあるかもしれない。
vector でなく valarray でもよかったかも。
#include <cassert>
#include <vector>
#include <iostream>
using namespace std;
class CInt {
typedef vector<char> VType;
VType m_data; // 1要素1桁
bool m_sign; // 符号が正
int GetAt(int n)const{return n < m_data.size() ? m_data[n] : 0;}
void SetAt(int n,int i)
{if (n >= m_data.size()) m_data.resize(n+1); m_data[n] = i;}
void Trim(){while (m_data.size() > 0 && m_data.back() == 0)
m_data.pop_back();}
void Reset(int i);
void Add(const CInt& i,int pos = 0,int r = 1);
void Sub(const CInt& i);
public:
CInt(int i = 0){Reset(i);}
ostream& Print(ostream& o)const;
CInt operator-()const
{CInt i = *this; i.m_sign = !i.m_sign; return i;}
CInt& operator++(){*this += 1; return *this;}
CInt& operator--(){*this -= 1; return *this;}
CInt operator++(int){CInt i = *this; *this += 1; return i;}
CInt operator--(int){CInt i = *this; *this -= 1; return i;}
CInt operator+(const CInt& i)const;
CInt operator-(const CInt& i)const;
CInt operator*(const CInt& i)const;
CInt operator/(const CInt& i)const;
CInt& operator+=(const CInt& i){return *this = *this + i;}
CInt& operator-=(const CInt& i){return *this = *this - i;}
CInt& operator*=(const CInt& i){return *this = *this * i;}
CInt& operator/=(const CInt& i){return *this = *this / i;}
CInt& operator*=(int i);
bool operator==(const CInt& i)const;
bool operator<(const CInt& i)const;
bool operator>(const CInt& i)const{return i < *this;}
bool operator<=(const CInt& i)const{return !(i < *this);}
bool operator>=(const CInt& i)const{return !(*this < i);}
};
void CInt::Reset(int i)
{
if (!(m_sign = i >= 0)) i = -i;
m_data.clear();
while (i) {
m_data.push_back(i%10);
i /= 10;
}
}
void CInt::Add(const CInt& i,int pos,int r)
{
int j, n = 0, m = i.m_data.size();
for (j=0;j<m;++j) {
n += GetAt(j+pos) + i.m_data[j] * r;
SetAt(j+pos,n%10);
n /= 10;
}
j += pos;
while (n) {
n += GetAt(j);
SetAt(j++,n%10);
n /= 10;
}
}
void CInt::Sub(const CInt& i)
{
int j,k, n = 0, l = m_data.size(), m = i.m_data.size();
assert(l >= m);
for (j=0;j<m;++j) {
k = n + m_data[j] - i.m_data[j];
n = 0;
while (k < 0) {k += 10; --n;}
m_data[j] = k;
}
while (n && j < l) {
k = n + m_data[j];
n = 0;
while (k < 0) {k += 10; --n;}
m_data[j++] = k;
}
assert(n == 0);
Trim();
}
ostream& CInt::Print(ostream& o)const
{
VType::const_reverse_iterator it;
if (!m_data.size())
return o << '0';
if (!m_sign) o << '-';
for (it=m_data.rbegin();it!=m_data.rend();++it)
o << static_cast<int>(*it);
return o;
}
CInt CInt::operator+(const CInt& i)const
{
if (m_sign != i.m_sign)
return m_sign ? *this - -i : i - -*this;
if (*this < i) return i + *this;
CInt j = *this;
j.Add(i);
return j;
}
CInt CInt::operator-(const CInt& i)const
{
if (!m_sign && !i.m_sign) return -i - -*this;
else if (!m_sign) return -(-*this + i);
else if (!i.m_sign) return *this + -i;
else if (*this < i) return -(i - *this);
CInt j = *this;
j.Sub(i);
return j;
}
CInt CInt::operator*(const CInt& i)const
{
CInt r;
int j, m = i.m_data.size();
for (j=0;j<m;++j)
r.Add(*this,j,i.m_data[j]);
r.m_sign = m_sign == i.m_sign;
return r;
}
CInt CInt::operator/(const CInt& i)const
{
CInt r,d;
int j,k, m = m_data.size();
for (j=m-1;j>=0;--j) {
d.m_data.insert(d.m_data.begin(),m_data[j]);
k = 0;
while (d >= i) {d.Sub(i); ++k;}
r.m_data.insert(r.m_data.begin(),k);
}
r.Trim();
r.m_sign = m_sign == i.m_sign;
return r;
}
CInt& CInt::operator*=(int i)
{
if (i < 0) {i = -i; m_sign = !m_sign;}
int j, n = 0, m = m_data.size();
for (j=0;j<m;++j) {
n += m_data[j] * i;
m_data[j] = n%10;
n /= 10;
}
while (n) {
SetAt(j++,n%10);
n /= 10;
}
return *this;
}
bool CInt::operator==(const CInt& i)const
{
int j, m = m_data.size();
if (m_sign != i.m_sign || m != i.m_data.size())
return false;
for (j=0;j<m;++j)
if (m_data[j] != i.m_data[j]) return false;
return true;
}
bool CInt::operator<(const CInt& i)const
{
if (!m_sign && !i.m_sign) return -i < -*this;
else if (!m_sign) return true;
else if (!i.m_sign) return false;
int j,k, m = m_data.size(), m2 = i.m_data.size();
if (m < m2) return true;
else if (m > m2) return false;
for (j=m-1;j>=0;--j)
if ((k = m_data[j] - i.m_data[j])) return k < 0;
return false;
}
ostream& operator<<(ostream& o,const CInt& i){return i.Print(o);}
int main(int argc,char** argv)
{
CInt i = 1, ii = 1;
int j,n = argc > 1 ? atoi(argv[1]) : 1000;
for (j=2;j<=n;++j) i *= j;
cout << i << endl;
for (j=2;j<=n;++j) ii *= CInt(j);
cout << i-ii << endl;
}
|
String を作らなかったのでパス。
String を作らなかったのでパス。
String を作らなかったのでパス。
String を作らなかったのでパス。
パス。
パス。
#include <iostream>
using namespace std;
class INT {
int i;
public:
INT(int i0 = 0) : i(i0) {}
int operator*(int i0){return i*(i0+2);}
operator int(){return i;}
};
#define int INT
int main()
{
// + と * の優先順位を逆にしてみた
int i = 2, j = 3, k = 4;
if (i*j+k == 2*(3+4)) cout << "ok 1\n";
if (i+j*k == (2+3)*4) cout << "ok 2\n";
}
|
パス。
#include <valarray>
#include <iostream>
using namespace std;
struct Vec4 : valarray<float> {
Vec4(float f[]) : valarray<float>(f,4) {}
};
ostream& operator<<(ostream& o,const valarray<float>& v)
{
return o << "(" << v[0] << "," << v[1] << ","
<< v[2] << "," << v[3] << ")";
}
int main()
{
float f1[] = {1,2,3,4}, f2[] = {2,1,4,3};
Vec4 v1(f1), v2(f2);
cout << v1+v2 << endl;
v1 += v2;
cout << v1 << endl;
}
|
パス。
パス。
パス。
#include <iostream>
using namespace std;
template <typename T>
class Ptr_to_T {
T* p; // 現在
T* array; // 先頭
int size; // サイズ
void check(T* pp)
{if (pp < array || pp >= array+size) throw out_of_range("");}
public:
Ptr_to_T(T* p0,T* v,int s) : p(p0), array(v), size(s) {}
Ptr_to_T(T* p0) : p(p0), array(p0), size(1) {}
Ptr_to_T& operator++(){++p; return *this;}
Ptr_to_T operator++(int){Ptr_to_T t = *this; ++*this; return t;}
Ptr_to_T& operator--(){--p; return *this;}
Ptr_to_T operator--(int){Ptr_to_T t = *this; --*this; return t;}
bool operator==(const Ptr_to_T& t){return p == t.p;}
T& operator*(){check(p); return *p;}
};
int main()
{
int a[10];
Ptr_to_T<int> p(&a[0],a,10);
if (++p == &a[1]) cout << "ok 1\n";
if (p-- == &a[1]) cout << "ok 2\n";
try {--p;} catch (out_of_range) {cout << "not use!\n";}
try {*p;} catch (out_of_range) {cout << "out\n";}
}
|
struct S {int x,y;};
struct T {char* p; char* q;};
struct C : S,T {};
int main()
{
C c;
c.x = 0;
c.p = 0;
}
|
#include <cmath>
#include <iostream>
using namespace std;
class Index {
double d;
friend double mypow(double d,Index i);
public:
class Proxy {
friend Index;
friend double operator*(double d,const Proxy& p);
Index& i;
Proxy(Index& i0) : i(i0) {}
};
Index(double d0 = 0) : d(d0) {}
Proxy operator*(){return Proxy(*this);}
};
double mypow(double d,Index i){return pow(d,i.d);}
double operator*(double d,const Index::Proxy& p)
{return mypow(d,p.i);}
int main()
{
Index i = 3;
cout << 2 ** i << endl;
}
|
パス。
前章へ
目次へ
次章へ