C++基础认识(新手村)day2
  oEHvnwBRyoan 2023年11月02日 76 0

引用的使用场景

1.引用作为函数参数

//1.引用作为函数参数
void fun1(int &a ,int &b)
{
	int sum = a + b;
	cout << "sum = " << sum << endl;
}

void test1()
{
	int a = 10;
	int b = 20;
	fun1(a, b);
}

2.引用作为函数的返回值

//2.引用作为函数的返回值
int& fun2()
{
	int b = 10;// 注意1:不要返回局部变量的引用
	int& p = b;
	return p;
}

int& fun3()
{
	static int b = 10;
	return b;
}

void test2()
{
	/*int& q = fun2();
	q = 100;
	cout << q << endl;

	fun2() = 200;
	cout << q << endl;*/
//-------以上代码均为错误代码,只是编译器未检测出来
	cout << "fun2() = " << fun2() << endl;

	fun3() = 100;//注意2:如果要函数作为左值,则该函数必须返回引用
	cout << "fun3() = " << fun3() << endl;
}

常量的引用

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>

using namespace std;

int main()
{
	//普通引用
	int a = 10;
	int& ref = a;
	ref = 20; 
	
	//int& ref2 = 10; //不能给字面量(1,2,3...)取别名
	const int& ref3 = 10; // 可以给const修饰的引用赋予字面量
	//const修饰符修饰的引用的原理
	//编译器会把上面的代码变为:int tmp =10; const int &ref3 =tmp;
	//ref3 =10; err 不能改动

	//bool类型
	//bool类型定义的变量只有两个值
	bool is = 1; // 注意:is的值除0以外都是真
	if (is)
		cout << "真" << endl;
	else
		cout << "假" << endl;

	return 0;
}

内联函数

  1. 宏函数的缺陷
  • 宏函数预处理阶段被替换,不会进行类型的检测,代码安全性低
  • 宏函数不能进行调试
  • 容易出错,宏函数的每一部分都需要加上括号
  • 每个宏函数的位置都会被展开,会造成代码的膨胀
#define ADD(x,y) x+y
//在普通函数前面加上inline是向编译器申请成为内联函数
//注意:加了inline可能成为内联函数,也可能不是
inline int Add(int x, int y)
{
	return x + y;
}

void test1()
{
	int a = ADD(10, 20) * 2;
	cout << "a = " << a << endl;

	int a2 = Add(10, 20) * 2;
	cout << "a2 = " << a2 << endl;
}

C++基础认识(新手村)day2_默认参数

#define COMPARE(x,y) ((x) < (y) ? (x) : (y))

inline int funPARE(int x, int y)
{
	return x < y ? x : y;
}

