【c++】引用+常量指针/指针常量+指针函数/函数指针+函数高级

本文详细介绍了C++中的引用概念,包括引用的初始化、不可变性和作为函数参数的使用。同时,探讨了指针的不同形式,如常量指针、指针常量和常量指针常量。此外,还讨论了指针函数和函数指针的用法,以及函数的默认参数、占位参数和重载。最后,展示了如何在实际代码中应用这些概念。

引用

引用:**给变量起一个别名**
语法:数据类型 &别名=原名;
  1. 引用一定要初始化
    int &c;//错误,要让b初始化引用指向a
  2. 引用初始化后,不能更改
    int &c=a;
    int &c=b;//错误,不能更改引用的指向
  3. 不要返回局部变量的引用,值会改变
  4. 函数的返回值为引用的时候,函数调用可以作为左值(等式左边)
  5. 引用本质:指针常量;指向不可以修改,指向的值可以修改
    int &ref = a;//自动转换 int* const ref = & a;//指针常量
    ref = 20;//内部发现ref是引用,自动转化为*ref = 20;
  6. 常量引用 const int& ref =10;

C++推荐使用引用,因为语法方便,引用本质是指针常量,但是所有的指针操作编译器都帮我们做了

#include <iostream>
#include <string>

using namespace std;

//创建引用
int g_a = 10;
int g_b = 10;
int& c = g_a;
//int& c = g_b;///错误,不能更改引用的指向

void swap(int &a, int &b) {//引用传递,形参会修饰实参
	int temp = b;
	b = a;
	a = temp;
}

int& test01() {//不要返回局部变量的引用
	int l_a = 10;
	return l_a;
}

int& test02() {//不要返回局部变量的引用
	static int static_b = 10;
	return static_b;
}

void showValue(const int& ref) {//使用常量引用,让变量只能被访问,不能修改
	//ref += 10;//只能被访问,不能修改
	cout << "打印g_a="<< ref << endl;
}

void main() {

	cout << "原始a,b的值" << endl;
	cout << "g_a=" << g_a << endl;
	cout << "g_b=" << g_b << endl;
	c = 20;
	cout << endl << "修改引用c后(c引用a),g_a,g_b的值" << endl;
	cout << "g_a=" << g_a << endl;
	cout << "g_b=" << g_b << endl;

	swap(g_a, g_b);//引用传递,形参会修饰实参
	cout << endl << "引用传递后(swap(int &a, int &b)),g_a,g_b的值" << endl;
	cout << "g_a=" << g_a << endl;
	cout << "g_b=" << g_b << endl;

	cout << endl << "不要返回局部变量的引用,值会改变,因为数据存放在栈区" << endl;
	int &return_l_a = test01();
	cout << "l_a=" << return_l_a << endl;
	cout << "l_a=" << return_l_a << endl;
	cout << "l_a=" << return_l_a << endl;

	int& return_l_b = test02();
	cout << endl << "全局变量的引用,值会不会变,因为数据存放在全局区" << endl;
	cout << "static_b=" << return_l_b << endl;
	cout << "static_b=" << return_l_b << endl;
	cout << "static_b=" << return_l_b << endl;

	test02() = 123;//函数的返回值为引用的时候,函数调用可以作为左值(等式左边),修改static_b=1123;
	cout << endl << "函数调用作为左值(等式左边),修改static_b" << endl;
	cout << "static_b=" << return_l_b << endl;

	//int& ref = 10;  引用本身需要一个合法的内存空间,因此这行错误
	//加入const就可以了,编译器优化代码,int temp = 10; const int& ref = temp;
	const int& ref = 10;

	//ref = 100;  //加入const后不可以修改变量
	cout << endl << "常量引用ref="<< ref << endl;

	showValue(g_a);
}

常量指针、指针常量

  • 语法:
    常量指针:const int* p = &a;
    指针常量:int* const p = &a;
    常量指针常量:const int* const p = &a;

总结:
常量指针:本质指针,指向的对象是常量,不能通过指针来修改指向对象,但是其本身是一个变量,因此可以被重新赋值
指针常量:本质常量,常量的值是一个指针,指向不能变,指向的内容可变
常量指针常量:常量指针+指针常量

#include<iostream>
using namespace std;
void main() {
	int a = 100;
	int b = 200;

	const int* p1 = &a;
	int* const p2 = &a;
	const int* const p3 = &a;

	//1.常量指针
	//*p = 200;//错误,不能通过指针来修改指向对象
	p1 = &b;//但是其本身是一个变量,因此可以被重新赋值
	cout << *p1 << endl;

	//2.指针常量
	//p2 = &b; //错误,指向不能变,指向的内容可变
	*p2 = 150;
	cout << *p2 << endl;
	cout << a << endl;

	//3.常量指针常量:常量指针 + 指针常量
	//*p3 = 200;//错误,指向的内容不能变
	//p3 = &b;//错误,指向不能变
}

指针函数、函数指针

  • 指针函数:返回值为指针的函数
  • 函数指针:指向函数的指针

