数据结构、算法与应用(C++语言描述) 练习题(1-18)

本文探讨了C++中的函数参数传递,指出传值参数在交换函数中的局限性,并介绍了引用参数的使用以实现值的正确交换。此外,详细阐述了模板函数如计数、填充、内积、 iota 和排序检查等,以及异常处理在函数调用中的应用,包括自定义异常类和错误检查。最后,展示了如何在货币类中进行加法、减法、乘法、除法操作及其异常处理,强调了数值范围和精度问题的重要性。
摘要由CSDN通过智能技术生成
  1. 在程序1-7的交换函数中,形参x、y实际上是传值参数,在运行时,交换函数执行前,把实参的值复制给形参,当函数运行结束时,形参类型的析构函数负责释放形式参数,而形参的值不会复制到对应的实参中,故程序1-7的交换函数不能将形参x和y所对应的实参的值交换。 若要使实参的值能够得到交换,将传值参数修改为引用参数即可void swap(int &x, int &y)

template<typename T>
int count(T a[], int n, const T& value)
{
	int cnt = 0;
	for (int i = 0; i < n; i++)
		if (a[i] == value)
			cnt++;
	return cnt;
}
  1. template<typename T>
    void fill(T a[], int start, int end, const T& value)
    {
    	for (int i = start; i < end; i++)
    		a[i] = value;
    	return;
    }
    
  2. template<typename T>
    T inner_product(T a[], T b[], int n)
    {
    	T sum = 0;
    	for (int i = 0; i < n; i++)
    		sum += a[i] * b[i];
    	return sum;
    }
    
  3. template<typename T>
    void iota(T a[], int n, const T& value)
    {
    	for (int i = 0; i < n; i++)
    		a[i] = value + i;
    	return;
    }
    
