4135人加入学习
(13人评价)
C++编程系列 第二季函数和类

制作于2018.4.2

价格 免费
//自写
cout << "请输入你喜爱的游戏,并给它们评分,分数为0-10分之间的小数" << endl;
	string gameName[5]{ "","","","","" };
	float gameScore[5]{ 0.0f,0.0f,0.0f,0.0f,0.0f };
	for (int i = 0; i < 5; i++)
	{
		cout << "请输入游戏名称:";
		cin >> gameName[i];
		cout << "请输入游戏评分:";
		cin >> gameScore[i];
	}
	for (int i = 0; i < 5 - 1; i++)
	{
		for (int j = 0; j < 5 - i - 1; j++)
		{
			if (gameScore[j] < gameScore[j + 1])
			{
				float temp1 = gameScore[j];
				gameScore[j] = gameScore[j + 1];
				gameScore[j + 1] = temp1;

				string temp2 = gameName[j];
				gameName[j] = gameName[j + 1];
				gameName[j + 1] = temp2;
			}
		}
	}
	for (int i = 0; i < 5; i++)
	{
		cout << (i + 1) << " : " << gameName[i] << "(" << gameScore[i] << ")" << endl;
	}

老师写的:

#include "pch.h"
#include <iostream>
#include <string>
using namespace std;

struct Game
{
	string gameName;
	float gameScore;
};

int main()
{
	const int size = 5;
	Game games[size] = {};

	cout << "请输入5个你喜爱的游戏的名称,并给他们评分,(分数为0-10之间的小数)" << endl;
	for (int i = 0; i < size; i++)
	{
		cout << "请输入游戏名称:";
		cin >> games[i].gameName;
		cout << "请输入游戏评分:";
		cin >> games[i].gameScore;
	}

	for (int i = 0; i < size - 1; i++)
	{
		for (int j = i + 1; j < size; j++)
		{
			Game temp;
			if (games[i].gameScore < games[j].gameScore)
			{
				temp = games[i];
				games[i] = games[j];
				games[j] = temp;
			}
		}
	}

	for (int i = 0; i < size; i++)
	{
		cout << i + 1 << " : " << games[i].gameName << "(" << games[i].gameScore << ")" << endl;
	}
}

 

[展开全文]

降接口放在头文件中,并将实现放在源代码(.cpp)中。

class表示类

