函数(局部静态对象,参数传递,默认参数,占位参数,函数重载),函数返回值,main函数外界输入参数

目录

1.局部静态对象(static)

2.参数传递(值传递,地址传递,引用传递)

2.1值传递:

2.2引用传递 :

2.3地址传递

2.4数组作为实参

3.函数的默认参数

4.占位参数

5.函数重载(函数名可以相同,提高复用性)

6.函数返回值

 7.返回值为引用类型

 8.返回值为数组:

9.main函数接受外界参数


1.局部静态对象(static)

      在程序的执行路径第一次经过对象定义语句时初始化,并且直到程序终止才被销毁,在此期间即使对象所在的函数结束执行也不会对它有影响。

注:静态对象只在第一次执行到定义语句时创建出来,之后即使函数执行结束,它的值依然保持;下一次函数调用时,不会再次创建、也不会重新赋值,而是直接在之前的值基础上继续叠加。

void callCount()
{
	static int cnt = 0;    // 静态对象只会创建一次
	cout << "我被调用了" << ++cnt << "次!" << endl;
}

int main()
{
	//cout << cnt << endl;    // 错误,局部变量在作用域外不可见
	callCount();     //1
	callCount();	 //2
	callCount();	 //3
	cin.get();
}

2.参数传递(值传递,地址传递,引用传递)

值传递时,函数实参不变

地址传递时,函数的实参发生变化

引用传递时,函数的实参发生变化,常量引用为形参时,实参不会发生变化:

2.1值传递:

 直接将一个实参的值,拷贝给形参做初始化的传参方式,就被称为“值传递”,

相当于将实参的值拷贝给形参 

缺点:实际应用中,很多时候函数要操作的对象可能非常庞大,如果做值拷贝会使得效率大大降低;这时使用引用就是一个好方法。 

2.2引用传递 :

 常量引用作为形参,实参既可以是常量,也可以是变量

// 比较两个字符串的长度
bool isLonger(const string & str1, const string & str2)
{
	return str1.size() > str2.size();
}

int main()
{
	string str1 = "hello", str2 = "worlds";
	const string cstr1 = "jia", cstr2 = "li";
	cout << isLonger(str1, str2) << endl;     实参是变量
	cout << isLonger(cstr1, cstr2) << endl;   实参既是常量
	cin.get();
}

2.3地址传递

//地址传递示例

#include<iostream>
using namespace std;
void swap(int *p1,int *p2) {
	 int tem = *p1;
	*p1 = *p2;
	*p2 = tem;
}

int main() {
	int a = 5, b = 10;
	swap(&a, &b);
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	system("pause");
	return 0;

}

2.4数组作为实参

值传递:数组是不允许做直接拷贝的,因此不能使用值传递

地址传递: 

void printArray(const int* arr, int size){
}

printArray(arr);   //数组名就为其地址

 引用传递:

// 使用数组引用作为形参
void printArray(const int(&arr)[5])
printArray(arr);

3.函数的默认参数

     1.如果某个位置参数有默认值,那么从这个位置往后,从左向右,必须要有默认值。
     2.如果函数的声明有默认值,函数实现(定义)的时候就不能有默认参数。即声明和实现只能有一个有默认参数。
     3.如果我们自己传入参数,就用我们的传入参数,如果没有,就用默认值

4.占位参数

     语法: 返回值类型  函数名(数据类型){函数体}   eg:void func(int){}

     1.占位参数还可以有默认参数 eg:void func(int = 10){}

5.函数重载(函数名可以相同,提高复用性)

函数重载满足条件:

        1.同一个作用域下

        2.函数名称相同

        3.函数参数 类型不同 或者 个数不同 或者 顺序不同

        注意:函数的返回值不同不可以作为函数重载的条件

引用可以作为重载条件

//函数重载

#include<iostream>
using namespace std;

//形参&c为引用
void func(int &c) {
	cout << "&c为引用" << endl;
}

void func(const int &c) {
	cout << "const  &c为引用" << endl;
}

int main() {
	int a = 5, b = 10;
	func(a);   //传入实参a时, int &c = a
	func(10);  //传入实参10时,const int &c = 10
	system("pause");
	return 0;
}

6.函数返回值

返回值原理:

函数在调用点会创建一个“临时量”,用来保存函数调用的结果。当使用return语句返回时,就会用返回值去初始化这个临时量。 一下函数,假设str1更长,所以将用str1对一个string临时量做初始化,执行的是值拷贝。最终返回的值,是str1的一个副本。

显然做值拷贝并不高效。使用引用类型来做返回值的传递,这样就可以避免值拷贝。

string longerStr(const string& str1, const string& str2)
{
	return str1.size() > str2.size() ? str1 : str2;
}

 7.返回值为引用类型

使用引用类型来做返回值的传递,这样就可以避免值拷贝。 

// 返回一个string常量对象的引用,不做值拷贝
const string & longerStr(const string& str1, const string& str2)
{
	return str1.size() > str2.size() ? str1 : str2;
}

 注意:不能返回函数内局部变量的引用,或返回指向局部对象的指针,因为局部对象,函数执行完成后就销毁了​​​​​​​。如下

错误的情况
const string & f()
{
	string str = "test";
	return str;
}

 8.返回值为数组:

由于数组“不能拷贝”的特点,函数也无法直接返回一个数组。同样的,我们可以使用指针或者引用来实现返回数组的目标;通常会返回一个数组指针。 

int arr[5] = { 1,2,3,4,5 };
int* pa[5];        // 指针数组,pa是包含5个int指针的数组
int(*ap)[5] = &arr;    // 数组指针,ap是一个指针,指向长度为5的int数组
int(*fun(int x))[5];    // 函数声明,fun返回值类型为数组指针

这里对于函数fun的声明,我们可以进行层层解析:

  1. fun(int x) :函数名为fun,形参为int类型的x;
  2. ( * fun(int x) ):函数返回的结果,可以执行解引用操作,说明是一个指针;
  3. ( * fun(int x) )[5]:函数返回结果解引用之后是一个长度为5的数组,说明返回类型是数组指针;
  4. int ( * fun(int x) )[5]:数组中元素类型为int

数组指针的定义比较繁琐,为了简化这个定义,我们可以使用关键字typedef来定义一个类型的别名:

typedef int arrayT[5];    // 类型别名,arrayT代表长度为5的int数组
arrayT* fun2(int x);      // fun2的返回类型是指向arrayT的指针

9.main函数接受外界参数

#include <iostream>
using namespace std;

//argc 代表argument cout, 参数数量
//argv 代表argument vector, 参数列表
int main(int argc, char** argv)
{
    cout << "argc is" << argc <<endl;
    for(int i = 0; i < argc; i++){
        cout << "argv[i] is "<< argv[i]  <<endl;   
        cout << "i is" << i <<endl;
    
    }
    return 0;
}


运行时,在VScode终端输入以下指令:
 /home/rui/VScode/release/main arc1 2 3
第一个参数为此文件生成的执行文件路径,此指令包括4个参数(路径也是参数)
参数列表argv为[/home/rui/VScode/release/main, arc1, 2, 3]

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值