day3.c++函数与预处理 string

c++函数与预处理 string

1.内置函数

c++ 复制代码
#include<iostream> 

using namespace std;

//1.内置函数的价值:主要作用地为了提高我们程序的执行效率。
//2.内置函数如何定义:只需要在传统函数定义的基础上,在返回类型的前面加inline关键字,此时该函数就变成了内置函数
//或者叫内联函数。--- 意味着程序在对inline修饰的函数在编译时会做特殊的处理

inline void test()
{
	
	cout<<"test inner function";
	
}


int main()
{

	 test();//3.内联函数的调用和传统函数时一样,程序在对其做编程时,会将test()调用语句替换成cout<<"test inner function";
            //替换后,在执行程序时 就省掉了保护现场和恢复现场的操作,从而提高了程序的效率。
	//4.什么场景适合将函数定义为内置函数:1.该函数在程序中需要被频繁的调用,2,该函数体中的语句比较短小(6条语句以下)
	return 0;
}

函数重载

c++ 复制代码
#include<iostream> 

using namespace std;

//1.什么是函数重载 就是在同一个作用域,定义多个同名函数,需要确保这些函数的参数个数不一样或参数类型不一样,这样的一组函数叫函数重载
int add(int a, int b) //函数重载成功的条件:要么它们的形参个数不一样,要么形参类型不一样,要么个数和类型都不一样
{
	cout<<"两个int相加"<<endl;
	return a+b;
}

double add(double a, double b)
{
	cout<<"两个double相加"<<endl;
	return a+b;
}


int add(int a, int b,int c)
{
	cout<<"三个int相加"<<endl;
	return a+b+c;
}

//void test(int a ,float b)  void test(float a,int b) 这个叫顺序不一样


int main()
{
    add(3,5);//在调用重载的某个函数时,它是如何来匹配目标函数,根据用户在调用时 所传递的实参个数和类型来匹配要调用的目标函数
	add(1,2,3);
	add(2.1,3.4);

	return 0;
}
c++ 复制代码
void fun(int a)
{
	cout<<"int"<<endl;
}

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


int main()
{
//    add(3,5);//在调用重载的某个函数时,它是如何来匹配目标函数,根据用户在调用时 所传递的实参个数和类型来匹配要调用的目标函数
//	add(1,2,3);
//	add(2.1,3.4);

  //fun(NULL);//在C++中,NULL对函数重载带来了调整,为了解决这个问题,C++提供一个新的关键字来代替NULL
	fun(nullptr);//在C++中提供了空指针的关键字nullptr来表示空指针,在C++中不推荐大家用NULL。
	return 0;
}
c++ 复制代码
void test(const int* a)  //这两个是可以重载成功的
{
	cout<<"const int *";
}

void test(int* a)
{
	cout<<"int *";
	
}


int main()
{
 int k=10;
   	test(&k );
     
	return 0;
}

函数模板

c++ 复制代码
#include<iostream> 

using namespace std;




//
//int add(int a, int b) //下边这三个函数,虽然能够重载成功,但是发现它们的代码逻辑一样,唯独数据类型不一样,这也是代码的重复
//{
//
//	return a+b;
//}
//
//float add(float a,float b)
//{	
//	return a+b;
//}
//
//double add(double a, double b)
//{
//	return a+b;
//}

//函数模板致力于构建一个通用的函数,用一些虚拟的符号来代指任意类型,从而让改函数更通用
//虚拟类型T 具体是啥类型,取决于调用改模版函数时用户的指定。
//<>里主要存放的是模板的形参列表,每个模板形参都有两部分组成:typename +虚拟符号,存在多个形参时用逗号去隔开
//虚拟类型的符号一般建议大写,为了和传统的具体类型做区分。
//修饰虚拟符号 可以用typename关键字来修饰,也可以用class来修饰。template<class T>
template<typename T> //这个就叫函数模板(代表多个函数逻辑一样,唯独类型不一样的场景)。减少代码冗余
T add(T a,T b) //一个函数模版只能代替参数个数相同的一群功能相似的函数
{
	
	return a+b;
}




