`
lovnet
  • 浏览: 6707806 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

C++与C#对比学习:函数(二)返回值,默认实参.this指针

 
阅读更多

函数返回值

我们定义函数时会指定一个返回值类型,那在函数体中必须返回一个匹配的类型,或者隐式转换后能匹配的类型.不过有时存在这样的情况,如果函数体中存在一些分支语句,有些情况是可以返回一个值,但有时不会返回值.还是举个例子吧.

有如下C++函数

int FunArwen(int a , int b)

{

if(a < b)

return 888;

}

很显然,上面的函数有时会返回一个值,但有时又不会.

int result = FunArwen(4,5); //这时结果是888;

int res= FunArwen(5,4);

//这时函数不会有返回值,不过我在VS中运行得到res为5,貌似返回了第一个参数的值.不知道为啥是这个值,没太搞懂.

//不过反正这肯定是个错误的结果.

在C++中上面的函数编译时会有一个警告信息"not all control paths return a value",而在C#中上面的函数不能通过编译的,会报错,"not all code paths return a value".

你必须写成if (a < b) return 888 ;

else return 44;

或者if(a < b) return 888; return 444;

这样才能编译通过

C#针对C++中的很多地方都做了一些改进,多做了一些检查.使你写出来的代码更不容易出错.其实一个编程语言的发展很多时候关注的一是,简化一些复杂的语法,使你能用更少的代码实现更多的功能.另一个是多做一些检查,要编译期间就给你检查出一些错误来.当然准确的讲有些错误也不是真正的错误,只要有潜在的犯错可能就当作错误处理了.

我们平时不是常讲软件测试嘛,其实编译器做的工作也算是测试的一种,给你把代码中的语法错误找出来.如果任何错误都能在编译期间都找出来自然是最完美的,不过编译器可没这么聪明.很多运行时错误它是没法检测出来的.

C++返回局部函数体中局部变量指针或引用的问题

另外值得注意的是在C++中如果返回结果是函数体中的局部指针或引用类型.则会出错,因为函数体中的局部变量一超过作用域就会被释放了.所以指针就变成野指针了.不知道指到哪去了.举个例子

int* GetResult( )

{

int num = 110;

int* ip = &num;

return ip;

}

int* p = GetResult(); //这样做是错误的,不过有时错误的操作也会得到正确的结果.

//你运行时可能出现运行时错误,可能运行正确得到个错误的结果,有时还可能得到正确的结果.反正我在VS中试的时候是得到个正确的结果的.

因为num超出作用域之后就告诉系统那块内存它不要了,系统可以把那内存分配给别人用了.不过如果那内存暂时还没被分给谁,那里面的值还仍然在,所以你通过指针去访问那个值时可能还能得到个正确的值

默认实参

假如某个函数的参数有很多个,我们调用时要传那么多个参数进去非常麻烦,而且有些参数不那么重要,我们整个啥默认值就行.你首先想到的可能是来个函数重载,整很多个函数出来,但参数个数都不一样.显然这确实是一个办法.但实现的不够优美.在C++中有个默认实参的做法能更好的解决这问题.举例

void Register(string userName = "打酱油的"

,string pwd = "123"

, int age = 18

)

{

//do something

}

这样我们调用函数时可以像下面那样

Register();

Register("arwen");

Register("arwen","911");

Register("weiwen","110",24);

上面那样调用都正确,不过你这样调用就不行

Register("wei", 24); //会出错.因为系统是从左到右去匹配.你传两个参数它只会去匹配userName和pwd

C#中没有默认实参

不过有点遗憾的是C# 2.0, 3.0中都没有提供这个功能.据说c# 4.0有提借这功能.不过我还从没用过4.0.微软的东西更新太快,要老想去跟着赶时髦会很累的啊.还是老实的把基础打好再说

This 指针

举个例子,有C++类Arwen

class Arwen

{

private:

int age;

int height;

public:

void SetAge(int age)

{

this ->age = height;

}

void SetHeight(int hgt)

{

height = hgt;

}

}

Arwen wen;

int hgt = 111;

wen.SetHeight(hgt); //我们知道每个类的函数跟static变量一样是不属于某个实例的,所以的实例对象都使用共一个函数.函数是保存在代码区.那我们这样调用函数时,怎么能找到函数呢?实际上你像上面这样调用一个函数时编译器会默认把它 转换成

Arwen::SetHeight(&wen , hgt);

然后给height赋值就是这样 wen.height = hgt; //默认情况都是给自成员变量前加个实例对象做前缀.&wen也就是this指针了.

但如果成员变量和传的参数同名了就必须显式加this指针.

像SetAge中 this->age = age;

const函数

我们可以在函数后面加个const,例如void SetAge(int age) const { this->age = age;}

Arwen wen;

int age = 222;

wen.SetAge(age); //此时出错了.

因为编译器把上面的调用中的this指针转化成指向const类型的指针了,所以不用this->age = age;这样去修饰指针指向的值了.

C#中的this的用法和原理跟C++差不多.虽然C#中没有指针的概念,但我猜实际上后台很多实现最终都是通过指针实现的.估计C#的编译器也是用C++和C开发的吧.连微软的操作操作都是C++和C开发的.

分享到:
评论

相关推荐

    61.java实参.zip

    61.java实参.zip61.java实参.zip61.java实参.zip61.java实参.zip61.java实参.zip61.java实参.zip61.java实参.zip61.java实参.zip61.java实参.zip61.java实参.zip61.java实参.zip61.java实参.zip61.java实参.zip61....

    传递实参.html

    传递实参.html

    C语言程序设计-函数参数和返回值.pptx

    函数参数和返回值 2-1 函数参数 函数的参数分为形参和实参两种: 形参出现在函数定义中,在整个函数体内都可以使用,离开该函数则不能使用。 实参出现在主调函数中,进入被调函数后,实参变量也不能使用。 形参和...

    [原创]自己工作中常用的模板库,简化你的工作

    ★ 当把"智能指针/stl迭代器/C指针/前三者嵌套"都视为指针时,其内的最终值(非指针值)是一致的,在模板函数中,某些场景需要取得其最终的非指针值。 应用场景:转发模板函数,如 template&lt;typename T&gt; void ...

    C++——有默认参数的函数.txt

    函数调用时形参从实参那里取值,so实参与形参一致,有时多次调用同一函数用同样的实参,可以直接给形参一个默认的值,这样形参不必从实参取值; 举例: 函数声明 float area(float r=6.5)//就是制定r的默认值是6.5...

    C/C++ 函数调用与函数返回值

    函数参数与函数调用  1、函数调用的作用:  ·用实参数向形式参数传递数据;  ·为获得数据参数及在函数体中声明的变量分配存储空间;  ·中断现行(调用)函数,把流程向被调用函数的入口处,开始执行被调...

    JavaScript程序设计课件:函数的调用方式.pptx

    一般形式的函数调用,是常见的函数调用方式,一般用于“没有返回值的函数”。 语法: 函数名称([参数1, 参数2, ……]) [参数1,参数2…]是可选的,用于表示实参列表,其值可以是零个、一个或多个。 5.2.2 函数的...

    【Matlab基础】自定义函数.docx

    在主程序中通过函数名和实参调用它,通过接口(即函数的输入、输出参数)来实现“通讯”。所以在调用函数时,你只要知道“被调用的函数是用来做什么的”,以及“如何对应它的输入、输出参数”就行了。 关于形参...

    Java程序设计基础:一维数组应用数组作为方法实参.pptx

    1 2 3 4 5 [0] [1] [2] [3] [4] args 0x3bc257 average 0x3bc257 array sum 0.0 15.0 3.0 数组地址 0x3bc257 int[ ] array = myList ...但是,基础类型作为方法参数时,形参值改变不会影响主调方法中的基本类型实参值。

    C++对象和指针的引用

    当对一个对象调用成员函数时,编译程序先将对象的地址赋给this指针,然后调用成员函数,每次成员函数存取数据成员时,由隐含作用this指针。而通常不去显式地使用this指针来引用数据成员。同样也可以使用*this来标识...

    Python程序基础:函数基本概念.pptx

    定义函数时,圆括号内是使用逗号分隔的形式参数列表(简称形参),调用函数时向其传递实参,根据不同的参数类型,将实参的值或引用传递给形参。;但当参数类型为可变数据类型(如列表、字典、集合等)时,在函数内部...

    C/C++中关于局部函数中更新实参指针的方法

    在C语言中因为参数的传递方式属于值传递,局部参数在函数内部的改变并不会影响实参的值,有时候为了保存对在函数中的修改,往往采用返回值或者指向指针的指针的形式来实现,我就采用简单的内存分配来说明。...

    C++的那些事:函数全解析

    二是函数的声明,它与函数的定义相比,没有了函数体部分;三则是函数的调用。当然,不同的函数定义可以还会稍有不同,比如类的成员函数、内联函数等。这里我们主要讨论函数的调用时需要注意的一些问题。我们将函数...

    [Visual.C++.2010入门经典(第5版)].Ivor.Horton.part1

    5.2.2 给函数传递指针实参 217 5.2.3 给函数传递数组 219 5.2.4 给函数传递引用实参 222 5.2.5 使用const修饰符 224 5.2.6 rvalue引用形参 225 5.2.7 main()函数的实参 227 5.2.8 接受数量不定的函数实参 229 5.3 从...

    深入理解C++11:C++11新特性解析与应用

    402.10 final/override控制 442.11 模板函数的默认模板参数 482.12 外部模板 502.12.1 为什么需要外部模板 502.12.2 显式的实例化与外部模板的声明 522.13 局部和匿名类型作模板实参 542.14 本章小结 55第3章 通用为...

    C语言教程,大学教材,Turbo C2.0 基础学习

    第三章 基本数据类型、运算符与输入输出函数...….....…..…….…....…......…............67 3.1 基本数据类型...….....…..……………….....…....…..…....….......….......………....67 3.2 常量……...

    Python 变量的引用-调用函数传递实参的引用

    Python解释器易于扩展,可以使用C语言或C++(或者其他可以通过C调用的语言)扩展新的功能和数据类型。Python也可用于可定制化软件中的扩展程序语言。Python丰富的标准库,提供了适用于各个主要系统平台的源码或机器...

    c++将引用或者是指针作为函数参数实现实参的运算

    主要介绍了c++将引用或者是指针作为函数参数实现实参的运算,需要的朋友可以参考下

    新手学习C++入门资料

    上面例子中,第一次调用show()函数时,让编译器自动提供函数原型中指定的所有默认参数,第二次调用提供了第一个参数,而让编译器提供剩下的两个,第三次调用则提供了前面两个参数,编译器只需提供最后一个,最后一...

    JavaScript程序设计课件:函数的参数.pptx

    函数的参数是函数与外界交换数据的接口。外部的数据通过参数传入函数内部进行处理,同时函数内部的数据也可以通过参数传到外界。 函数定义时圆括号里的参数称为形式参数,调用函数时传递的参数称为实际参数。 5.2.3 ...

Global site tag (gtag.js) - Google Analytics