zoukankan      html  css  js  c++  java
  • 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++函数名与函数地址作用相同。

  • 相关阅读:
    bzoj 4012: [HNOI2015]开店
    POJ 1054 The Troublesome Frog
    POJ 3171 Cleaning Shifts
    POJ 3411 Paid Roads
    POJ 3045 Cow Acrobats
    POJ 1742 Coins
    POJ 3181 Dollar Dayz
    POJ 3040 Allowance
    POJ 3666 Making the Grade
    洛谷 P3657 [USACO17FEB]Why Did the Cow Cross the Road II P
  • 原文地址:https://www.cnblogs.com/grooovvve/p/10467742.html
Copyright © 2011-2022 走看看