int main()
{
   cout<< add(1,2);//调用函数模版的函数就像调用普通函数一样去调用。
   cout<<add(2.3,3.3);//模板函数的调用原理:1.当调用函数模板时,它会根据实参值推断出实参类型然后将该类型传递给虚拟符号
   cout<<add(1.0f,3.3f);              //    .在函数中经虚拟符号出现的地方用具体类型进行替换,然后就生成了一个真正意义的函数
                                            //2.再发起对该函数进行调用。
	return 0;
}
c++ 复制代码
#include<iostream> 

using namespace std;





//函数模板也支持重载,重载时主要看形参个数,形参类型不需要看 因为虚拟符号可以代指任意类型。


//template<typename T> 
//T add(T a,T b) 
//{
//	
//	return a+b;
//}

//虚拟形参列表中可以定义多个虚拟符号,虚拟形参之间用逗号去隔开
//template<typename T,typename K>
//void test(T a,K b)
//{
//	
//  cout<<a*b;	
//	
//}

//.如果在一个函数模板中你声明了多个虚拟符号,虚拟符号的名字不能重复。
template<typename T,typename K> //在定义函数模板时,你声明的虚拟类型符号,只能在它紧跟的函数内使用,离开这个函数不能再使用这个虚拟符号
void test(T a,K b)
{
	
	auto ret= a*b;	
	cout<<ret;
	
}

//void add(K a)
//{
//	
//}


int main()
{
   //调用函数模板一般有两种方式:1.类型推断 2,显式指定,通过调用函数模板时在<>内来明确指定类型名称,给虚拟形参T
//   cout<< add(1,2); //根据实参值来推断实参类型 将推断出来的类型传递虚拟形参T
//   add<int>(1,1);
//	
//   cout<<add(2.3,3.3);
//   cout<<add(1.0f,3.3f);  
	
	test<int,double>(2,3.3);
	return 0;
}

默认形参

c++ 复制代码
#include<iostream> 

using namespace std;

/*

 int clifd =accept(serid,NULL,NULL); )


*/
void test(int a) //a就叫必须形参,用户在调用该函数时,必须给该形参提供对应的实参值,否则就会造成调用失败。
{
	
	
	
}
//name形参就叫必须形参,country就叫默认形参,用户如果给第二个形参提供了值 就按照提供值参与运算,不提供按照默认值参与运算
//一个函数中用户可以根据需要定义一个或多个默认形参,一个函数中可以既有默认形参 也可以有普通形参
//如果一个函数中既有默认形参 又有普通形参,需要将默认形参定义在普通形参的后边。
void mytest(string name,string country="中国") //给形参变量提供了一个默认值的形参叫默认形参
{
	cout<<name<<country;
	
	
}

////使用的时候,要注意默认形参给函数重载带来的影响。
//void test1(int a=1,int c=2)
//{
//	
//	
//}
//void test1(){}


int main()
{
    	
  test(10);
  mytest("ljs","英国");
  mytest("yangyang");//函数中定义了默认形参,意味调用改函数时,实参对应的默认形参可以提供 也可以不提供,不提供 按默认值处理
	
	return 0;
}





#include<iostream> 

using namespace std;

//带默认形参的函数在做函数原型声明和定义时,只能二选一,定义时指定了默认形参 则声明不能再次指定,如果声明指定了 则定义不需要再次指定,推荐后者。
void mytest(int a,int b=0);

void mytest(int a,int b)
{
	
	
	
}


int main()
{
  mytest(100);
	
	return 0;
}

引用

c++ 复制代码
#include<iostream> 

using namespace std;




