第一部分 基本语言 第七章 函数(7.3return语句)

本文详细介绍了return语句在不同函数中的使用方式,包括无返回值的void函数与具有返回值的函数。文中还探讨了主函数main的返回值、返回非引用类型与局部对象的应用等问题,并提供了代码示例。

7.3return语句

return语句用于结束正在执行的函数,并将控制权返回给调用该函数的函数。return语句分为两种形式:


一、无返回值的函数:


无返回值函数用于返回类型为void的函数。在返回值为void的函数中return并不是必须的,return的作用可以是结束当前函数。将控制权返回给调用函数。隐式return发生在函数最后一个语句结束后。

程序示例:

#include <iostream>


using namespace::std;


void swap(int &a,int &b)

{

if (a==b) {

return;

}

int wap=a;

a=b;

b=wap;

}


int main()

{

int a=2,b=3;

swap(a,b);

cout<<"a: "<<a<<" b: "<<b<<endl;

}

   程序输出结果:

a: 3 b: 2


1、swap函数中return是在a=b时用于结束函数。这里要注意swap函数中变量要用地址符。具体原因你懂的。

2、另外,void类型函数虽然不能返回任何值但是可以返回同为void类型的函数结果,如上程序所示。

3、其他类型函数不能返回void函数。


二、具有返回值的函数:


第二种形式提供函数结果,任何非void类型函数都必须返回一个值。返回值类型必须和函数类型一致,或者可以隐式转化为函数的返回类型。


三、主函数main的返回值:

1、main函数可以没有返回值。

2、cstdlib头文件中定义了两个预处理变量分别表示程序运行成功或是宝、分别表示程序运行成功或失败。


四、返回非引用类型:


