C++之返回类型用法及return语句介绍

 更新时间:2026年06月06日 10:38:46   作者:春风吹又生丶  
这篇文章主要介绍了C++之返回类型用法及return语句,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

返回类型和return语句

return 语句的作用是终止一个函数的执行,结束当前代码块中return后的语句,即return后的语句不再执行,从当前位置退出函数。

return语句有两种形式:

return;
return expresion;

无返回值函数

没有返回值的return语句只能用在返回类型是void的函数中。

返回void的函数不要求非得有return语句,因为这类函数的最后一句后面会隐式执行return

// example
void swap(int &v1, int &v2){
	// 如果两个值是相等的,则不需要交换,直接退出
	if(v1 == v2){
		return ;
	}
	// 如果执行到了这里,说明还需要继续完成某些功能
	int tmp = v2;
	v2 = v1;
	v1 = tmp;
	// 这里无须显示的return语句
}

强行另void函数返回其他类型的表达式将会产生编译错误!!

有返回值函数

return语句的第二种形式提供了函数的结果。只要函数的返回类型不是void,则该函数内的每条return语句必须返回一个值。return语句返回值类型必须与函数的返回类型相同,或者能够隐式地转换成函数的返回类型。

尽管编译器无法确保结果的正确性,但是可以保证每个return语句的结果类型正确。例如:

// 因为含有不正确的返回值 ,所以这段代码无法编译通过
bool str_subrange(const string &str1, const string &str2){
	// 大小相同,此时用普通的相等性判断结果作为返回值
	if(str1.size() == str2.size()){
		return str1 == str;		// 正确:==运算符返回的是布尔值
	}
	auto size = (str1.size() < str2.size()) ? str1.size() < str2.size();
	
	// 检查两个string对象的对应字符是否相等,以较短的字符串长度为限
	for(decltype(size) i = 0;i != size; ++i){
		if(str1[i] != str2[i])
		return ;	// 错误:没有返回值,编译器将会报告这一错误
	}
	// 错误:控制流可能尚未返回任何值就结束了函数的执行
	// 编译器可能检查不出来这一错误!
}

注意!含有return语句的循环后面应该也要有一条return语句,如果没有那么程序就是错误的!很多编译器都无法发现此类错误!

值是如何被返回的

返回一个值的方式和初始化一个变量或形参的方式完全一样:返回值是初始化调用点的一个临时量,该临时量就是函数调用的结果

string make_plural(size_t ctr, const string &word, const string &ending){
	return (ctr > 1) ? word + ending : word;
}

该函数的返回类型是string,意味着和返回值将被拷贝到调用点。因此,该函数将返回word的副本或者一个未命名的临时string对象,该对象的内容是word和ending的和

const string &shorterString(const string &s1, const string &s2){
	return s1.size() <= s2.size() ? s1: s2;
}

其中形参和返回类型都是const string的引用,不管是调用函数还是返回结果都不会真正拷贝string对象

不要返回局部对象的引用或指针

函数完成后,它所占用的存储空间也会随之被释放掉。因此,函数终止意味着局部变量的引用将指向不再有效的内存区域

// 严重错误:这个函数试图返回局部对象的引用
const string &manip(){
	string ret;
	if(!ret.empty())
		return ret;			// 错误,返回局部对象的引用!
	else
		return "empty";		// 错误,"empty”是一个局部变量!
}

在第二条return语句中,字符串字面值转换成一个局部临时string对象,对于manip来说,该对象和ret一样都是局部的。

引用返回左值

函数的返回类型决定函数调用是否是左值。调用一个返回引用的函数得到左值,其他返回类型得到右值。可以像使用其他左值那样来使用返回引用的函数调用,特别是,能为返回类型是非常量引用的函数的结果赋值:

char &get_val(string &str, string::size_type ix){
	return str(ix);	// get_val假定索引值是有效的
}

int main(){
	string s("a value");	// 输出a value
	cout << s << endl;		// 将s[0]的值改为A
	get_value(s, 0) = 'A';	// 输出A value
	cout << s << endl;	
	return 0;
}

把函数调用放在赋值语句的左侧可能看起来会有点奇怪,但其实没什么特别的!返回值是引用,因此调用是个左值,和其他左值一样他也能出现在复制运算符的左侧

列表初始化返回值

C++11新标准规定,函数可以返回花括号包围的值的列表。类似于其他返回结果,此处的列表也用来对表示函数返回的临时量进行初始化。如果列表为空,临时量执行值初始化;否则,返回的值有函数的返回类型决定。

vector<string> process(){
	// ...
	// expected  actual是string对象
	if(expected.empty()){
		return {};
	}
	else if(expected == actual)
		return {"functionX", "okay"};
	else 
		return {"functionX", expected, actual};
}

如果函数返回的是内置类型,则花括号包围的列表最多包含一个值!而且该值所占空间不应该大于目标类型的空间!如果函数返回类型是类类型,由类本身定义初始值如何使用。

主函数main的返回值

如果函数的返回类型不是void,那么必须返回一个值。但是这条规定有个例外:我们允许main函数没有return语句直接结束。如果控制到达了main函数的结尾处而且没有return语句,编译器将隐式地插入一条返回0的return语句

main函数的返回值可以看作是状态指示器。返回0表示执行成功,返回其他值表示执行失败,其中非0值的具体含义根据机器来定!

返回数组指针