private(私有成员:只能通过公共成员访问的类成员(数据隐藏)

public:标识组成类的公共接口的类成员(抽象)。

[展开全文]

 

函数的基本概念

函数是一个i命名了的代码块,我们通过调用函数执行相应的代码。

每个C++程序都至少有一个函数,即主函数main(),所有简单的程序都可以定义其他额外的函数。

想要使用函数,必须完成以下工作:

1.提供函数定义

2.提供函数原型

3.调用函数

 

 

函数定义

一个典型的函数定义包括:

1.返回类型(returnType)

2.函数名(functionName)

3.形参列表(parameterList)

4.函数体(functionBody)

returnType functionName(parameterList)

{

functionBody;

}

 

 

函数定义

返回类型:一个函数可以选择生成一个值并将它返回给调用函数,或者不返回值。返回值时,returnType为这个值的数据类型。不返回值时,returnType为关键字void。

参数列表:参数列表包括函数参数的类型、顺序、数量。一个函数可以有0个或多个参数。

函数主体:函数主体定义了函数执行的任务。

 

 

 

 

#include <iostream>
#include <string>

using namespace std;

int main()
{
	return 0;
}

//没有返回值,没有参数
//函数名greet
//函数体为输出Hello语句
void greet()
{
	cout << "Hello!" << endl;
}

//返回值为int类型
//参数为2个int类型的值a,b
//函数名为sum
//函数体为求得两个参数的和,并返回一个int类型的数值
int sum(int a, int b)
{
	int res = a + b;
	return res;
}

 

[展开全文]

函数声明(函数原型)

函数原型描述了函数到编译器的接口,它将函数的信息告诉了编译器。

函数的名字也必须在使用之前声明。

函数的声明和函数的定义非常类似,唯一的区别是函数声明无需函数体,用一个分号替代即可。

returnType functionName(parameterList);

 

 

函数原型

函数原型可以确保:

1.编译器正确处理函数返回值。

2.编译器检查使用的参数数目是否正确。

3.编译器检查使用的参数类型是否正确。

 

 

函数调用

函数的调用完成两项工作:

1.用实参初始化函数对用的形参。

2.将控制权转移给被调函数。此时,主调函数的执行被暂时中断,被调函数开始执行。

return语句也能完成两项工作:

1.函数有返回值的话,则返回return语句中的值。

2.将控制权从被调函数转回主调函数。

 

 

形参和实参

形参:用于接受传递值的变量被称为形参。

实参:传递给函数的值被称为实参。

实参是形参的初始值,所以实参的类型须与对应的形参类型匹配。

 

#include <iostream>
#include <string>

using namespace std;
//函数声明
void greet();
int sum(int a, int b);

int main()
{
	int num1 = 10;
	int num2 = 5;
	//调用函数
	greet();
	//需要一个int类型的变量来接受返回值
	int result = sum(num1, num2);
	cout << result << endl;
	return 0;
}

//没有返回值,没有参数
//函数名greet
//函数体为输出Hello语句
void greet()
{
	cout << "Hello!" << endl;
}

//返回值为int类型
//参数为2个int类型的值a,b
//函数名为sum
//函数体为求得两个参数的和,并返回一个int类型的数值
int sum(int a, int b)
{
	int res = a + b;
	return res;
}

 

[展开全文]

局部对象

在C++中,名字(变量、函数、类型)有作用域(静态),对象有生命周期(动态)。

名字的作用域是程序文本的一部分,名字在其中可见。对象的生命周期是程序执行过程中该对象存在的一段时间。

形参和函数体内部定义的变量统称为局部变量,仅在函数的作用域内可见。

在所有函数体外定义的对象存在于程序的整个执行过程中。局部变量的生命周期则依赖于定义的方式。

 

 

自动对象

我们把只存在于块执行期间的对象称为自动对象。

普通的局部变量对应的对象,是自动对象,在每次调用函数时创建和销毁。

形参也是一种自动对象。函数开始时为形参申请存储空间,因为形参定义在函数体作用域内,所以一旦函数终止,形参也就被销毁。

 

 

局部静态对象

局部静态对象在程序的执行路径第一次经过对象定义语句时初始化,并且知道程序终止才被销毁,所以局部静态对象不是自动对象。

可以用static关键字来修饰局部变量,从而获得局部静态对象。

static int count = 0;

 

 

#include <iostream>
#include <string>

using namespace std;

int min(int num1, int num2, int num3);
//定义在所有函数体外的对象,为全局对象。
int a = 3;

int main()
{
	//res的作用域为main()函数
	int res = min(4, 8, 2);
	//cout << res << endl;

	res = min(3, 3, 6);
	res = min(2, 3, 5);
	return 0;
}

//num1/num2/num3为函数min()的形参
int min(int num1, int num2, int num3)
{
	//res的作用域为min()函数
	int res;
	//局部静态变量,直到程序终止才被销毁
	static int count = 0;
	count += 1;
	cout << count << endl;
	res = num1 < num2 ? num1 : num2;
	res = res < num3 ? res : num3;
	return res;
}

 

[展开全文]

int min(int num,int &num2)

num 是定义复制实参的值,不改变实参

%num2是定义引用类型的参数,修改了实参

[展开全文]

int min=num1<num2?num1:num2;

 

[展开全文]

private:标识只能通过公共成员访问的类成员(数据隐藏)

public:标识组成类的公共接口的类成员(抽象)

降接口放在头文件中,并将实现放在源代码(.cpp)中。

class表示类

private(私有成员:只能通过公共成员访问的类成员(数据隐藏)

public:标识组成类的公共接口的类成员(抽象)。

   

 

 

 

[展开全文]

int main(0

{

int res=min(4,8,2);

cout<<res;

}

int min(int num1,int num2,int num3)

{

int res;

static int count=0;

count+=1;

res=num1<num2?num1:num2;

res=res<num3?res:num3;

return res;

 

}

[展开全文]

参数传递

形参的类型决定了形参和实参的交互方式。

如果形参是引用类型,它将绑定到对应的实参上(传引用参数);否则,将实参的值拷贝后赋给形参(传值参数)。

 

 

传值参数

传值参数有2种方式:

1.将实参的实际值复制给函数的形参。在这种情况下,修改函数内的形参对实参没有影响。

2.将参数的地址复制给形参(指针)。因为指针使我们可以见间接地访问它所指的对象,所以通过指针可以修改它所指对象的值。

 

 

#include "pch.h"
#include <iostream>
#include <string>

using namespace std;

int reset(int i);
void reset1(int* pi);

int main()
{
	int num = 10;
	cout << "reset: " << reset(num) << endl; // 20
	cout << "num: " << num << endl; // 10
	cout << "num的地址:" << &num << endl; // num的地址:001FFD04
	reset1(&num);
	cout << "reset1: " << num << endl; // 20
	cout << "num的地址:" << &num << endl; // num的地址:001FFD04
	return 0;
}
//传递实参的实际值,将实参的值拷贝给形参,函数体种修改的是形参的值,对实参不产生影响
int reset(int i)
{
	i *= 2;
	return i;
}

//传递实参的地址,修改*pi的值,就是修改实参指向的对象的值,修改pi的值,是修改的形参存储的地址,不影响实参的地址。
void reset1(int* pi)
{
	*pi *= 2;
	pi = 0;
}

 

[展开全文]

传引用参数

引用:引用是已定义的变量的别名。对于引用的操作实际上是作用在引用所引的对象上的。它们共用相同的内存空间。

传引用参数:通过将引用变量用作参数,函数将使用原始数据,而不是其副本。

int n = 0;

int &r = n;(&不再是地址运算符,r是n的引用)

 

 

传引用参数

用途:

1.当某种类型不支持拷贝操作,或是需要拷贝的对象太大时,我们可以通过引用形参来访问对象。

2.当函数需要同时返回多个值时,可以使用引用形参来处理。

 

 

#include <iostream>
#include <string>

using namespace std;

void reset(int &i);
int min(int num1, int num2, int num3, int &max);

int main()
{
	int num = 10;
	reset(num);
	cout << num << endl;

	int maxNum;
	int minNum;
	minNum = min(20, 15, 23, maxNum);
	cout << "最大值为:" << maxNum << endl;
	cout << "最小值为:" << minNum << endl;
	return 0;
}

//将引用变量作为参数,函数使用的是圆石数据,而不是副本。
//对形参的修改其实就是对实参的修改。
void reset(int &i)
{
	i = i * 2;
}

//函数的返回值为int类型,返回的是3个数中的最小值
//定义了一个引用类型的参数,通过这个参数修改maxNum的值,获得最大值
int min(int num1, int num2, int num3,int &max)
{
	int temp1, temp2;
	temp1 = num1 < num2 ? num1 : num2;
	temp1 = temp1 < num3 ? temp1 : num3;

	temp2 = num1 > num2 ? num1 : num2;
	temp2 = temp2 > num3 ? temp2 : num3;

	max = temp2;
	return temp1;
}

 

[展开全文]

const形参和实参

顶层const:表示任意的对象是常量。

底层const:与指针和引用等复合类型有关。

对指针而言,顶层const表示指针本事就是个常量,而底层const表示指针所指的对象是一个常量。

int i = 22;

const int ci = 20; //顶层const,不能修改 ci 的值

const int *p1 = &ci; //底层const,允许修改 p1 的值,但是不能通过 *p1 修改 ci 的值。

int *const p2 = &i; //顶层const,不能修改 p2 的值,但是允许通过 *p2 修改 i 的值。

 

 

#include <iostream>

using namespace std;

int main()
{
	//num1 为 int 类型的变量,可以修改它的值
	//num2 为 int 类型的常量,不可以修改它的值
	int num1 = 10;
	const int num2 = 10;
	num1 = 20;
	//num2 = 10;//出错

	//普通指针,可以修改p1的值,也可以修改*p1来修改num1的值。
	//所以只能用int类型的数据来初始化,不能用const int类型,不能修改常量的值。
	int *p1 = &num1;
	//int *p2 = &num2;//出错
	
	//底层const,可以修改指针(p3,p4),但是不可以修改*p3,*p4,去修改num1,num2的值。
	//可以使用int类型或const int 类型的数据来初始化
	const int *p3 = &num1;
	const int *p4 = &num2;

	//顶层const,不可以修改指针(p5,p6),但是可以通过*p5去修改num1的值。
	//所以只能使用int类型的数据来初始化,不能const int类型
	int * const p5 = &num1;
	//int * const p6 = &num2; //错误

	//int类型的引用,可以通过r1去修改num1的值,所以只能使用int类型去初始化,不能使用const int类型
	int &r1 = num1;
	//int &r2 = num2; //出错

	//const int 类型的引用,不能修改r3,r4的值
	//可以使用int类型的数据来初始化,也可以使用const int类型
	const int &r3 = num1;
	const int &r4 = num2;
	return 0;
}

111

[展开全文]

const形参和实参

用实参初始化形参时,会忽略掉顶层const,也就是说,当形参有顶层const时,传给它常量对象或者非常量对象也是可以的。

 

#include <iostream>

using namespace std;

int cube1(int i);
int cube2(const int i);
int pCube1(int *pi);
int pCube2(const int *pi);
int pCube3(int* const pi);

int main()
{
	//num1 为 int 类型的变量,可以修改它的值
	//num2 为 int 类型的常量,不可以修改它的值
	int num1 = 10;
	const int num2 = 10;
	num1 = 20;
	//num2 = 10;//出错

	//普通指针,可以修改p1的值,也可以修改*p1来修改num1的值。
	//所以只能用int类型的数据来初始化,不能用const int类型,不能修改常量的值。
	int *p1 = &num1;
	//int *p2 = &num2;//出错
	
	//底层const,可以修改指针(p3,p4),但是不可以修改*p3,*p4,去修改num1,num2的值。
	//可以使用int类型或const int 类型的数据来初始化
	const int *p3 = &num1;
	const int *p4 = &num2;

	//顶层const,不可以修改指针(p5,p6),但是可以通过*p5去修改num1的值。
	//所以只能使用int类型的数据来初始化,不能const int类型
	int * const p5 = &num1;
	//int * const p6 = &num2; //错误

	//int类型的引用,可以通过r1去修改num1的值,所以只能使用int类型去初始化,不能使用const int类型
	int &r1 = num1;
	//int &r2 = num2; //出错

	//const int 类型的引用,不能修改r3,r4的值
	//可以使用int类型的数据来初始化,也可以使用const int类型
	const int &r3 = num1;
	const int &r4 = num2;

	//实参为int类型或const int类型
	cout << cube1(num1)<<" "<< cube1(num2) << endl;
	cout << cube2(num1) << " " << cube2(num2) << endl;

	//实参只能为int类型
	cout << pCube1(&num1) << endl;
	//cout << pCube1(&num2) << endl; //出错

	//所以实参可以是int类型,const int类型
	cout << pCube2(&num1) << " " << pCube2(&num2) << endl;
	
	//实参类型只能是int类型
	cout << pCube3(&num1) << endl;
	//cout << pCube3(&num2) << endl; //出错

	return 0;
}

//可以修改形参i
int cube1(int i)
{
	//i = 0;
	return i * i * i;
}

//不可以修改形参i
int cube2(const int i)
{
	//i = 0; //出错
	return i * i * i;
}

int pCube1(int *pi)
{
	//*pi = 0;
	return *pi * (*pi) * (*pi);
}

//可以修改pi,但是不可以修改*pi,所以实参可以是int类型,const int类型
int pCube2(const int *pi)
{
	//*pi=0; //出错
	return *pi * (*pi) * (*pi);
}

//不可以修改pi,但是可以修改*pi,所以实参类型只能是int类型
int pCube3(int* const pi)
{
	//*pi=0;
	return *pi * (*pi) * (*pi);
}

[展开全文]

const形参和实参

总结:

1.int cube(int i); 实参可以为int类型,也可以为const int类型。在函数体中可以修改i的值,函数不会修改实参的值。

2.int cube(const int i); 实参可以为int类型,也可以为const int类型。在函数体中不可以修改i的值,函数不会修改实参的值。

总结:

3.int pCube(int* pi); 实参为int*类型的指针,不能为const int*类型。可以通过修改*pi的值修改实参指向的对象的值,修改pi对实参没有影响。

4.int pCube(const int *pi); 实参可以为const int*类型,也可以为int*类型。不可以通过修改*pi的值修改实参指向的对象的值,修改pi对实参没有影响。

5.int pCube(int * const pi); 实参为int*类型,不能为const int*类型。可以通过修改*pi的值修改实参指向的对象的值,不可以给pi赋值。

总结:

6.void reset(int &r); 实参为int类型,不可以为const int类型。可以通过修改r的值,从而修改实参的值。

7.void print(const int &r); 实参可以为int类型,也可以为const int类型,不可以修改r的值

 

 

#include <iostream>

using namespace std;

int cube1(int i);
int cube2(const int i);

int pCube1(int *pi);
int pCube2(const int *pi);
int pCube3(int* const pi);

int rCube1(int &r);
int rCube2(const int &r);

int main()
{
	//num1 为 int 类型的变量,可以修改它的值
	//num2 为 int 类型的常量,不可以修改它的值
	int num1 = 10;
	const int num2 = 10;
	num1 = 20;
	//num2 = 10;//出错

	//普通指针,可以修改p1的值,也可以修改*p1来修改num1的值。
	//所以只能用int类型的数据来初始化,不能用const int类型,不能修改常量的值。
	int *p1 = &num1;
	//int *p2 = &num2;//出错
	
	//底层const,可以修改指针(p3,p4),但是不可以修改*p3,*p4,去修改num1,num2的值。
	//可以使用int类型或const int 类型的数据来初始化
	const int *p3 = &num1;
	const int *p4 = &num2;

	//顶层const,不可以修改指针(p5,p6),但是可以通过*p5去修改num1的值。
	//所以只能使用int类型的数据来初始化,不能const int类型
	int * const p5 = &num1;
	//int * const p6 = &num2; //错误

	//int类型的引用,可以通过r1去修改num1的值,所以只能使用int类型去初始化,不能使用const int类型
	int &r1 = num1;
	//int &r2 = num2; //出错

	//const int 类型的引用,不能修改r3,r4的值
	//可以使用int类型的数据来初始化,也可以使用const int类型
	const int &r3 = num1;
	const int &r4 = num2;

	//实参为int类型或const int类型
	cout << cube1(num1)<<" "<< cube1(num2) << endl;
	cout << cube2(num1) << " " << cube2(num2) << endl;

	//实参只能为int类型
	cout << pCube1(&num1) << endl;
	//cout << pCube1(&num2) << endl; //出错

	//所以实参可以是int类型,const int类型
	cout << pCube2(&num1) << " " << pCube2(&num2) << endl;
	
	//实参类型只能是int类型
	cout << pCube3(&num1) << endl;
	//cout << pCube3(&num2) << endl; //出错

	//实参只能是int类型
	cout << rCube1(num1) << endl;
	//cout << rCube1(num2) << endl; //出错

	//实参类型可以是int类型,也可以是const int类型
	cout << rCube2(num1) << " " << rCube2(num2) << endl;

	return 0;
}

//可以修改形参i
int cube1(int i)
{
	//i = 0;
	return i * i * i;
}

//不可以修改形参i
int cube2(const int i)
{
	//i = 0; //出错
	return i * i * i;
}

int pCube1(int *pi)
{
	//*pi = 0;
	return *pi * (*pi) * (*pi);
}

//可以修改pi,但是不可以修改*pi,所以实参可以是int类型,const int类型
int pCube2(const int *pi)
{
	//*pi=0; //出错
	return *pi * (*pi) * (*pi);
}

//不可以修改pi,但是可以修改*pi,所以实参类型只能是int类型
int pCube3(int* const pi)
{
	//*pi=0;
	return *pi * (*pi) * (*pi);
}

//可以修改r,实参只能是int类型
int rCube1(int &r)
{
	//r = r * r * r;
	return r * r * r;
}

//不可以修改r,实参类型可以是int类型,也可以是const int类型
int rCube2(const int &r)
{
	//r = r * r * r; //出错
	return r * r * r;
}

[展开全文]

定义成员函数时,需要使用域解析符(::)来标识函数所属的类

void Student::setStudent(string name,int chinese,int math,int english)

{

    name_=name  }

[展开全文]

通过引用 可以同时返回两个或两个以上得返回值

[展开全文]

默认实参:某些函数有这样一种形参,在函数的很多次调用中他们都被赋予一个相同的值,我们把这个反复出现的值称为函数的默认实参。

调用含有默认实参的函数时,可以包含该实参,也可以省略该实参。

对于有多个形参的函数,必须从右向左添加默认值。

 

#include <iostream>
#include <string>

using namespace std;

void compare(int num1, int num2 = 100);
void greet(string name = "User");

int main()
{
	int a = 59;
	int b = 120;
	compare(a);
	compare(b);
	compare(a, b);
	greet();
	greet("Jane");
	return 0;
}

void compare(int num1, int num2)
{
	if (num1 > num2)
	{
		cout << num1 << "大于" << num2 << endl;
	}
	else if (num1 < num2)
	{
		cout << num1 << "小于" << num2 << endl;
	}
	else
	{
		cout << num1 << "等于" << num2 << endl;
	}
}

void greet(string name)
{
	cout << name << ", hello!" << endl;
}

[展开全文]

授课教师

SIKI学院老师

课程特色

下载资料(1)
视频(43)