C++的学习之旅——函数

目录

一、函数的基本知识

1、定义函数

2、缺省参数(即给参数一个默认值) 

二、函数和数组

三、函数与C-风格字符串

1、将C-风格字符串作为参数的函数

2、返回C-风格字符串的函数

四、函数和结构

1、传递和返回结构

2、传递结构的地址

五、函数和string对象

六、函数与array对象

七、递归

八、函数指针


一、函数的基本知识

1、定义函数

函数的基本定义与C语言相同

可以将函数分为两大类:没有返回值和有返回值的函数。没有返回值的函数称为void函数,其通用格式如下: 

void functionName(parameterList)
{
    statements
    return;
}

 parameterList为传递给函数的参数列表,statements为函数执行的内容。

 对于有返回值的函数,通用格式如下: 

typename functionName(parameterList)
{
    statements
    return parameter(typename 类型);
}

2、缺省参数(即给参数一个默认值) 

C++支持缺省函数(如果没有指定实参则使用缺省值,有则使用指定实参),不过有如下注意事项

①默认实参必须在参数列表的结尾

②默认参数只能出现在函数声明或者定义二选一中

③缺省值必须是常量或全局变量

④缺省参数必须是值传递或者常参传递

(1)全缺省参数

#include <iostream>

using namespace std;

void test(int a = 1, int b = 2, int c = 3)
{
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl;
}

int main()
{
	test();//全缺省参数,参数可传可不传,传递的参数从左到右传递
	test(5);
	test(15, 25);
	test(35, 45, 55);
	return 0;
}

此时函数的所有参数都有默认值,若没有传参给函数,编译器会使用默认参数列表中的参数。但是这里需要注意的是:如果传参时只传了部分参数,那么该值会被从左至右匹配

(2)半缺省函数

#include <iostream>
using namespace std;

void test(int a, int b = 1, int c = 2) {
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl;
}

int main() {
	test(10);   
    /* 半缺省:从右往左连续地缺省一部分参数
       a - 必须传 (因为没缺省)
       b - 可传可不传 (因为缺省了)
       c - 可传可不传 (因为缺省了)
    */
	return 0;
}

函数的部分参数有默认值,部分缺省,半缺省参数必须 从右往左 依次给出,不能间隔着给。

二、函数和数组

可以将数组作为函数参数进行传递,传递格式为:

typename functionName(typename name[])
{
    statements
    return parameter(typename 类型);
}

如:
int sum_arr(int arr[],int n)
{
    for(int i=0;i<n;i++)
    cout<<arr[i]<<endl;
    return a;
}

当然,也可以使用二维数组作为参数

三、函数与C-风格字符串

1、将C-风格字符串作为参数的函数

表示字符串的方式有三种:

①char 数组

②用引号括起的字符串常量

③被设置的字符串的地址的char指针(传递的实际是字符串的第一个字符地址,所以是char类型指针)

常用格式为:

typename name(char * name)
{
    statement
    return parameter(typename 类型); 
}

传递的参数不一定为数组名,还可以是其他类型的指针

2、返回C-风格字符串的函数

函数无法返回一个字符串,但是可以返回字符串的地址,常用格式如下: 

char * name(char * name)
{
    statement
    return parameter(char * 类型); 
}

如:
char * buildstr(char c,int n)
{
    char * pstr=new char[n+1];//开辟动态内存空间
    pstr[n]='\0';
    while(n-->0)
        pstr[n]=c;
    return pstr;
}

四、函数和结构

当结构比较小时,可以使用按值传递结构,结构比较大时,使用指针传递结构

1、传递和返回结构

使用一个例子来说明,将三个时间相加

#include <iostream>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;

//创建时间结构
struct travel_time
{
	int hours;
	int mins;
};

const int Mins_per_hr=60;

travel_time sum(travel_time t1,travel_time t2);
void show_time(travel_time t);

int main(int argc, char** argv) {
	
	travel_time day1={5,45};//时间1
	travel_time day2={4.55};//时间2
	
	travel_time trip=sum(day1,day2);
	cout<<"Two-day total:";
	show_time(trip);
	
	travel_time day3={4,32};//时间3
	cout<<"Three-day total:";
	show_time(sum(trip,day3));

	return 0;
}

travel_time sum(travel_time t1,travel_time t2)//时间加法 
{
	travel_time total;
	total.hours=t1.hours+t2.hours+(t1.mins+t2.mins)/Mins_per_hr;
	total.mins=(t1.mins+t2.mins)%Mins_per_hr;
	return total;
}

void show_time(travel_time t)//打印时间 
{
	cout<<t.hours<<"hours,"<<t.mins<<"minutes"<<endl;
}

 

函数travel_time sum 返回一个travel_time结构

2、传递结构的地址

传递结构的地址而不是整个结构以节省时间和空间,传递结构指针有如下注意事项:

①将结构的地址(&t)而不是结构本身(t)传递给它