int main()
{

	int k=100;
	//引用类型需要和你绑定的变量类型要一致。
	// &在这里叫引用符号 如果&符号前存在数据类型名称 就叫引用符号,如果说&符号前没有数据类型名称 叫取地址符号。
	int &mykk=k; //就是给我们的变量K起了一个新的别名叫mykk;
	
	mykk=mykk+10;//通过引用名进行操作 会影响到该别名绑定变量空间中的值,它也是双向的。
	cout<<k<<endl;
	cout<<&k<<":"<<&mykk;//0x7811ff634:0x7811ff634
	
//	int y=3;
//	int &myy;错误的 ---定义引用名的同时必须要对其初始化,不可以先定义后初始化。
	
	int a,b;
	int *pt;
	pt=&a;//指针是可以改变绑定的变量地址
	pt=&b;
	
//	int x=3;
//	int &mykk=x; //是错的,在同一个作用域下,引用名一旦绑定到某个变量上,就不可以将该名在绑定到其他变量上。人家比较专一
	//引用传参比指针传参要安全。
	//注意:引用是给变量绑定一个别名,不可以对常量构建一个左值引用。
	
	return 0;
}
c++ 复制代码
#include<iostream> 

using namespace std;
/*
 指针传参与引用传参的区别
1)引用传参比指针传参更安全
2)指针可以赋值为NULL,引用不可以。
3)指针可以改变执行,引用一旦被绑定 在同一个作用域下不可以再次绑定到其他变量身上。
4)它们对++的操作含义不一样,指针++是改变指针本身,引用变量++是改变绑定变量空间中的值
5)对sizeof的含义也不一样,对指针加sizeof是代表指针本身所占空间的大小,对引用变量加sizeof代表绑定变量所占空间的大小。
*/

//引用传参不是万能的,不可以完全取代指针传参 比如传递数组,对指针变量本身进行操作来改变指向
//引用类型做函数的形参
void test(int &mykk)//用引用做形参,传参也是双向的,函数内对引用别名的操作是会影响到实参的。
{
	
	mykk=mykk+10;//在函数中操作别名mykk就相当于操作的是a变量
}


int main()
{
   
	int a=100;
	cout<<"before:"<<a<<endl;
	test(a);
    cout<<"after:"<<a<<endl;
	
	return 0;
}
c++ 复制代码
#include<iostream> 

using namespace std;

//1.引用也可以做函数的返回类型
//2.不可以在引用类型的函数中 返回一个非静态变量的引用。
int &mytest()
{
	static int a=100;
	
	return a;
}


int main()
{
//    int a=10;
//	int &myaa=a;
//
//	cout<<myaa;
//	myaa=myaa+1;
//	
//	int b=11;
//	const int &mybb=b; //常引用 目的来保护我们的数据安全,也就是说通过新建的入口可以对绑定变量的空间进行读取 不可以修改。
//	cout<<mybb;
//	mybb=33;是错的
	
	int &pp=mytest();
	cout<<pp;
	return 0;
}
相关推荐
七夜zippoe1 小时前
基于 DolphinDB 构建全流程质量追溯体系:从原材料到成品的全链路追踪
大数据·人工智能·算法·全链路·dolphindb·质量追溯
rannn_1112 小时前
【力扣hot100】238、41、73题解
java·算法·leetcode·开发
QN1幻化引擎2 小时前
认知场的涌现动力学:结构证明、Phi度量与意识签名电池
人工智能·深度学习·神经网络·算法·机器学习·agi
lingran__2 小时前
C++ 高阶数据结构:AVL 树万字详解|原理、四种旋转、key‑value 实现、调试校验、set/map/红黑树 底层前置知识
数据结构·c++·二叉搜索树·平衡二叉树·avl树·红黑树前置
爱和冰阔落2 小时前
【Linux】两个毫无关系的进程怎么通信?命名管道 FIFO 从原理到 Server/Client 实战
android·linux·数据库·c++·vim
码匠许师傅10 小时前
【C++ 面试真题】C++ 的 const 和 constexpr 有什么区别?
c++·面试
坚持编程的菜鸟11 小时前
模拟实现memmove
c语言·算法·模拟实现memmove
wabs66612 小时前
关于图论【最短路径之Dijkstra算法(堆优化版)|卡码网47.参加科学大会的思考】
数据结构·算法·图论·优先级队列·邻接表·小顶堆·卡码网
果果燕13 小时前
实习笔记(一):NFS、Samba、VNC、Git、CMake、systemd、内核、交叉编译
linux·arm开发·c++·笔记·git