因为数组不能拷贝,所以函数不能返回数组。不过,函数可以返回数组的指针或引用!要想定义一个返回数组的指针或者引用的函数比较繁琐,但可以使用类型别名来简化这一任务!

typedef int arrT[10];	// arrT是一个类型别名,表示的类型含有10个整数的数组
using arrT = int [10];	// arrT的等价声明
arrT* func(int i);		// func返回一个指向含有10个整数的数组的指针

arrT是含有10个整数的数组别名。因为无法返回数组,所以将返回类型定义成数组的指针。因此,func函数接收一个int实参,返回一个指向包含10个整数数组的指针。

声明一个返回数组指针的函数

​ 首先要区分以下的不同:

int arr[10];			//arr是一个含有10个整数的数组
int *p1[10];			//p1是一个含有10个指针的数组	数组中的值是指针
int (*p2)[10] = &arr;	//p2是一个指针,它指向含有10个整数的数组

返回数组指针的函数形式如下所示:

Type (*function(parameter_list))[dimension];
// example
int (*func(int i))[10];

可以按照以下顺序来逐层理解该声明的定义:

  • func(int i) 调用func函数时需要int类型实参
  • (*func(int i)) 对函数调用的结果进行解引用操作
  • (*func(int i))[10] 解引用func的调用将得到一个大小是10的数组
  • int (*func(int i))[10]; 表示数组中的元素时int类型
#include<iostream>
using namespace std;

int (*func(int k))[10] {
	int (*p)[10];
	for(int i=0;i<k;i++){
		(*p)[i] = i;
	}
	return p;
}
int main() {
	int (*a)[10];
	a = func(10);
	for(int i=0; i<10; i++) {
		cout << (*a)[i] << " ";
	}
	return 0;
}

使用尾置返回类型

C++11新标准有一种能简化上述声明的方法,就是使用尾置返回类型。然和函数的定义都能使用位置返回,但是这种形式对于返回类型比较复杂的函数最有效,比如返回类型是数组或者数组的引用。为了表示函数真正的返回类型跟在形参列表之后,应该要在本应该出现返回类型的地方放置一个auto

// func接受一个int类型的实参,返回一个指针,该指针指向含有10个整数的数据
auto func(int i) -> int(*)[10];

把函数的返回类型放在形参列表之后,可以清楚地看到func函数返回是一个指针,并且该指针指向了含有10个整数的数组。

使用decltype

假设一直到函数返回的指针指向哪个数组,就可以使用decltype关键字声明返回类型。

例如,下面的函数返回一个指针,该指针根据参数i的不同指向两个已知数组的某一个:

int odd[] = {1,3,5,7,9};
int even[] = {2,4,6,8,10};
// 返回一个指针,该指针指向含有5个整数的数组
decltype(odd) *arrPtr(itn i){
	return (i%2) ? &odd : &even;
 }

arrptr使用关键字decltype表示它的返回类型是个指针,并且该指针所指向的对象与odd类型一致。

需要注意的是,decltype并不负责把数组类型转换成对应的指针,所以decltype的结果是个数组,想要表示arrptr返回指针,还必须在函数声明时加一个*符号。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 基于C语言fflush()函数的使用详解

    基于C语言fflush()函数的使用详解

    本篇文章是对C语言中fflush()函数的使用进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • 最新VScode C/C++ 环境配置的详细教程

    最新VScode C/C++ 环境配置的详细教程

    这篇文章主要介绍了最新VScode C/C++ 环境配置的详细教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • 彻底掌握C语言strcpy函数的用法

    彻底掌握C语言strcpy函数的用法

    C语言中的strcpy函数,是一种C语言的标准库函数,它用于对字符串进行复制。本章带你了解它的使用并模拟实现它
    2022-05-05
  • C++ Eigen库计算矩阵特征值及特征向量

    C++ Eigen库计算矩阵特征值及特征向量

    这篇文章主要为大家详细介绍了C++ Eigen库计算矩阵特征值及特征向量,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-06-06
  • C语言实现合并字符串

    C语言实现合并字符串

    今天小编就为大家分享一篇C语言实现合并字符串,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • 详解C++标准库中处理正则表达式的类std::regex

    详解C++标准库中处理正则表达式的类std::regex

    std 是 C++ 标准库的命名空间,包含了大量标准的 C++ 类、函数和对象,这些类和函数提供了广泛的功能,包括输入输出、容器、算法、字符串处理等,这篇文章主要介绍了C++标准库中提供的用于处理正则表达式的类std::regex,需要的朋友可以参考下
    2024-03-03
  • C++ 配置文件管理神器 yaml-cpp 实战指南

    C++ 配置文件管理神器 yaml-cpp 实战指南

    本文主要介绍了C++ 配置文件管理神器 yaml-cpp 实战指南,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2026-05-05
  • C++多重继承二义性原理实例解析

    C++多重继承二义性原理实例解析

    这篇文章主要介绍了C++多重继承二义性原理实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • 深入理解C++中的vector类的用法及特性

    深入理解C++中的vector类的用法及特性

    vector直接翻译过来为向量,在C++中为封装动态数组的容器,且有序,需要的朋友可以参考下
    2016-05-05
  • C语言互换最大值与最小值的位置

    C语言互换最大值与最小值的位置

    大家好,本篇文章主要讲的是C语言互换最大值与最小值的位置,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01

最新评论