C++_函数1-编程的基本模块函数

以下是《C++ Primer Plus》中第七章的内容:

使用C++函数的3个步骤:

       提供函数定义

       提供函数原型

       调用函数

7.1.1 定义函数

       函数分成两类:没有返回值的函数、有返回值的函数。

       return返回语句标记了函数的结尾;否则,函数将在右花括号处结束。

       对于有返回值的函数,必须使用返回语句,以便将值返回给被调用函数。

 

       C++对于返回值的类型有一定的限制:不能是数组,但可以是其他任何类型。

7.1.2 函数原型和函数调用

       为什么需要函数原型:原型描述了函数到编译器的接口,也就是说,它将函数返回值的类型以及参数的类型和数量告诉编译器。其次,函数完成计算后,将返回值放置在指定的位置——可能是CPU寄存器、也可能是内存中。然后调用函数将从这个位置获取返回值。原型指出了该函数的类型为double,因此编译器指导应检索多少个字节以及如何解释它们。

       编译器需要原型,这样也可以提高效率。

       原型的语法:函数原型是一条语句,因此必须以分号结束。原型不需要提供变量名,有类型列表就足够了。C++中原型是必不可少的。

       原型的功能:原型可以帮助编译器完成许多工作;它可以极大地降低程序出错的几率。编译阶段进行的原型化被称为静态类型检查

========================================

7.2 函数参数和按值传递

       接收传递值的变量被称为形参;传递给函数的值被称为实参

       C++标准使用参数(argument)来表示实参,使用参量(parameter)来表示形参。参数传递将参数传递给参量。形参是实参的副本。

       函数声明中的函数变量(包括参数)是函数私有的。在函数被调用时,计算机将为这些变量分配内存。函数结束时,计算机将释放这些变量使用的内存。这样的变量被称为局部变量,因为它们被限制在函数中。这样有助于确保数据的完整性。这样的变量也被称为自动变量,因为它们在程序执行过程中是自动被分配和释放的。

7.2.1 多个参数

       函数可以有多个参数,只需使用逗号将这些参数分开即可。

       只需添加分号就可得到该函数的原型;

       提供变量名将使原型更易于理解。

      

7.2.2 另外一个接受两个参数的函数

=====================================================     

7.3 函数和数组

函数是处理更复杂的类型的关键。

 

7.3.1 函数如何使用指针来处理数组

       C++和C语言一样,也将数组名视为指针。C++将数组名解释为其第一个元素的地址。

       有个例外:使用取址运算符&用于数组名时,将返回整个数组的地址。

       int * arr == int arr [ ];

       指针也可以用方括号表示法来访问数组元素。

       记住:指针加1,实际上是加上了一个与指针指向的类型的长度相等的值。

       对于遍历数组而言,使用指针加法和数组下标时等效的。

7.3.2 将数组作为参数意味着什么

       实际上并没有把数组的内容传递给函数,而是将数组的位置信息,长度,包含元素种类告诉了函数。函数便可使用原来的数组。传递的值是数组的地址。将数组地址作为参数可以节省复制整个数组所需的时间和内存。但是使用原始数据增加了破坏数据的风险。但是ANSI C和C++中的const限定符提供了解决这种问题的办法。

 

7.3.3 更多数组函数示例

       构思程序时将:存储属性对数据的操作结合起来。

7.3.4 使用数组区间的函数

       传统的C/C++方法处理数组的函数是:将指向数组起始处的指针作为一个参数,将数组长度作为第二个参数,这样便给函数提供了找到所有数据所需的信息。

       另一种给函数提供所需信息的方法:即指定元素区间。可以通过传递两个指针来完成。一个指针标识数组的开头,一个指针标识数组的尾部。

       end – begin 是一个整数值,等于数组的元素数目。

7.3.5 指针和const

       有两种将const和指针结合使用的方法:

              让指针指向一个常量对象:可以防止使用该指针来修改所指向的值。(指针指向的值)

                     int age =39;

                     const int * pt = &age;

                     微妙的地方是,pt的声明并不意味着它指向的值实际上就是一个常量。而只是对pt而言,这个值是常量。age不是const,可以直接通过age变量来修改age的值。

              将指针本身声明为常量:可以防止修改指针指向的位置。(指针的值)

                     int * const finger = &sloth; 

              将指针作为函数参数来传递时,可以使用指向const的指针来保护数据。

====================================================

7.4 函数和二维数组

       将二维数组作为参数的函数:

       int sum(int ar2[ ] [4], int size);

       int sum(int (* ar2)[4], int size);

====================================================

7.5 函数和C-风格字符串

       C风格字符串由一系列字符组成:以空字符结尾,有关设计数组函数的知识也适用于字符串函数。

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

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

              char数组;用引号括起来的字符串常量;备设置为字符串的地址的char指针;

              但上述3种选择的类型都是char指针,因此可以将其作为字符串处理函数的函数;

       将字符串作为参数来传递,但实际传递的是字符串的第一个字符的地址。字符串函数原型应将其表示字符串的形参声明为char *类型

       C风格字符串与常规char数组之间的一个重要区别:字符串有内置的结束字符。这意味着不必将字符串长度作为参数传递给函数。而函数可以使用循环依次检查字符串中的每个字符,直到遇到结尾的空值字符为止。

 

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

       函数无法返回一个字符串,但是可以返回字符串的地址,这样做效率更高。

