函数的作用,代码的重用,这种模块的概念在面向过程和面向对象的编辑方式中通用。
基础概念:
1.函数的返回值:函数的返回类型是以指定的,默认情况下函数的返回值是int类型,(一般都需要明确指定)。
2.参数的传递:在调用函数的时候,传入和返回参数都是值传递,这个根java很不一样。另外,函数里面的所有变量都是局部变量,包括:入参,内部变量,返回值。
3.由于C++是编译语言不是解释语言(java),所以与java所不同的是C++比较注意代码的顺序。由此,C++也有了一个与java不同的概念,声明,声明是为确保编译的先后顺序。
4.C++为入参分配内存的方式与普通定义变量的分配方式不同,入参分配内存的顺序是从左到右内存中的地址是依次递增的(关于内存的分配有空自己调试一下,这里先只说他们是不同的)。定义普通的变量是依次递减的分配内存空间。
5.当入参为基础类型,且字节长度小于int类型的时候,默认会保持与int的长度一致。
标准结构:(函数参数的三种传递方式)
1.值传递:
int z = add(a,b); int add(int x,int y){ return x + y; }
2.引用传递:
int z = add(a,b); int add(int &x,int &y){ return x + y; }
3.指针传递:
int z = add(&a,&b); int add(int *x,int *y){ return *x + *y; }
注意:对于这三种传递方式,就像我当初在学校学习的时候一样,我很难理解引用传递的写法和用法。调用方法时,传递给函数的是值,包括值的内存信息,而函数定义参数的写法是&x。如果&x = a,那x是什么?哦,这里的标准写法应该是&x = &a。只是在传递参数的时候省略了&。只有这样定义参数,才能让x可以直接在函数里直接使用,而不需要*&x。
而指针传递的优势在于参数可以传入一个地址过来,一般情况下这种方式应该用的少一点,因为引用传递就能获取到传入参数的地址。当然,传指针也有传指针的好,它会直接分配一个空间来保存传入的地址。
总结:传引用,使用的就是传入的值的本身,只是为变量取了一个别名。传指针,是另外开辟新空间来存放传入的值的地址。各有各的好!
可变参数函数:
实现原理:参入的参数在内存中的存放顺序是固定的,所以只要寻址合理就可以实现可变参数。C++提供了相关的API帮我们检索可变参数的参数,这是因为它通过调用内部API获取方法参数的首地址(其实也就帮我们获取了个这,如果我们自己就知道可变参的首地址,自己实现起来也很容易)。在可变参实现的时候,除首地址外,参数所占长度的计算也是关键。因为参数类型有可能不同,计算下一个参数的偏移量也就不同。
函数指针:
指针的强大之处在于它能够直接访问内存,为了它有意义才有了各种指针类型,这是一个很强大的能力。所以,对于指针来说所有的东西都具有类型,包括简单类型,复杂类型,函数之类的能够在内存里面描述的东西。
------ 这里需要一点代码 -----
函数指针是一个类型,用它定义的变量里面存储的是同类函数的地址。所以,对于函数指针来说,定义的函数的函数名其实是一个值。
注意:
从宽泛一点的角度来讲,我们见到的基本类型,结构体,类,指针以及函数。都是由类型和对象来进行描述的。就像结构体本身是一个类型,它的作用就是定义一个复杂的结构。函数也是一种类型,它的作用是定义一段能够重用的逻辑。指针也是一种类型,它的作用是通过首地址的方式访问对象(包括数据对象和逻辑对象)。
由于数据对象的侧重点是保存数据,所以我们能够直接获取的就是它里面的数据。而逻辑对象(函数),它的侧重点是运行一段行为,计算机需要知道的是它的首地址,然后执行逻辑,所以我们能够直接通过它获取它的首地址。
函数是一个动态的类型,因为它的入参和返回值是可以根据定义进行改变的。