总结:
函数名本身就是一个地址,就是一个函数指针
函数指针可以作为参数进行传递

#include<iostream>
using namespace std;

int* ptr_a(int& val) {//返回指针,指针函数
	val = val + 1;
	return &val;
}

int& ptr_b(int& val) {//返回引用,指针函数
	val = val + 1;
	return val;
}

int ptr_c(int& val) {//普通函数
	val = val + 1;
	return val;
}

void test_() {
	int value = 1;
	//返回指针,指针函数
	int* p1 = ptr_a(value);
	cout << "value:" << value << "\t\t*p1:" << *p1 << endl;

	//返回引用,指针函数
	int& p2 = ptr_b(value);
	p2++;
	cout << "value:" << value << "\t\tp2:" << p2 << endl;

	//普通函数,来定义成函数指针
	// 直接定义
	int (*func_ptr)(int&);//定义一个指针,指向函数(返回值为int,参数为int&)
	func_ptr = ptr_c;//赋值
	func_ptr(value);
	cout << "value:" << value << endl;

	//typedef
	typedef int(*func_ptr2)(int&);//用typedef给函数指针(返回值为int,参数为int&)别名func_ptr2
	func_ptr2 ptr1 = ptr_c;//定义一个函数指针,并赋值
	ptr1(value);//利用函数指针调用函数
	cout << "value:" << value << endl;

	//using,推荐使用
	using func_ptr3 = int(*)(int&);//用using给函数指针(返回值为int,参数为int&)别名func_ptr3
	func_ptr3 ptr2 = ptr_c;//定义一个函数指针,并赋值
	ptr2(value);//利用函数指针调用函数
	cout << "value:" << value << endl;

}

void main() {
	test();
}

函数高级

  1. 函数默认参数 返回值类型 函数名(参数= 默认值){}
    //1. 如果某个位置参数有默认值,那么从这个位置往后,从左向右,必须都要有默认值
    //2. 如果函数声明有默认值,函数实现的时候就不能有默认参数(函数声明和实现只能有一个有默认参数)
    int func(int a=10; int b=10);//函数声明
    int func(int a=10; int b=10){return a+b;}//函数实现
    //上述例子错误,函数声明和实现只能有一个有默认参数
    int func(int a; int b);//函数声明
    int func(int a=10; int b=10){return a+b;}//函数实现
    //3. 有传入的参数就用传入的参数,没有就要用默认值
  2. 函数占位参数 返回值类型 函数名 (数据类型){} void func(int a, int) {}
    //1. C++中函数的形参列表里可以有占位参数,用来做占位,调用函数时必须填补该位置
    //2. 函数占位参数 ,占位参数也可以有默认参数 void func(int a, int = 10) {}
    //3. 在现阶段函数的占位参数存在意义不大,但是后面的课程中会用到该技术
  3. 函数重载 函数名可以相同,提高复用性
    //1. 满足条件:同一个作用域下;函数名称相同;函数参数类型不同或者个数不同或者顺序不同;
    //2. 函数返回值不可以作为函数重载条件
    //3. 注意: * 引用作为重载条件 函数重载碰到函数默认参数
#include <iostream>
#include <string>

using namespace std;

//函数默认参数
int sum_3(int a, int b = 10, int c = 10) {//求三数之和
	return a + b + c;
}

//函数占位参数
void placeholder(int a, int) {
	cout << "This is placeholder func." << endl;
}

//引用作为重载条件
void ref_overloading(int& a)
{
	cout << "ref_overloading (int &a) 调用 " << endl;
}
void ref_overloading(const int& a)
{
	cout << "ref_overloading (const int &a) 调用 " << endl;
}

//默认参数碰到函数重载
void def_overloading(int a,int b = 10) {
	cout << "def_overloading (int a; int b = 10) 调用 " << endl;
}
void def_overloading(int a) {
	cout << "def_overloading (int a) 调用 " << endl;
}

void main() {
	//调用有默认参数的函数时,默认的参数位置可以传值也可不传
	cout << "默认参数" << endl;
	cout << "sum_3 = " << sum_3(20, 20) << endl;
	cout << "sum_3 = " << sum_3(100) << endl;
	
	//调用有占位参数(非默认)的函数时,占位参数必须填补,占位参数为默认参数时可填补可不填补
	cout << endl << "占位参数" << endl;
	placeholder(10, 10); //占位参数必须填补

	//引用作为重载条件,根据传入的类型调用,指针常量(调用无const),常量指针常量(调用const)
	int a = 10;
	const int b = 10;
	cout << endl << "引用作为重载条件" << endl;
	ref_overloading(a); //a为变量,调用无const
	ref_overloading(b); //b为常量,调用const
	ref_overloading(10);//int &a = 10 不合法,const int &a = 10 合法;所以调用有const

	//默认参数碰到函数重载
	cout << endl << "默认参数碰到函数重载" << endl;
	//def_overloading(10);//报错,不知道调用哪个
	def_overloading(10, 10);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值