====================================================

7.6 函数和结构

       为结构编写函数比为数组编写函数要简单得多。结构变量的行为更接近于基本的单值变量。

       注意:结构名只是结构的名称,要获得结构的地址,必须使用地址运算符&

       使用结构编程时,最直接的方式是像处理基本类型那样来处理结构;将结构作为参数传递,并在需要时将结构用作返回值使用。

       按值传递结构有一个缺点。如果结构非常大,则复制结构将增加内存要求,降低系统运行的速度。处于这些原因,许多程序员倾向于传递结构的地址,然后使用指针来访问结构的内容。

       还有第三种选择:按引用传递

7.6.1 传递和返回结构

 

7.6.2 另一个处理结构的函数示例

 

7.6.3 传递结构的地址

       传递结构的地址而不是整个结构以节省时间和空间,使用指向结构的指针。

       注意点

              调用函数时,将结构的地址(&pplace)而不是结构本身(pplace)传递给它。

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

              由于形参是指针而不是结构,因此应使用间接成员运算符(->),而不是成员运算符(句点)

====================================================

7.7 函数和string对象

       功能上C风格字符串与string对象的用途几乎相同。但是string对象与结构更相似。例如:可以将一个结构赋给另一个结构,也可以将一个对象赋给另一个对象。可以将结构作为完整的实体传递给函数,也可以将对象作为完整的实体传递给函数。如果需要多个字符串,可以声明一个string对象数组。

====================================================

7.8 函数与array对象

       按值传递对象给函数,函数处理的是原始对象的副本。

       也可以传递指向对象的指针,这让函数能够操作原始对象。(修改对象,按地址传递)

      

       按值传递(拷贝副本)、占用内存空间;

传递地址;但是代码看起来更复杂;

引用传递;-->解决了效率和表示法两方面的问题;

====================================================

7.9 递归

       函数调用自己,被称为递归。

7.9.1 包含一个递归调用的递归

 

7.9.2 包含多个递归调用的递归

==================================================== 

7.10 函数指针

       函数也有地址,函数的地址是存储器机器语言代码的内存的开始地址。通常这个地址对用户而言既不重要也没有什么用处。对程序而言,却很有用,可以编写将另一个函数的地址作为参数的函数。

7.10.1 函数指针的基础知识

       获取函数地址;

              函数名及函数的地址;

       声明函数指针;

              声明应该像函数原型那样指出有关函数的信息。

              double pam(int);  //函数的prototype

              double (*pf)(int);  //声明指向函数的指针,包含指向函数的返回类型、函数的特征标;

       使用函数指针来调用函数;

       对于(*pf),只需将它看做是函数名即可。

       double pam(int);

       double (*pf)(int);  //声明函数指针

       pf =pam;   //将pam函数赋给pf函数指针,

       double x = pam(4);

       double y =(*pf)(5);  //这种格式虽然不太好看,但是给出了强有力的提示,代码正在使用函数指针

       double y = pf(5);  //这个格式就和函数差不多;

7.10.2 函数指针示例

 

7.10.3 深入探讨函数指针

 

7.10.4 使用typedef进行简化

       关键字typedef让您能够创建类型别名;

       使用typedef可减少输入量,让您编写代码时不容易犯错。

例子:

       typedef const double *(*p_fun)(const double *, int);   //p_fun现在就是函数指针,或者可以认为是一种类型

       p_fun p1 = f1;   //现在p1是指向f1的函数指针

==================================================== 

7.11 总结

       函数是C++的编程模块。要使用函数,必须提供定义和原型,并调用该函数。函数定义是实现函数功能的代码;函数原型描述了函数的接口:传递给函数的值的数目和种类以及函数的返回类型;函数调用使得程序将参数传递给函数,并执行函数的代码。

       在默认情况下,C++函数按值传递参数。这意味着函数定义中的形参是新的变量,它们被初始化为函数调用所提供的值。C++函数通过使用拷贝,保护了原始数据的完整性。

       C++将数组名参数视为数组第一个元素的地址。从技术上讲,这仍然是按值传递的,因为指针是原始地址的拷贝,但函数将使用指针来访问原始数组的内容。当且仅当声明函数的形参时,下面两个声明才是等价的。

       typename arr[ ];

       typename * arr;

       C++提供了3中表示C-风格字符串的方法:字符数组、字符串常量、字符串指针;它们的类型都是char *;

       C++提供了string类,用于表示字符串。

       C++处理结构的方式与基本类型完全相同,这意味着可以按值传递结构,并将其用作函数返回类型。

       C++函数可以是递归的;

       C++函数名与函数地址作用相同。

转载于:https://www.cnblogs.com/grooovvve/p/10467742.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值