②将形参数声明为指向travel_time的指针,即travel_time*类型。由于函数不应该修改结构,则使用了const 修饰符

③形参是指针而不是结构,则需要使用间接成员运算符(->),而不是成员运算符(句点)。

则函数show_time修改如下:

void show_time(const travel_time * str)//打印时间 
{
	cout<<str->hours<<"hours,"<<str->mins<<"minutes"<<endl;
}

五、函数和string对象

可以使用string对象进行传参,当需要多个字符时,还可以声明string对象数组,进行传参

#include <iostream>
#include <string>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;

const int SIZE=5;
void display(const string sa[],int n);

int main(int argc, char** argv) {
	
	string list[SIZE];//string对象数组
	cout<<"Enter your "<<SIZE <<" favorite astronomical sights:\n";//打印 
	for(int i=0;i<SIZE;i++)//输入五个天文景点的字符串 
	{
		cout<<i+1<<": ";
		getline(cin,list[i]);
	}
	
	cout<<"Your list:\n";
	display(list,SIZE);

	return 0;
}

void display(const string sa[],int n)//打印景点字符串 
{
	for(int i=0;i<n;i++)
	{
		cout<<i+1<<": "<<sa[i]<<endl;
	}
}

六、函数与array对象

使用array类需要添加头文件array,可以使用按值传递array对象,或者传递指针,下面一个例子使用array对象存储一年四季的开支

#include <iostream>
#include <string>
#include <array>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;

const int Seasons=4;
const array<string,Seasons> Snames={"Spring","Summer","Fall","Winter"};//创建包含4个季节string对象的array对象 

void fill(array<double,Seasons>*pa);

void show(array<double,Seasons>da);

int main(int argc, char** argv) {
	
	array<double,Seasons> expenses;
	fill(&expenses);
	show(expenses);

	return 0;
}

void fill(array<double,Seasons>*pa)//传递指针 
{
	for(int i=0;i<Seasons;i++)
	{
		cout<<"Enter "<<Snames[i]<<" exprense: ";
		cin>>(*pa)[i];
	}
}

void show(array<double,Seasons> da)//传递对象 
{
	double total=0.0;
	cout<<"\nEXPENSES\n";
	for(int i=0;i<Seasons;i++)
	{
		cout<<Snames[i]<<":$"<<da[i]<<endl;
		total+=da[i];
	}
	cout<<"total exprense:$"<<total<<endl;
}

七、递归

递归即函数自己调用自己,与C语言的递归相同,不过C++不允许main()调用自己。这里简单介绍它是如何工作的。使用递归函数的一般格式如下:

void recurs(argumentlist)
{
    statement
    if(test)
    {
        recurs(argument)
    }
    statement
}

 test最终变成false则跳出调用。

八、函数指针

在程序定义一个函数,编译时会把函数的源代码转换为可执行代码并分配一段存储空间,该存储空间有一个起始地址,为函数的入口。调用函数时,从地址入口开始执行此段函数代码。函数名代表函数的起始地址,即为函数的指针。定义一个指向函数的指针变量格式为:

int (*p)(int,int);

表示p为一个指向函数的指针变量,它可以指向函数类型为整型且有两个整形参数的函数。

可以用函数指针变量调用函数,或者指向函数的指针作函数参数,这样第一个函数可以通过函数指针在其代码块里面使用我们传递给它的函数


C++的学习笔记持续更新中~

要是文章有帮助的话

就点赞收藏关注一下啦!

感谢大家的观看

欢迎大家提出问题并指正~

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C++ 默认构造函数是在没有显式定义构造函数的情况下自动生成的特殊成员函数。它通常用于在创建对象时进行初始化操作。默认构造函数无参数,不接受任何实参。当我们通过调用类的构造函数来创建对象时,如果没有提供实参,则编译器会自动调用默认构造函数。 默认构造函数的作用是确保对象的所有成员变量都被正确初始化。例如,如果一个类有一个int类型的成员变量,那么在默认构造函数中,可以将该成员变量初始化为0。如果没有默认构造函数,当我们创建对象时,该成员变量可能会未被初始化,导致程序运行时出现意外结果。 另一个重要的地方是,当我们定义了类的其他构造函数时(比如有参数的构造函数),默认构造函数依然会被生成。这是因为在某些情况下,我们可能只想使用默认构造函数来创建对象,而不希望传递实参。此时,默认构造函数就能满足需求。当我们重载构造函数时,可以使用默认参数来实现默认构造函数的功能。 需要注意的是,默认构造函数在一些特殊情况下可能不会被生成。例如,如果我们显式定义了有参数的构造函数,但没有提供默认构造函数,那么编译器将不会自动生成默认构造函数,这意味着我们不能再使用无参的方式来创建对象。 总之,理解C++默认构造函数的作用和用法对于编写高质量的代码至关重要。它可以帮助我们确保对象的正确初始化,并且在一些特殊情况下可以提供方便的使用方式。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IC 1396

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值