template<typename T>
bool is_sorted(T a[], int n)
{
	for (int i = 1; i < n; i++)
		if (a[i] < a[i - 1])
			return false;
	return true;
}
template<typename T>
int mismatch(T a[], T b[], int n)
{
	for (int i = 0; i < n; i++)
		if (a[i] != b[i])
			return i;
	return n;  //return n if no such i.
}
  1. 不是,因为一个函数的签名是由这个函数的形参类型以及形参个数确定的,例题中的两个函数具有相同的形参类型以及形参个数(int, int, int),仅仅是返回值不同,不能构成函数重载。

  2. (1)调用了1-1

    (2)调用了1-2

    (3)会报错,调用函数的签名与1-1,1-2的签名不匹配,而且因为从intfloat和从floatint的类型转换都是可能发生的,C++无法确定需要调用哪个函数,故而给出编译错误。

    (4)会报错,实参类型为double,因为从doubleint和从doublefloat的类型转换都是可能发生的,C++无法确定需要调用哪个函数,故而给出编译错误。

  3. #include<iostream>
    using namespace std;
    
    int abc(int a, int b, int c)
    {
    	if (a < 0 && b < 0 && c < 0)
    		throw 1;
    	else if (!a && !b && !c)
    		throw 2;
    	return a + b * c;
    }
    
    int main()
    {
    	int a = -1, b = -2, c = -3;
    	cout << "The parameters to abc were " << a << ", "
    		<< b << ", " << c << endl;
    	try { cout << abc(a, b, c) << endl; }
    	catch (int e)
    	{
    		if (e == 1)
    			cout << "All parameters < 0.\n";
    		else
    			cout << "All parameters = 0.\n";
    	}
    
    	a = 0, b = 0, c = 0;
    	cout << "The parameters to abc were " << a << ", "
    		<< b << ", " << c << endl;
    	try { cout << abc(a, b, c) << endl; }
    	catch (int e)
    	{
    		if (e == 1)
    			cout << "All parameters < 0.\n";
    		else
    			cout << "All parameters = 0.\n";
    	}
    
    	a = 1, b = -2, c = 0;
    	cout << "The parameters to abc were " << a << ", "
    		<< b << ", " << c << endl;
    	try { cout << abc(a, b, c) << endl; }
    	catch (int e)
    	{
    		if (e == 1)
    			cout << "All parameters < 0.\n";
    		else
    			cout << "All parameters = 0.\n";
    		return 1;
    	}
    	cout << "No Exception.\n";
    	return 0;
    }
    
  4. #include<iostream>
    using namespace std;
    
    template<typename T>
    int count(T a[], int n, const T& value)
    {
    	if (n < 1)
    		throw "The parameter n should be >= 1";
    	int cnt = 0;
    	for (int i = 0; i < n; i++)
    		if (a[i] == value)
    			cnt++;
    	return cnt;
    }
    
    int main()
    {
    	const int N = 10;
    	int a[N] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    	int value = 5;
    	try { cout << count(a, 0, value) << endl; }
    	catch (const char* e)
    	{
    		cout << "The parameter n < 1.\n";
    		cout << "An exception has been thrown.\n";
    		cout << e << endl;
    		return 1;
    	}
    	return 0;
    }
    
  5. template<typename T>
    void make2dArray(T**& x, int numberOfRows, T rowSize[])
    {
    	x = new T * [numberOfRows];
    	for (int i = 0; i < numberOfRows; i++)
    		x[i] = new T[rowSize[i]];
    }
    
  6. template<typename T>
    void changeLength1D(T*& x, int oldLength, int newLength)
    {
    	if (newLength < 0)
    		throw "newLength must be >= 0";
    
    	T* t = new T[oldLength];
    	int len = min(oldLength, newLength);
    	copy(x, x + len, t);                      //copy()函数拷贝x的len个字符到t中(从索引0开始)。
    
    	delete[] x;
    	x = t;
    }
    
  7. template<typename T>
    void changeLength2D(T**& x, int oldRows, int oldColums, int newRows, int newColums)
    {
    	if (newRows || newColums < 0)
    		throw "All parameters mush be >= 0";
    
    	T** t = new T * [newRows];
    	for (int i = 0; i < newRows; i++)
    		ti] = new T[newColums];
    
    	int rows = min(oldRows, newRows);
    	int colums = min(oldColums, newColums);
    	for (int i = 0; i < rows; i++)
    		copy(x, x + colums, t[i]);
    
    	for (int i = 0; i < oldRows; i++)
    		delete x[i];
    	delete[]x;
    	x = t;
    }
    
    1. max = (2^32-1).99,min = -max

    2. max = (2^31-1).99,min = - max

    3. 这题没不是很懂,直接复制了官网的答案,后面再看看

      To avoid an error in the conversion, the result (a1 and a2) should not exceed MAX_VALUE = 2^{32}-1. Therefore, the dollar amount should not exceed MAX_VALUE / 100. Even though the dollar amount may not exceed MAX_VALUE / 100, the method may not give the correct result. To assure a correct result, the sum of the dollar amounts should not exceed MAX_VALUE / 100.
      
  8. class illegalParameterValue
    {
    public:
    	illegalParameterValue(const char* theMessage = "Illegal parameter value") :message(theMessage) {}
    	void outputMessage() const { cout << message << std::endl; }
    private:
    	std::string message;
    };
    
    enum signType { plus, minus };
    class currency
    {
    public:
    	currency(signType theSign = plus, unsigned long theDollars = 0, unsigned int theCents = 0)
    	{
    		setValue(plus, theDollars, theCents);
    	}
    
    	~currency() {}
    	void setValue(signType theSign, unsigned long theDollars, unsigned int theCents)
    	{
    		if (theCents > 99)
    			throw illegalParameterValue("Cents should be < 100.");
    
    		sign = theSign;
    		dollars = theDollars;
    		cents = theCents;
    	}
    
    	void setValue(double theAmount)
    	{
    		if (theAmount < 0)
    		{
    			theAmount = -theAmount;
    			sign = minus;
    		}
    
    		dollars = (unsigned long)theAmount;
    		cents = (unsigned int)((theAmount + 0.001 - dollars) * 100);
    	}
    	signType getSign() const { return sign; }
    	unsigned long getDollars() const { return dollars; }
    	unsigned int getCents() const { return cents; }
    
    	currency add(const currency& x)const
    	{
    		long a1, a2, a3;
    		currency result;
    		a1 = dollars * 100 + cents;
    		if (sign == minus)a1 = -a1;
    		a2 = x.dollars * 100 + x.cents;
    		if (x.sign == minus) a2 = -a2;
    		a3 = a1 + a2;
    
    		signType theSign = plus;
    		if (a3 < 0)
    		{
    			a3 = -3;
    			theSign = minus;
    		}
    		result.setValue(theSign, a3 / 100, a3 - a3 / 100 * 100);
    		return result;
    	}
    	currency& increment(const currency& x)
    	{
    		*this = add(x);
    		return *this;
    	}
    
    	void output() const
    	{
    		if (sign == minus)cout << '-';
    		cout << '$' << dollars << '.';
    		if (cents < 10)cout << '0';
    		cout << cents;
    	}
    
    	// (1)
    	void input()
    	{
    		double theAmount;
    		cin >> theAmount;
    		setValue(theAmount);
    	}
    
    	// (2)
    	currency subtract(const currency& x)
    	{
    		long a1, a2, a3;
    		currency result;
    		a1 = dollars * 100 + cents;
    		if (sign == minus)a1 = -a1;
    		a2 = x.dollars * 100 + x.cents;
    		if (x.sign == minus) a2 = -a2;
    		a3 = a1 - a2;
    
    		signType theSign = plus;
    		if (a3 < 0)
    		{
    			a3 = -3;
    			theSign = minus;
    		}
    		result.setValue(theSign, a3 / 100, a3 - a3 / 100 * 100);
    		return result;
    	}
    	// (3)
    	currency percent(double x)
    	{
    		long a1 = dollars * 100 + cents;
    		if (sign == minus) a1 = -a1;
    		currency result;
    		long a2 = (long)(a1 * x / 100);
    		result.setValue(sign, a2 / 100, a2 - a2 / 100 * 100);
    		return result;
    	}
    	//(4)
    	currency multiply(double x)
    	{
    		return percent(x * 100);
    	}
    	//(5)
    	currency divide(double x)
    	{
    		long a1 = dollars * 100 + cents;
    		if (sign == minus) a1 = -a1;
    		long a2 = (long)(a1 / x);
    		currency result;
    		result.setValue(sign, a2 / 100, a2 - a2 / 100 * 100);
    		return result;
    	}
    private:
    	signType sign;
    	unsigned long dollars;
    	unsigned int cents;
    };
    
  9. class currency
    {
    public:
    	currency(signType theSign = plus, unsigned long theDollars = 0,
    		unsigned int theCents = 0)
    	{
    		setValue(plus, theDollars, theCents);
    	}
    
    	~currency() {}
    	void setValue(signType theSign, unsigned long theDollars, unsigned int theCents)
    	{
    		if (theCents > 99)
    			throw illegalParameterValue("Cents should be < 100.");
    
    		amount = theDollars * 100 + theCents;
    		if (theSign == minus) amount = -amount;
    	}
    
    	void setValue(double theAmount)
    	{
    		if (theAmount < 0)
    			amount = (long)(theAmount - 0.001) * 100;
    		else
    			amount = (long)(theAmount + 0.001) * 100;
    	}
    	signType getSign() const { return amount < 0 ? minus : plus; }
    	unsigned long getDollars() const { return amount < 0 ? -amount / 100 : amount / 100; }
    	unsigned int getCents() const { return amount < 0 ? -amount - getDollars() * 100 : amount - getDollars() * 100; }
    
    	currency add(const currency& x)const
    	{
    		currency y;
    		y.amount = x.amount + amount;
    		return y;
    	}
    
    	currency& increment(const currency& x)
    	{
    		amount += x.amount;
    		return *this;
    	}
    	void output() const
    	{
    		long theAmount = amount;
    		if (theAmount < 0)
    		{
    			cout << '-';
    			theAmount = -theAmount;
    		}
    		long dollars = theAmount / 100;
    		cout << '$' << dollars << '.';
    		int cents = theAmount - dollars * 100;
    		if (cents < 10) cout << '0';
    		cout << cents;
    	}
    
    	// (1)
    	void input()
    	{
    		cout << "Enter the currency amount as a real number: ";
    		double theAmount;
    		cin >> theAmount;
    		setValue(theAmount);
    	}
    
    	// (2)
    	currency subtract(const currency& x)
    	{
    		currency y;
    		y.amount = amount - x.amount;
    		return y;
    	}
    	// (3)
    	currency percent(double x)
    	{
    		currency result;
    		result.amount = (long)(amount * x / 100);
    		return result;
    	}
    	//(4)
    	currency multiply(double x)
    	{
    		currency result;
    		result.amount = (long)(amount * x);
    		return result;
    	}
    	//(5)
    	currency divide(double x)
    	{
    		currency result;
    		result.amount = (long)(amount / x);
    		return result;
    	}
    private:
    	long amount;
    };
    
  10. class currency
    {
    public:
    	currency(signType theSign = plus, unsigned long theDollars = 0,
    		unsigned int theCents = 0)
    	{
    		setValue(plus, theDollars, theCents);
    	}
    
    	~currency() {}
    	void setValue(signType theSign, unsigned long theDollars, unsigned int theCents)
    	{
    		if (theCents > 99)
    			throw "Cents should be < 100.";
    
    		amount = theDollars * 100 + theCents;
    		if (theSign == minus) amount = -amount;
    	}
    
    	void operator = (int x)
    	{
    		amount = x;
    	}
    
    	void operator = (double x)
    	{
    		if (x < 0)
    			amount = (long)(x - 0.001) * 100;
    		else
    			amount = (long)(x + 0.001) * 100;
    	}
    	signType getSign() const { return amount < 0 ? minus : plus; }
    	unsigned long getDollars() const { return amount < 0 ? -amount / 100 : amount / 100; }
    	unsigned int getCents() const { return amount < 0 ? -amount - getDollars() * 100 : amount - getDollars() * 100; }
    
    	currency operator + (const currency& x)const
    	{
    		currency y;
    		y.amount = x.amount + amount;
    		return y;
    	}
    
    	currency& operator += (const currency& x)
    	{
    		amount += x.amount;
    		return *this;
    	}
    	void output(std::ostream& out)const
    	{
    		long theAmount = amount;
    		if (theAmount < 0)
    		{
    			out << '-';
    			theAmount = -theAmount;
    		}
    
    		long dollars = theAmount / 100;
    		cout << '$' << dollars << '.';
    		long cents = theAmount - dollars * 100;
    		if (cents < 10) out << '0';
    		out << cents;
    	}
    
    	friend std::ostream& operator << (std::ostream out, const currency& x)
    	{
    		x.output(out);
    		return out;
    	}
    
    	// (1)
    	friend std::istream& operator >> (std::istream& in, currency& x)
    	{
    		cout << "Enter the currency amount as a real number: ";
    		double theAmount;
    		in >> theAmount;
    		x = theAmount;
    		return in;
    	}
    
    	// (2)
    	currency operator -(const currency& x)
    	{
    		currency y;
    		y.amount = amount - x.amount;
    		return y;
    	}
    	// (3)
    	currency operator%(double x)
    	{
    		currency result;
    		result.amount = (long)(amount * x / 100);
    		return result;
    	}
    	//(4)
    	currency operator*(double x)
    	{
    		currency result;
    		result.amount = (long)(amount * x);
    		return result;
    	}
    	//(5)
    	currency operator/(double x)
    	{
    		currency result;
    		result.amount = (long)(amount / x);
    		return result;
    	}
    private:
    	long amount;
    };
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值