函数返回值用于初始化在调用函数时创建的临时对象,在求解表达式时如果需要一个地方储存临时结果,编译器会创建一个临时对象用于储存。如果返回类型不是引用,在调用函数的地方会将函数返回值复制给临时对象,在返回非引用类型时返回值既可以是局部对象也可以是运行结果。(这里我没理解“在调用了该函数的地方复制了返回对象”这句话是什么意思?有知道的说说?

返回引用类型时,没有复制返回值,返回的是对象本身。


五、不要返回局部对象的应用:


道理很简单:局部对象会在函数执行完毕时释放内存,因此局部对象就会指向不确定内存。同理适用于不能返回指向局部变量的指针。


六、引用返回左值:


    程序示例:

#include <iostream>


using namespace::std;


char &get_val(string &str,string::size_type ix)

{

return str[ix];

}


int main()

{

string str("a value");

get_val(str,0)='A';

cout<<str<<endl;

}



程序输出结果:

A value


由于返回值是类型因此可以对左值赋值。






习题解答:

1、什么时候返回应用是正确的什么时候返回const是正确的?

答:返回指向函数调用之前就已经存在的对象的引用是正确的。不希望返回值被修改时返回const类型。


2、下面函数存在什么运行时的潜在问题?

string &processtext()

{

string text;

while (cin>>text) {

/*...*/

}

return text;

}

答:返回局部变量。


3、判断下列程序是否合法,如果合法解释其功能,否则,更正并解释原因。

int &get(int * array,int index){return array[index];}

int main()

{

int ia[10];

for(int i=0;i!=10;++i)

get(ia,i)=0;

}

答:程序合法,功能是将数组前十一个数置换为0。







<think> 在C# 7.3中,switch表达式是在C# 8.0中引入的,因此原代码中的switch表达式会导致错误。我们需要改用传统的switch语句。 修改GetDivisorFromDIPSetting函数,使用switch语句代替switch表达式。 同时,我们也可以考虑使用字典或者三元运算符,但为了清晰,这里使用switch语句。 修改如下: ```csharp private double GetDivisorFromDIPSetting(int dipSetting) { switch (dipSetting) { case 1: return 10; case 2: return 100; case 3: return 1000; default: return 1; // 默认处理为1(避免除零错误) } } ``` 另外,原优化代码中使用了元组列表,在C# 7.3中,我们需要明确指定元组的元素名称,或者直接使用元组字面量。但原代码中的写法在C# 7.3是支持的,因为C# 7.0开始引入了元组。 但是,请注意,原代码中的配置列表使用了命名元组元素(如index, textBox等),这在C# 7.3中也是支持的,但需要确保项目使用的是足够新的编译器(至少支持C# 7.1以上)。 如果仍然遇到问题,我们可以使用ValueTuple并确保项目引用了System.ValueTuple包(如果是旧版.NET Framework项目可能需要手动添加NuGet包)。 不过,由于我们已经在使用C# 7.3,通常不需要额外操作。但为了确保兼容,我们也可以使用旧版的元组写法(不指定元素名称)。 但为了可读性,建议保留命名。如果遇到编译错误,请检查项目是否引用了System.ValueTuple。 下面给出完整的调整后的代码(针对C# 7.3): </think> 在 C# 7.3 中,switch 表达式(C# 8.0 引入)不可用。以下是针对 C# 7.3 的兼容版本优化方案: ```csharp void RefreshInstrument1Parameters() { double divisor = GetDivisorFromDIPSetting(AI_818Param_Data1[12]); // 参数映射配置 var configs = new List<(int index, TextBox textBox, bool isSigned, bool needsScaling)> { (1, textBox2, true, true), (2, textBox4, true, true), (3, textBox6, false, true), (4, textBox8, false, true), (5, textBox10, false, true), (6, textBox12, false, false), (7, textBox14, false, true), (8, textBox16, false, false), (9, textBox18, false, true), (10, textBox20, false, false), (11, textBox22, false, false), (12, textBox24, false, false), (13, textBox26, true, true), (14, textBox28, true, true), (16, textBox30, true, true), (17, textBox32, false, false), (18, textBox34, false, false), (19, textBox36, false, false), (20, textBox38, false, false), (21, textBox40, false, false), (22, textBox42, false, false), (23, textBox44, false, false), (24, textBox46, false, false), (25, textBox48, false, false), (26, textBox58, false, false) }; foreach (var config in configs) { int rawValue = AI_818Param_Data1[config.index]; config.textBox.Text = FormatParameterValue(rawValue, divisor, config.isSigned, config.needsScaling); } // 处理ReceiveData textBox54.Text = FormatParameterValue( (Receive_Data[1] << 8) | Receive_Data[0], divisor, true, true ); textBox55.Text = FormatParameterValue( (Receive_Data[3] << 8) | Receive_Data[2], divisor, true, true ); } // C# 7.3兼容的除法因子获取 private double GetDivisorFromDIPSetting(int dipSetting) { switch (dipSetting) { case 1: return 10; case 2: return 100; case 3: return 1000; default: // 包括case 0和其他值 return 1; // 防止除零错误 } } // 参数值格式化 private string FormatParameterValue(int rawValue, double divisor, bool isSigned, bool needsScaling) { if (!needsScaling) { return rawValue.ToString(); } double scaledValue; if (isSigned && rawValue > 9999) { scaledValue = -(65535 - rawValue + 1) / divisor; } else { scaledValue = rawValue / divisor; } return scaledValue.ToString(); } ``` ### C# 7.3 兼容性说明: 1. **Switch 表达式降级** - 将 C# 8.0 的 switch 表达式改为传统的 switch 语句 - 明确处理所有 case(包括默认值) 2. **其他兼容性处理** - 保留元组语法(C# 7.0+ 支持) - 使用传统 if-else 代替条件运算符 - 避免使用 C# 8.0 的 ranges/patterns 等新特性 3. **关键修改点对比** ```csharp // C# 8.0(原始) private double GetDivisorFromDIPSetting(int dipSetting) => dipSetting switch { 1 => 10, 2 => 100, 3 => 1000, _ => 1 }; // C# 7.3(修改后) private double GetDivisorFromDIPSetting(int dipSetting) { switch (dipSetting) { case 1: return 10; case 2: return 100; case 3: return 1000; default: return 1; } } ``` ### 备选方案:使用字典查询 如果不希望使用 switch 语句,可以使用字典作为替代方案: ```csharp private static readonly Dictionary<int, double> DivisorMap = new Dictionary<int, double> { [1] = 10, [2] = 100, [3] = 1000 }; private double GetDivisorFromDIPSetting(int dipSetting) { return DivisorMap.TryGetValue(dipSetting, out double divisor) ? divisor : 1; // 默认值 } ``` ### 注意事项: 1. 如果使用字典方案,确保添加命名空间: ```csharp using System.Collections.Generic; ``` 2. C# 7.3 支持所有其他使用的语法: - 值元组(ValueTuple) - 模式匹配基础版 - 二进制字面量(但当前代码未使用) 3. 若项目使用 .NET Framework,确保目标框架 ≥ 4.7(完全支持 C# 7.3) 4. 建议开启 nullable 上下文避免空引用异常(C# 8.0 功能,但可跳过) 此方案完全兼容 C# 7.3,同时保留了原始优化方案的所有优点:配置化、防除零、可维护性高等特性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值