当前位置: 首页 > news >正文

手机网站在线制作建网站要注册吗

手机网站在线制作,建网站要注册吗,企业app开发制作,东莞网站建设 硅橡胶第8 章 函数探幽 本章内容包括#xff1a; 内联函数。引用变量。如何按引用传递函数参数。默认参数。函数重载。函数模板。函数模板具体化。通过第 7 章#xff0c;您了解到很多有关 C函数的知识#xff0c;但需要学习的知识还很多。C还提供许多新的函 数特性#xff0c;…第8 章 函数探幽 本章内容包括 内联函数。引用变量。如何按引用传递函数参数。默认参数。函数重载。函数模板。函数模板具体化。通过第 7 章您了解到很多有关 C函数的知识但需要学习的知识还很多。C还提供许多新的函 数特性使之有别于 C 语言。新特性包括内联函数、按引用传递变量、默认的参数值、函数重载多态 以及模板函数。 本章介绍的 C在 C 语言基础上新增的特性比前面各章都多这是您进入加加领 域的重要一步. 内联函数 内联函数是在编译时将函数的定义直接插入到调用该函数的地方而不是通过函数调用的方式执行。通过内联函数可以提高程序的执行效率减少函数调用的开销。 在C中使用关键字inline来声明内联函数。一般情况下将函数定义放在类定义的头文件中或者在函数定义前加上inline关键字。 例如 inline int add(int a, int b) {return a b; }内联函数在编译时会被替换为函数体的实际代码而不是通过函数调用执行。这样可以避免函数调用的开销提高程序的执行效率。然而内联函数的展开也会增加代码的体积所以内联函数适用于函数体较小且被频繁调用的情况。 需要注意的是对于递归函数、含有循环或复杂控制流的函数以及包含静态变量的函数通常不适合声明为内联函数。此外编译器并不一定会完全遵守内联函数的声明它可能会根据自己的优化策略选择是否内联某个函数。 总之内联函数是一种用于提高程序性能的机制它通过将函数的代码插入到调用处减少了函数调用的开销但也会增加代码的体积。我们需要根据实际情况来选择使用内联函数。 // inline.cpp -- using an inline function #include iostream// an inline function definition inline double square(double x) { return x * x; } int main() {using namespace std;double a, b;double c 13.0;a square(5.0);b square(4.5 7.5); // can pass expressionscout a a , b b \n;cout c c;cout , c squared square(c) \n;cout Now c c \n;// cin.get();return 0; }内联函数是在编译时展开的函数它通常用于简单的函数以提高程序的执行效率。在C中使用关键字inline来声明内联函数。 在上面的代码示例中square()函数被声明为内联函数。它的定义如下 inline double square(double x) { return x * x; }square()函数接受一个double类型的参数然后返回该参数的平方。 在main()函数中我们可以通过调用square()函数来计算不同值的平方并将结果打印出来。例如 a square(5.0);这里5.0作为参数传递给square()函数并将返回值赋给变量a。 另外内联函数还支持传递表达式作为参数。例如 b square(4.5 7.5);这里表达式4.5 7.5的值作为参数传递给square()函数。 此外内联函数的展开发生在编译时因此在代码中多次调用同一个内联函数时每次调用都会被替换为函数体的复制。在上述代码中可以看到square(c)的调用其中c是一个后缀递增操作。由于内联函数的展开发生在编译时所以c只会在整个表达式计算之前递增一次而不是在每次复制的调用中递增。 综上所述内联函数是一种用于提高程序执行效率的特殊函数它将函数的调用替换为函数体的复制适用于简单的函数和频繁调用的函数。 当我们在代码中使用内联函数时编译器会尝试将函数的定义直接嵌入到调用该函数的地方。这样可以减少函数调用带来的额外开销提高程序的执行效率。 以下是一些关于内联函数的注意事项 小函数内联函数适合用于短小且频繁调用的函数。因为直接插入函数代码而不是通过函数调用所以函数体越小插入到调用处的冗余代码就越少性能提升也越明显。 头文件中的定义为了使内联函数在每个调用点都可见通常将内联函数的定义放在头文件中。这样在每个使用该内联函数的源文件编译时都可以将函数的定义嵌入。否则在链接阶段会出现无法解析的符号错误。 函数声明与定义的一致性内联函数的声明和定义必须一致即函数签名参数类型返回类型和函数体需一致。如果函数的定义与声明不一致编译器可能会忽略内联修饰符。 递归函数和循环递归函数通常不适合用作内联函数因为递归函数的执行需要保持调用栈的状态。而内联函数的工作方式不适合保持递归调用的状态。 编译器优化内联函数的使用并不保证编译器一定会进行内联展开。编译器可能会根据自身的优化策略和设置来决定是否内联函数。我们可以使用编译器的优化选项来指示编译器进行内联展开。 内联函数是一种在编译时将函数调用替换为函数本体的方式以提高程序执行效率。内联函数适用于短小且频繁调用的函数但并不能保证编译器一定会进行内联展开。我们需要根据实际情况来选择使用内联函数并注意遵循内联函数的声明和定义规则。 当我们在编程中使用内联函数时有几点需要注意 使用内联函数可以减少函数调用的开销但这并不意味着每个函数都应该声明为内联函数。编译器根据一系列规则和优化策略来决定是否将函数展开为内联代码。通常适合用于内联的函数包括简短的、频繁调用的函数。 内联函数的定义通常放在头文件中。因为内联函数的定义需要在每个调用点都可见所以将其放在头文件中可以确保在所有使用的源文件中都能访问到内联函数的定义。否则在链接阶段会出现找不到函数定义的错误。 内联函数的声明和定义必须一致包括参数类型、返回类型和函数体。如果声明和定义不一致编译器可能会忽略内联修饰符。 内联函数不适合复杂的函数体、包含循环或递归调用的函数以及包含静态变量的函数。由于内联函数会在每个调用点直接插入代码复杂的函数体会导致代码重复并且可能会影响性能。 内联函数的展开也会增加代码的体积因此在某些情况下过度使用内联函数可能会导致代码膨胀影响可执行文件的大小。 编译器并不一定会完全遵循内联函数的声明。编译器会根据自身的优化策略和设置来决定是否将函数展开为内联代码。我们可以使用编译器提供的优化选项来指示编译器进行内联展开。 引用变量 在编程中引用变量是一个存储内存地址的变量它指向另一个变量或对象的位置。通过引用变量我们可以间接地访问和修改相应的数据。 在不同的编程语言中引用变量可能具有不同的表达方式。例如在C中引用变量使用符号声明并在声明时与另一个变量绑定在Java中引用变量直接声明为对象类型在Python中变量实际上就是一个引用直接通过赋值来引用其他对象。 引用变量的主要作用是允许多个变量同时指向同一个对象从而实现数据共享和传递。通过修改引用变量的值可以改变所指向对象的状态。这在处理大型复杂数据结构时非常有用可以减少内存复制和提高性能。 然而需要注意的是引用变量并不总是指向有效的内存地址。如果引用变量没有初始化或者指向已释放的内存那么访问该引用变量可能导致错误或者未定义行为。因此在使用引用变量时需要谨慎处理确保引用的对象是有效的。 / firstref.cpp -- defining and using a reference #include iostream int main() {using namespace std;int rats 101;int rodents rats; // rodents is a referencecout rats rats;cout , rodents rodents endl;rodents;cout rats rats;cout , rodents rodents endl;// some implementations require type casting the following // addresses to type unsignedcout rats address rats;cout , rodents address rodents endl;// cin.get();return 0; }这是一个C的示例代码演示了引用变量的用法。下面是对代码的解释 #include iostream引入iostream库用于输入输出操作。 int main() {using namespace std;int rats 101;int rodents rats; // rodents is a referencecout rats rats;cout , rodents rodents endl;在主函数中声明一个整型变量rats并赋值为101。然后通过引用变量rodents将rats进行引用绑定。rodents成为rats的引用它们指向同一个内存地址。 接下来使用cout语句输出rats和rodents的值。 rodents;cout rats rats;cout , rodents rodents endl;通过修改rodents的值也会同时修改rats的值。这里对rodents进行自增操作并再次输出rats和rodents的值。 cout rats address rats;cout , rodents address rodents endl;最后使用运算符获取rats和rodents的地址并输出。请注意两者在内存中的地址是相同的因为rodents是rats的引用。 return 0; }程序结束返回0表示正常退出。 这个示例代码展示了引用变量的使用。通过引用变量我们可以创建别名并直接访问和修改原始变量的值实现数据共享和传递。 // secref.cpp -- defining and using a reference #include iostream int main() {using namespace std;int rats 101;int rodents rats; // rodents is a referencecout rats rats;cout , rodents rodents endl;cout rats address rats;cout , rodents address rodents endl;int bunnies 50;rodents bunnies; // can we change the reference?cout bunnies bunnies;cout , rats rats;cout , rodents rodents endl;cout bunnies address bunnies;cout , rodents address rodents endl;// cin.get();return 0; }这是另一个C的示例代码展示了引用变量的一些特性。下面是对代码的解释 #include iostream引入iostream库用于输入输出操作。 int main() {using namespace std;int rats 101;int rodents rats; // rodents is a referencecout rats rats;cout , rodents rodents endl;在主函数中声明一个整型变量rats并赋值为101。然后通过引用变量rodents将rats进行引用绑定。 接下来使用cout语句输出rats和rodents的值。 cout rats address rats;cout , rodents address rodents endl;使用运算符获取rats和rodents的地址并输出。请注意两者在内存中的地址是相同的因为rodents是rats的引用。 int bunnies 50;rodents bunnies; // can we change the reference?cout bunnies bunnies;cout , rats rats;cout , rodents rodents endl;在此代码段中声明了一个整型变量bunnies并赋值为50。然后将bunnies赋值给rodents即修改了rodents所引用的值。请注意这里并没有修改rodents的引用目标仅修改了其所引用对象的值。 接下来使用cout语句输出bunnies、rats和rodents的值。 cout bunnies address bunnies;cout , rodents address rodents endl;最后使用运算符获取bunnies和rodents的地址并输出。请注意bunnies和rodents在内存中的地址是不同的因为它们是两个独立的变量。 return 0; }程序结束返回0表示正常退出。 这个示例代码演示了引用变量的一些特性。通过引用变量我们可以创建别名并直接访问原始变量的值。在赋值操作中引用变量会更改其所引用对象的值而不是修改引用本身。引用变量与原始变量共享相同的内存地址。 当我们使用引用变量时可以进行以下操作 声明引用变量在编程语言中可以使用特定的语法来声明引用变量。具体的语法可能因编程语言而异但通常使用符号或关键字表示。例如在C中可以使用符号来声明引用变量。 初始化引用变量引用变量必须在声明时被初始化即要将其绑定到另一个变量或对象。这样引用变量就指向了相应的内存地址。初始化后引用变量将成为该变量或对象的别名并且可以通过该引用变量来访问和修改其值。 传递引用变量可以将引用变量作为参数传递给函数或方法。通过这种方式函数可以直接操作原始变量的值而不需要进行额外的内存复制。这样可以提高性能并减少内存消耗。 修改引用变量通过引用变量可以修改所指向的变量或对象的值。这种修改是直接的会反映在原始变量上。这对于在函数内部修改传入的变量非常有用。 注意引用的有效性在使用引用变量时需要确保引用的对象是有效的。如果引用变量指向已释放的内存或未初始化的变量访问该引用变量可能导致错误或未定义行为。因此在使用引用变量时需要进行适当的检查和管理以确保引用的正确性。 需要注意的是具体的引用变量用法和语法可能因编程语言而异。在使用引用变量时应该查阅相应编程语言的文档和规范了解具体的用法和语法规则。 使用传值和引用参数的示例代码 / cubes.cpp -- regular and reference arguments #include iostream double cube(double a); double refcube(double ra); int main () {using namespace std;double x 3.0;cout cube(x);cout cube of x endl;cout refcube(x);cout cube of x endl;// cin.get();return 0; }double cube(double a) {a * a * a;return a; }double refcube(double ra) {ra * ra * ra;return ra; }这是一个展示了使用传值和引用参数的示例代码。代码如下所示 #include iostreamdouble cube(double a); double refcube(double ra);int main() {using namespace std;double x 3.0;cout cube(x);cout cube of x endl;cout refcube(x);cout cube of x endl;return 0; }double cube(double a) {a * a * a;return a; }double refcube(double ra) {ra * ra * ra;return ra; }在主函数中首先声明一个变量x并赋值为3.0。然后调用cube(x)函数并使用cout输出计算结果再次输出x的值。接着调用refcube(x)函数并同样使用cout输出计算结果以及x的值。 cube函数使用传值方式计算a的立方。在函数内部先将a自乘两次然后将结果返回。 refcube函数使用引用参数计算ra的立方。在函数内部同样将ra自乘两次然后将结果返回。由于使用引用参数函数修改的是原始变量x的值。 通过比较两个函数的输出结果可以看出使用传值参数的cube函数并没有修改原始变量x的值而使用引用参数的refcube函数成功修改了原始变量x的值。 将引用用于结构 //strc_ref.cpp -- using structure references #include iostream #include string struct free_throws {std::string name;int made;int attempts;float percent; };void display(const free_throws ft); void set_pc(free_throws ft); free_throws accumulate(free_throws target, const free_throws source);int main() {free_throws one {Ifelsa Branch, 13, 14};free_throws two {Andor Knott, 10, 16};free_throws three {Minnie Max, 7, 9};free_throws four {Whily Looper, 5, 9};free_throws five {Long Long, 6, 14};free_throws team {Throwgoods, 0, 0};free_throws dup;set_pc(one);display(one);accumulate(team, one);display(team); // use return value as argumentdisplay(accumulate(team, two));accumulate(accumulate(team, three), four);display(team); // use return value in assignmentdup accumulate(team,five);std::cout Displaying team:\n;display(team);std::cout Displaying dup after assignment:\n;display(dup);set_pc(four); // ill-advised assignmentaccumulate(dup,five) four;std::cout Displaying dup after ill-advised assignment:\n;display(dup);// std::cin.get();return 0; }void display(const free_throws ft) {using std::cout;cout Name: ft.name \n;cout Made: ft.made \t;cout Attempts: ft.attempts \t;cout Percent: ft.percent \n; } void set_pc(free_throws ft) {if (ft.attempts ! 0)ft.percent 100.0f *float(ft.made)/float(ft.attempts);elseft.percent 0; }free_throws accumulate(free_throws target, const free_throws source) {target.attempts source.attempts;target.made source.made;set_pc(target);return target; }这段代码是一个简单的示例用于展示如何使用结构体引用以及结构体的操作。 首先在代码中定义了一个名为free_throws的结构体。该结构体包含了篮球队员的姓名name成员变量、投中次数made成员变量、尝试次数attempts成员变量和命中率percent成员变量。 接下来定义了几个函数来操作和显示free_throws对象。 display函数用于显示一个free_throws对象的内容。它接受一个常量引用参数ft以避免对原始对象进行修改。在函数内部使用cout对象输出对象的姓名、投中次数、尝试次数和命中率。 set_pc函数用于计算和设置投篮命中率。它接受一个非常量引用参数ft因为它需要修改原始对象的成员变量。在函数内部通过判断尝试次数是否为0计算出命中率并将其赋值给对象的命中率成员变量。 accumulate函数用于累加两个free_throws对象的数据并返回一个free_throws引用。它接受一个非常量引用参数target作为目标对象一个常量引用参数source作为源对象。在函数内部将目标对象的投中次数和尝试次数分别加上源对象的对应值并调用set_pc函数更新目标对象的命中率。最后返回目标对象的引用。 在main函数中首先创建了一些free_throws对象分别赋值给不同的变量one、two、three、four、five和team。这些对象表示了不同篮球队员的投篮数据和一个整个团队的总数据。 接下来通过调用set_pc函数计算和设置了对象one的命中率并调用display函数显示出来。 然后通过调用accumulate函数将对象one的数据累加到了team对象中并再次调用display函数显示了team对象的数据。 接着演示了如何将accumulate函数的返回值作为参数传递给display函数以便直接显示累加结果。 然后又通过多次调用accumulate函数将不同对象的数据逐步累加到team对象中并再次调用display函数显示了team对象的最新数据。 接下来演示了将accumulate函数的返回值赋值给另一个free_throws对象dup并通过调用display函数显示了team对象和dup对象的数据。 最后代码中还演示了一种不推荐的做法即将accumulate函数的返回值用于赋值并再次调用accumulate函数进行修改。这样的操作是合法的但可能会导致代码难以理解和维护。 总的来说这段代码通过结构体引用的方式展示了如何操作和修改结构体对象并且演示了函数返回值的使用场景。通过累加和更新数据可以实现对结构体成员变量的修改和计算。 函数重载 函数重载是指在同一个作用域内可以定义多个具有相同名称但参数列表包括参数类型、顺序和数量不同的函数。 通过函数重载可以根据不同的参数类型或数量来调用不同的函数逻辑提高了代码的灵活性和可读性。它允许使用相同的函数名来表示一组相关的操作从而更直观地表达代码的意图。 函数重载的规则如下 函数名称必须相同但是参数列表必须不同。参数列表可以有不同的参数类型、参数顺序或参数数量。返回类型可以相同也可以不同。函数重载仅通过函数的名称和参数列表进行区分与返回类型无关。 以下是一个函数重载的示例 #include iostream// 重载的函数add接受两个整数参数 int add(int a, int b) {return a b; }// 重载的函数add接受三个整数参数 int add(int a, int b, int c) {return a b c; }// 重载的函数add接受两个浮点数参数 float add(float a, float b) {return a b; }int main() {int result1 add(2, 3);int result2 add(2, 3, 4);float result3 add(2.5f, 3.7f);std::cout result1 std::endl; // 输出5std::cout result2 std::endl; // 输出9std::cout result3 std::endl; // 输出6.2return 0; }在上述示例中定义了三个重载的add函数。第一个函数接受两个整数参数第二个函数接受三个整数参数第三个函数接受两个浮点数参数。 在main函数中通过根据需要选择调用不同版本的add函数实现了整数相加和浮点数相加的功能并打印出结果。 请注意函数重载是 C 的特性在函数调用时会根据传入的参数类型或数量自动匹配调用合适的函数版本。这样可以简化函数命名提高代码的可读性和灵活性。 函数模版 函数模板Function Template是C中一种用于创建通用函数的特性。函数模板允许定义一个通用的函数可以在不同的数据类型上进行操作从而避免了重复编写类似功能的多个函数。 使用函数模板可以根据具体的参数类型生成对应的函数代码实现类型无关的重用。 函数模板的语法如下 template typename T void functionName(T parameter) {// 函数体 }其中template typename T 告诉编译器接下来的代码是模板代码并且使用类型参数 TT 可以是任意合法的标识符。 在函数体中可以使用类型参数 T 来定义变量、执行操作等。 以下是一个简单的函数模板示例 #include iostream// 函数模板用于交换两个值 template typename T void swapValues(T a, T b) {T temp a;a b;b temp; }int main() {int a 1, b 2;float c 1.5f, d 2.7f;std::cout Before swap: a a , b b std::endl;swapValues(a, b);std::cout After swap: a a , b b std::endl;std::cout Before swap: c c , d d std::endl;swapValues(c, d);std::cout After swap: c c , d d std::endl;return 0; }在上述示例中定义了一个函数模板swapValues用于交换两个值。在main函数中首先声明了几个变量a、b、c和d分别为int类型和float类型。 通过调用swapValues函数模板来交换这些变量的值不论是int类型还是float类型的变量都可以使用相同的函数模板进行操作。 值得注意的是在函数模板中编译器会根据实际参数类型自动生成对应类型的函数代码并进行编译。 通过函数模板可以实现对不同类型数据的通用操作提高代码的重用性和可读性。同时C标准库中许多常见的函数如std::sort、std::max等也是使用函数模板实现的。 / funtemp.cpp -- using a function template #include iostream // function template prototype template typename T // or class T void Swap(T a, T b);int main() {using namespace std;int i 10;int j 20;cout i, j i , j .\n;cout Using compiler-generated int swapper:\n;Swap(i,j); // generates void Swap(int , int )cout Now i, j i , j .\n;double x 24.5;double y 81.7;cout x, y x , y .\n;cout Using compiler-generated double swapper:\n;Swap(x,y); // generates void Swap(double , double )cout Now x, y x , y .\n;// cin.get();return 0; }// function template definition template typename T // or class T void Swap(T a, T b) {T temp; // temp a variable of type Ttemp a;a b;b temp; }这段代码演示了如何使用函数模板来创建通用的交换函数。 在这段代码中定义了一个名为Swap的函数模板用于交换两个值。在main函数中先声明了int类型的变量i和j并输出它们的初始值。 接着调用Swap(i, j)来交换i和j的值编译器会根据Swap函数模板的定义生成一个针对int类型的具体函数。最后再次输出i和j的值可以看到它们已经被交换了。 类似地还定义了一个交换double类型值的例子通过调用Swap(x, y)来交换x和y的值并最终输出交换后的结果。 总之函数模板可以根据不同的数据类型自动生成对应的函数代码从而提供了一种通用的解决方案避免了重复编写相似功能的函数。 // twotemps.cpp -- using overloaded template functions #include iostream template typename T // original template void Swap(T a, T b);template typename T // new template void Swap(T *a, T *b, int n);void Show(int a[]); const int Lim 8; int main() {using namespace std;int i 10, j 20;cout i, j i , j .\n;cout Using compiler-generated int swapper:\n;Swap(i,j); // matches original templatecout Now i, j i , j .\n;int d1[Lim] {0,7,0,4,1,7,7,6};int d2[Lim] {0,7,2,0,1,9,6,9};cout Original arrays:\n;Show(d1); Show(d2);Swap(d1,d2,Lim); // matches new templatecout Swapped arrays:\n;Show(d1);Show(d2);// cin.get();return 0; }template typename T void Swap(T a, T b) {T temp;temp a;a b;b temp; }template typename T void Swap(T a[], T b[], int n) {T temp;for (int i 0; i n; i){temp a[i];a[i] b[i];b[i] temp;} }void Show(int a[]) {using namespace std;cout a[0] a[1] /;cout a[2] a[3] /;for (int i 4; i Lim; i)cout a[i];cout endl; }这段代码展示了使用重载的函数模板来创建通用的交换函数。 首先在代码中定义了一个名为Swap的模板函数它有两个参数类型为T引用类型。该模板函数用于交换两个值不管这两个值的具体类型是什么。在函数内部创建了一个临时变量temp将参数a的值赋给temp然后将参数b的值赋给a最后将temp的值赋给b。通过这个过程实现了两个值的交换。 接下来定义了一个重载的模板函数Swap它有三个参数分别是T[]类型的数组a和b以及一个整数n用于指定数组的长度。该模板函数用于交换两个数组中的元素。 在函数内部使用一个循环遍历数组元素。对于每个位置上的元素都执行一个交换操作将数组a的当前位置上的元素赋值给临时变量temp将数组b的当前位置上的元素赋值给数组a最后将temp的值赋给数组b。通过这个过程实现了两个数组中元素的交换。 在main函数中首先声明并初始化了两个int类型的变量i和j并输出它们的初始值。然后调用了Swap(i,j)来交换i和j的值因为i和j的类型为int所以编译器会根据Swap模板函数的定义生成一个专门针对int类型的具体函数。最后再次输出i和j的值可以看到它们已经被成功交换。 接着创建了两个int类型的数组d1和d2并分别初始化它们的值。通过调用Show函数展示了数组d1和d2的内容。然后调用了Swap(d1,d2,Lim)来交换这两个数组中的元素。由于Swap函数模板被重载了所以编译器会根据参数类型选择调用合适的函数。最后再次调用Show函数显示交换后的数组内容。 总之通过使用重载的函数模板代码实现了通用的交换函数可以适用于不同类型的参数提供了更灵活和通用的交换操作。 // twoswap.cpp -- specialization overrides a template #include iostream template typename T void Swap(T a, T b);struct job {char name[40];double salary;int floor; };// explicit specialization template void Swapjob(job j1, job j2); void Show(job j);int main() {using namespace std;cout.precision(2);cout.setf(ios::fixed, ios::floatfield);int i 10, j 20;cout i, j i , j .\n;cout Using compiler-generated int swapper:\n;Swap(i,j); // generates void Swap(int , int )cout Now i, j i , j .\n;job sue {Susan Yaffee, 73000.60, 7};job sidney {Sidney Taffee, 78060.72, 9};cout Before job swapping:\n;Show(sue);Show(sidney);Swap(sue, sidney); // uses void Swap(job , job )cout After job swapping:\n;Show(sue);Show(sidney);// cin.get();return 0; }template typename T void Swap(T a, T b) // general version {T temp;temp a;a b;b temp; }// swaps just the salary and floor fields of a job structuretemplate void Swapjob(job j1, job j2) // specialization {double t1;int t2;t1 j1.salary;j1.salary j2.salary;j2.salary t1;t2 j1.floor;j1.floor j2.floor;j2.floor t2; }void Show(job j) {using namespace std;cout j.name : $ j.salary on floor j.floor endl; }这段代码展示了如何通过特化版本覆盖模板函数。 首先在代码中定义了一个模板函数Swap它有两个参数类型为T引用类型。该模板函数用于交换两个值不管这两个值的具体类型是什么。在函数内部创建了一个临时变量temp将参数a的值赋给temp然后将参数b的值赋给a最后将temp的值赋给b。通过这个过程实现了两个值的交换。 然后定义了一个特化的模板函数Swapjob它有两个参数类型为job引用类型。该特化函数用于交换两个job结构体对象的部分成员即只交换salary和floor字段的值。在函数内部创建了两个临时变量t1和t2分别存储j1和j2的salary和floor的值。然后将j1的salary赋值为j2的salary将j2的salary赋值为t1同样地将j1的floor赋值为j2的floor将j2的floor赋值为t2。通过这个过程实现了特定成员的交换。 在main函数中首先声明并初始化了两个int类型的变量i和j并输出它们的初始值。然后调用了Swap(i, j)来交换i和j的值因为i和j的类型为int所以会选择调用通用版本的Swap模板函数。最后再次输出i和j的值可以看到它们已经被成功交换。 接着创建了两个job结构体对象sue和sidney并分别初始化它们的值。通过调用Show函数展示了这两个对象的内容。然后调用了Swap(sue, sidney)来交换这两个对象的salary和floor字段的值因为sue和sidney的类型为job所以会选择调用特化版本的Swapjob函数。最后再次调用Show函数显示交换后的对象内容。 总之通过在模板中创建特化版本并在特化版本中提供针对特定类型的交换操作代码实现了更精细和特定的交换功能。 8.6 总结 C 扩展了 C 语言的函数功能其中包括引入内联函数和引用变量等特性。内联函数可以通过在函数定义前加上 inline 关键字并在首次调用前提供函数定义来实现。引用变量允许为变量创建别名主要用于处理结构和类对象的函数参数。需要注意的是基类引用可以指向派生类对象。 C 还支持函数参数默认值的定义当函数调用省略了某些参数时程序将使用默认值当函数调用提供了参数值时程序将使用提供的值。定义默认参数时需要按照从右到左的顺序提供。 函数的特征标是通过参数列表来确定的允许定义同名函数但特征标不同从而实现函数多态或函数重载。此外函数模板可以自动完成函数重载的过程通过使用泛型和具体算法定义函数编译器将为特定参数类型生成正确的函数定义。 8.8 编程练习 1编写通常接受一个参数字符串的地址并打印该字符串的函数。然而如果提供了第二个参数 int 类型且该参数不为 0则该函数打印字符串的次数将为该函数被调用的次数注意字符串的打印次数不等于第二个参数的值而等于函数被调用的次数。是的这是一个非常可笑的函数但它让您能够使用本章介绍的一些技术。在一个简单的程序中使用该函数以演示该函数是如何工作的。 2CandyBar 结构包含 3 个成员。第一个成员存储 candy bar 的品牌名称第二个成员存储 candy bar的重量可能有小数第三个成员存储 candy bar 的热量整数。请编写一个程序它使用一个这样的函数即将 CandyBar 的引用、char 指针、double 和 int 作为参数并用最后 3 个值设置相应的结构成员。最后 3 个参数的默认值分别为“Millennium Munch”、2.85 和 350。另外该程序还包含一个以 CandyBar 的引用为参数并显示结构内容的函数。请尽可能使用 const。 3编写一个函数它接受一个指向 string 对象的引用作为参数并将该 string 对象的内容转换为大写 为此可使用表 6.4 描述的函数 toupper( )。然后编写一个程序它通过使用一个循环让您能够用不同的输入来测试这个函数该程序的运行情况如下 8.8 编程练习 打印字符串函数 #include iostream #include stringvoid printString(const std::string str, int n 1) {for (int i 0; i n; i) {std::cout str std::endl;} }int main() {std::string str Hello, world!;printString(str); // 调用一次打印一次字符串printString(str, 3); // 调用三次打印三次字符串return 0; }CandyBar 结构和函数 #include iostream #include stringstruct CandyBar {std::string brand;double weight;int calories; };void setCandyBar(CandyBar candy, const char* brand Millennium Munch, double weight 2.85, int calories 350) {candy.brand brand;candy.weight weight;candy.calories calories; }void showCandyBar(const CandyBar candy) {std::cout Brand: candy.brand std::endl;std::cout Weight: candy.weight std::endl;std::cout Calories: candy.calories std::endl; }int main() {CandyBar candy;setCandyBar(candy); // 使用默认参数设置结构成员showCandyBar(candy); // 显示结构内容return 0; }字符串转大写函数 #include iostream #include stringvoid toUpper(std::string str) {for (int i 0; i str.length(); i) {str[i] toupper(str[i]);} }int main() {std::string str;while (true) {std::cout Please enter a string (q to quit): ;std::getline(std::cin, str);if (str q) {break;}toUpper(str);std::cout Uppercase: str std::endl;}return 0; }
http://www.huolong8.cn/news/194092/

