c++ 中的函数参数的值传递

写 c++ 程序的时候要特别小心这种函数参数的传递。稍不注意就会出现问题。

下面看一段代码并思考,为什么这里的 double grade(double, double, const std::vector<double>&);的第三个参数是std::vector<double>&,而 double median(std::vector<double>);的参数是 std::vector<double>.


#include <iostream>
#include <sstream>
#include <iomanip>
#include <ios>
#include <vector>
#include <algorithm>
#include <stdexcept>
using std::endl;

double grade(double, double, double);
double grade(double, double, const std::vector<double>&);
double median(std::vector<double>);

int main()
{

	std::cout << "Please enter your first name." << endl;
	std::string name{};
	std::cin >> name;
	std::cout << "Hello " << name << " !" << endl;

	std::cout << "Please enter your middle and final exam grades: ";
	double middle = 0, final = 0;
	std::cin >> middle >> final;

	std::cout << "Enter all your homework grades"
		"followed by end-of-file: ";

	std::vector<double> homework;

	double x;
	while (std::cin >> x)
	{
		homework.push_back(x);
	}
	printf("homework is %p\n", &homework);
	std::streamsize prec = std::cout.precision();

	std::cout << "Your final grade is " << std::setprecision(3)
		<< grade(middle, final, homework)
		<< std::setprecision(prec) << std::endl;
	return 0;
}


double grade(double median, double final, const std::vector<double>& hw) {
	printf("hw is %p\n", &hw);
	// 在 main() 里面调用这个函数的时候,传入的是 main 中的 homework 的 引用,并不是对其的一个复制拷贝,
	// 所以,这里的 hw 就是 main 里面的 homework,这里没毛病。
	double mm = ::median(hw);

	double rg = grade(median, final,mm);

	return rg;
}


double median(std::vector<double> vec) {

	// median 是被 grade(double,double,vector)调用的,这个 vec 是对其传入的 hw 的一个拷贝,也就是说,这个 vec 与 hw 是两个不同的对象。
	// 另外 hw 是 const 没事,t它只是赋值给vec,不会让vec也变成 const
	printf("vec is %p\n", &vec);
	std::vector<double>::size_type len = vec.size();

	if (len == 0)
	{
		throw std::domain_error("vector is empty...");
	}
	std::sort(vec.begin(), vec.end());
	int mp = len / 2;
	double number;
	if (len % 2 == 0)
	{
		// even length
		number = 0.5 * (vec[mp] + vec[mp - 1]);
	}
	else {
		// odd length
		number = vec[mp];
	}

	return number;

}

double grade(double middle, double final, double homework) {

	return 0.2 * middle + 0.4 * final + 0.4 * homework;
}

首先函数的调用栈是 main() -> grade() -> median() . 函数实参是在main() 里面创建的 homework对象。在调用 grade 函数的时候,这里传入的是一个常量引用,所以这里不会去创建对象,并且保证grade函数不会去修改main中创建的homework对象,而 median()函数的参数类型就是std::vector<double>,所以这里会进行一个拷贝赋值,也就是创建了一个新的对象。所以在 median里面去进行排序,不会影响到原来的homework对象,因为 hwvec是两个不同的对象。

看一下输出就明白了:

homework is 0000007EE0F7F7A8
hw is 0000007EE0F7F7A8
vec is 0000007EE0F7F688

可以看到 homeworkhw是同一个地址,而 vec是一个新的地址。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值