void test2()
{
	int m = 1;
	int n = 3;

	cout << "fun(m,n) = " << funPARE(++m, n) << endl;

	cout << "COMPARE(x,y) = " << COMPARE(++m, n) << endl;

C++基础认识(新手村)day2_函数重载_02


  1. 编译器不会将函数进行内联编译的情况
  • 存在过多的条件判断语句
  • 函数体过大
  • 对函数进行取址操作
  • 存在任何形式的循环语句
  1. 内联函数的好处
  • 有宏函数的效率,但是没有宏函数的缺点
  • 类的成员函数默认加上inline

宏函数与内联函数的区别

函数的默认参数

1.函数的默认参数就是给函数的形参赋值

int myFun(int a, int b = 0)
{
	return a + b;
}

void test1()
{
	//函数的默认参数的作用
	//当函数内常要用到形参的某个值,但偶尔要使用其他值
	//增加函数的灵活性
	cout << myFun(10, 20) << endl;
	cout << myFun(10) << endl;
}

//注意1:函数的默认参数后面的参数必须全都是默认参数
int myFun2(int a, int b = 0, int c = 2, int d = 3)
{
	return a + b + c + d;
}

//注意2:函数的声明和实现不能同时有函数的默认参数
void myFun3(int a, int b);
void myFun3(int a, int b = 0)
{
	
}

函数的占位参数

//函数的占位参数,占位参数在后面运算符重载时区分前++或后++时
void func(int a,int =10) // 占位参数也有默认值
{

}

void test2()
{
	func(10);
}

函数占位参数和默认参数的混搭

void func2(int, int a = 10)
{

}

void test3()
{
	func2(10);
	func2(10, 30);
}

函数传参的方式

1.值传递

void swap(int a, int b)
{
	int tmp = a;
	a = b;
	b = tmp;
}
int main()
{
	int a = 10;
	int b = 20;
	swap(a, b);
	print(a, b);
	return 0;
}

C++基础认识(新手村)day2_宏函数_03

2.指针传递

void swap2(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
int main()
{
	int a = 10;
	int b = 20;
	swap2(&a, &b);
	print(a, b);
	return 0;
}


C++基础认识(新手村)day2_函数重载_04

3.引用传递

void swap3(int& a, int& b)
{
	int tmp = a;
	a = b;
	b = tmp;
}
int main()
{
	int a = 10;
	int b = 20;
	swap3(a, b);
	print(a, b);
	return 0;
}

C++基础认识(新手村)day2_宏函数_05

函数重载

1.函数重载:在同一个作用域内,可以声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同。

2.函数重载的作用:为了方便使用函数名

3.函数重载的条件:同一个作用域,参数的个数不同,参数的顺序不同,参数的类型不同

//参数的个数不同
void func()
{
	cout << "func()" << endl;
}

void func(int a)
{
	cout << "fun(int a) " << endl;
}

//参数的类型不同
void func(char b)
{
	cout << "func(char b)" << endl;
}

//参数的顺序不同
void func(int a, double b)
{
	cout << "fun(int a,double b)" << endl;
}

void func(double b, int a)
{
	cout << "func(double b, int a)" << endl;
}

4.调用重载函数的注意

  • 严格的类型匹配,如果类型不匹配,那么会尝试转换,转换成功就调用,失败就会报错
void test()
{
	int a = 10;
	double b = 3.14;
	func();
	//func(b);  //err  double没法转换成int 或 char
	func(a, b);
	func(b, a);
	char c = 'c';
	func(c); //char转换int成功,调用int参数的函数
}

5.函数重载和函数的默认参数一起使用,需要注意二义性问题

void myfunc(int a, int b = 0)
{
	cout << "myfunc(int a, int b = 0)" << endl;
}

void myfunc(int a)
{
	cout << "myfunc(int a)" << endl;
}

void test2()
{
	//myfunc(10); //err 二义性问题,不知道调用哪个函数
}

6.函数的返回值不作为函数重载的条件

编译器是通过调用函数时,传入的参数来判断调用重载的哪个函数,而调用函数时不需要写返回值类型,所以函数的返回值不作为函数重载的条件

函数重载的原理

函数重载的原理实是在汇编时,给各个函数取别名,c语言不能重载的原因是没有取别名

C++调用C语言的函数

c++的函数在汇编时会给函数取别名,c语言不会,如果c++调用c语言的函数,c++会去宅找取了别名的函数,但是c语言没有取别名,这时会出错

test.h头文件中

#pragma once
#include<stdio.h>

//这里是告诉c++编译器,找下面的函数,要以c语言的方式去找
#ifdef __cplusplus
extern "C"
{
#endif // DEBUG
	void func();

#ifdef __cplusplus
}
#endif

类和对象

1.类是自定义数据类型,是c语言的结构体进化而来的

2.对象是类实例化出来的,用数据类型定义一个变量

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>

using namespace std;

class Maker //类
{
public:
	int a; // 成员属性(成员变量)
	void func() //成员方法(成员函数)
	{
		cout << "func" << endl;
	}
};

int main()
{
	Maker m; // m是对象

	return 0;
}

类的封装

1.封装是把属性(变量)和方法(函数)封装到类内,然后给这些数据赋予权限

2.封装的原因:

  • 防止乱调用函数和变量,出现错误
  • 维护代码更方便

3.权限

//封装:1.把属性和方法放到类中,2.给这些数据赋予权限
class Maker {
public://公共权限
	void set(int Id, string Name)
	{
		id = Id;
		name = Name;
	}
	void printMaker()
	{
		cout << "id = " << id << "\nname = " << name << endl;
	}
	void get()
	{
		cout << "Maker a = " << a << endl;
	}
private://私有
	int id;
	string name;
protected://保护
	int a;
};

//继承,公有继承
class Son :public Maker //子类:继承方式 父类
{
public:
	void fun()
	{
		//下面这个a是从父类复制过来的
		int a = 20;//子类的类内可以访问父类的保护权限的成员

	}
	void getS()
	{
		cout << "Son a= " << a << endl;
	}
};
//类外不能访问私有权限的成员
//类外可以访问公有权限的成员
//类外不能访问保护权限的成员
//子类的类内可以访问父类的保护权限的成员
//类内是没有权限之分 

void test()
{
	Maker m;
	m.set(1, "张三");
	m.printMaker();
}

void test1()
{
	Maker m;
	m.get();
	Son s;
	s.fun();
	s.getS();
}

4.尽量将变量属性设置为私有权限

  • 可以控制属性的读写权限
  • 可赋予客户端访问数据的一致性
  • 可以保护属性的合法性

类和结构体的区别

结构体的成员和成员函数在默认情况下的访问级别是公有的(public),类的成员和成员函数在默认情况下的访问级别是私有的(private)。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论