相关文章:

  • 合肥网站建设sina自己建设公司网站
  • 郑州seo建站wordpress 执行了两次
  • 湖南长沙网站建试论述网上商城的推广技巧
  • 淘宝推广费用多少钱一天seo中文
  • wordpress网站慢网店代运营怎么做
  • 网站托管找如何看一个站点是不是有wordpress
  • 阿德莱德做网站长春网络公司排名榜
  • 建设厅网站的无法打印平台推广引流怎么做
  • 如何在百度搜索dw做的网站企业网站建设情况说明
  • 电子商务基础网站建设与维护单项选择题wordpress 登录接口
  • 南宁企业网站建设技术公司怎么利用个人网站
  • 做婚庆网站嵌入式软件能干一辈子
  • 大连p2p网站建设中文网站模板下载免费
  • html5 mysql 网站开发淄博网站建设开发
  • 株洲网站建设的企业网站空间到期提示
  • wordpress门户主题下载专业网站优化外包
  • php和wordpress教程网站 优化 关键字
  • 自己做网站赚流量钱石家庄新闻头条
  • h5手机网站源码下载网站开发需求表
  • 网站策划运营网页设计免费模板参考网页
  • 企业网站网络营销优化设计四年级下册语文答案
  • 电子书网站搭建教程电脑网络连接正常但是上不了网
  • 中国人做暧暧视频网站微信分销系统模板
  • 福建莆田网站开发怎么做电影网站页面的
  • 网站开发需要学数学吗电子商务知名网站
  • 建设银行河北省分行官方网站做欧洲电商看哪个网站
  • 包头网站建设制作极家装修口碑好不好
  • 福州网站建设多少钱wordpress转发插件
  • 廊坊网站推广外包破解直播免费视频
  • 用什么软件可以制作图片海阳seo排名优化培训