- if
- switch
- for
- while
- 声明函数
- 传递参数
- 重载函数
- 优化函数
3.1 if
C++ if 关键字执行基本的条件测试,对给定表达式进行布尔值(true 或 false)求值,其语法如下:
if ( test-expression ) { statements-to-execute-when-true }
测试后面的大括号可以包含一个或多个语句,每个语句都以分号结束,但这些语句只有在发现表达式为真时才会被执行。如果测试结果为假,程序将继续执行下一个任务。
另外,if 语句还可以在测试失败时提供其他执行语句,方法是在 if 语句块后附加 else 语句块,如下所示:
if ( test-expression ) { statements-to-execute-when-true }
else { statements-to-execute-when-false }
如果测试成功时只需执行一条语句,则可以省略大括号,但保留大括号会使代码更清晰。
要测试两个条件,测试表达式可以使用 && 操作符,例如 if ( ( num > 5 ) && ( letter == ‘A’ ) )。另外,if 语句也可以 “嵌套 “在另一个 if 语句中,这样只有当两个测试都成功时,内部语句块中的语句才会被执行,但如果外部测试成功,外部语句块中的语句才会被执行。
ifelse.cpp
#include <iostream>
using namespace std;
int main()
{
int num = 8;
char letter = 'A';
if( num > 5 )
{
cout << "Number exceeds five" << endl;
if( letter == 'A' )
{
cout << "Letter is A" << endl;
}
}
else { cout << "Number is five or less" << endl; }
return 0;
}
执行
# ./ifelse
Number exceeds five
Letter is A
表达式 if ( flag == true ) 可以写成 if ( flag ),避免嵌套超过三层的 if 语句,以避免混淆和错误。
3.2 switch
使用较长的 if-else 语句进行条件分支时,通常使用 switch 语句会更有效,尤其是当测试表达式只对一个变量求值时。
switch 语句的工作方式与众不同。它获取给定的变量值,然后在多个 case 语句中寻找匹配值。然后执行与匹配的 case 语句值相关的语句。
如果没有找到匹配值,则不会执行任何 case 语句,但可以在最后的 case 语句后添加默认语句,指定在没有找到匹配值时要执行的语句。
重要的是,要在每个 case 语句后加上 break 关键字,以便在执行了与匹配的 case 值相关的所有语句后,停止程序继续执行开关块,除非这正是你所需要的。例如,每个包含三个值的代码块都需要一条语句,就像这样:
switch( variable-name )
{
case value1 ; case value2 ; case value3 ;
statements-to-be-executed ; break ;
case value4 ; case value5 ; case value6 ;
statements-to-be-executed ; break ;
}
通常情况下,每个 case 语句都有自己的执行语句集,并以 break 结束,如相反的程序。
switch.cpp
#include <iostream>
using namespace std;
int main()
{
int num = 3;
switch ( num )
{
case 1 : cout << num << " : Monday"; break;
case 2 : cout << num << " : Tuesday"; break;
case 3 : cout << num << " : Wednesday" ; break;
case 4 : cout << num << " : Thursday"; break;
case 5 : cout << num << " : Friday"; break;
default : cout << num << " : Weekend day";
}
cout << endl;
return 0;
}
执行
# ./switch
3 : Wednesday
请注意,默认语句后面不需要使用 break 关键字,因为默认语句总是出现在 switch 语句的最后。
3.3 for
循环是程序中自动重复的一段代码。循环的迭代次数由循环中的条件测试控制。当测试的表达式为真时,循环将继续进行,直到测试的表达式变为假时,循环结束。
C++ 编程中的三种循环结构是 for 循环、while 循环和 do-while 循环。最常用的循环可能是 for 循环,其语法如下
for ( initializer ; test-expression ; incrementer ) { statements }
初始化器为循环迭代次数的计数器设置起始值。为此使用了一个整数变量,传统上命名为 “i”。在循环的每次迭代中,都会对测试表达式进行评估,只有当该表达式为真时,迭代才会继续。当测试表达式为假时,循环立即结束,不再执行语句。每次迭代时,计数器都会递增,然后执行语句。
循环可以嵌套在其他循环中,这样内循环将在外层循环的每次迭代中完全执行其迭代。
#include <iostream>
using namespace std;
int main()
{
int i , j;
for ( i = 1; i < 4; i++ )
{
cout << "Loop iteration: " << i << endl;
// Uncomment the lines below to add the nested loop.
// for ( j = 1; j < 4; j++ )
// {
// cout << " Inner loop iteration: " << j << endl;
// }
}
return 0;
}
执行
# ./forloop
Loop iteration: 1
Loop iteration: 2
Loop iteration: 3
3.4 while
for循环的一种替代方法是使用while关键字,后面跟一个待求值表达式。当表达式为真时,将执行测试表达式后面大括号中的语句。然后将再次评估表达式,并继续执行 while 循环,直到发现表达式为假为止。
循环的语句块必须包含会影响测试表达式的代码,以便将评估结果更改为假,否则将创建一个会锁定系统的无限循环!当被测试表达式在第一次求值时被发现为假时,while 循环的语句块将永远不会被执行。
while循环的一个微妙变化是在循环的语句块前加上do关键字,并在其后加上 while 测试,语法如下:
do { statements-to-be-executed } while ( test-expression );
在 do-while 循环中,语句块总是至少被执行一次,因为表达式在循环第一次迭代后才会被求值。如果不小心开始运行一个无限循环,请按 Ctrl + C 键终止进程。
可以在任何类型的循环中加入 break 语句,以便在满足测试条件时立即终止循环。break 语句可确保不再执行该循环的迭代。同样,可以在任何一种循环中加入 continue 语句,以便在满足测试条件时立即终止循环的特定迭代。continue 语句允许循环进行下一次迭代。
while.cpp
{
int i = 0;
vector <int> vec(10);
while ( i < vec.size() )
{
i++; // 1 - 10
// Uncomment the next line to skip at three.
if ( i== 3 ) { cout << " | Skipped"; continue; }
// Uncomment the next line to break on eight.
if ( i == 8 ) { cout << endl << "Done"; break; }
vec[ i-1 ] = i; // vec[0] = 1, vect[1] = 2, etc.
cout << " | " << vec.at( i-1 );
}
cout << endl;
return 0;
}
执行
# ./forloop
Loop iteration: 1
Loop iteration: 2
Loop iteration: 3
参考资料
- 软件测试精品书籍文档下载持续更新 https://github.com/china-testing/python-testing-examples 请点赞,谢谢!
- 本文涉及的python测试开发库 谢谢点赞! https://github.com/china-testing/python_cn_resouce
- python精品书籍下载 https://github.com/china-testing/python_cn_resouce/blob/main/python_good_books.md
- Linux精品书籍下载 https://www.cnblogs.com/testing-/p/17438558.html
- https://askubuntu.com/questions/1408873/ubuntu-22-04-chinese-simplified-pinyin-input-support
3.5声明函数
函数包含一段为程序提供特定功能的代码。从主程序调用函数时,将执行其语句,完成后可选择将值返回给主程序。使用函数有三大好处:
- 函数使程序代码更易于理解和维护。
- 其他程序可以重复使用经过测试的函数。
- 在大型项目中,多个程序员可以通过处理程序中的不同函数来分担工作量。
每个函数都在程序代码的早期以”原型”的形式声明,原型由函数返回值的数据类型和函数名组成,函数名后有括号,括号中可选择包含函数可能使用的”参数”数据类型列表。函数原型声明的语法如下
return-data-type function-name ( arguments-data-type-list );
// 示例
float computeArea( float, float );
严格来说,函数原型中的参数被称为 “形式参数”。
函数的定义出现在程序代码的后面,包括原型的重复和实际的函数体。函数体是每次调用函数时要执行的语句,包含在一对大括号中。如果函数不会向调用者返回任何值,请使用 void 关键字。
编译器会根据原型检查函数定义,因此实际返回的数据类型必须与原型中指定的数据类型一致,而且提供的任何参数在数量和数据类型上都必须一致。如果定义与原型不匹配,编译就会失败。一个简单的 computeArea 定义可能如下所示:
float computeArea( float width, float height )
{
return ( width * height ) ;
}
在函数中声明的变量只能在该函数的本地使用,不能在其他函数中全局访问。这种限制被称为 “变量作用域”。
#include <iostream>
using namespace std;
float bodyTempC();
float bodyTempF();
int main()
{
cout << "Centigrade: " << bodyTempC() << endl;
cout << "Fahrenheit: " << bodyTempF() << endl;
return 0;
}
float bodyTempC()
{
float temperature = 37.0;
return temperature;
}
float bodyTempF()
{
float temperature = 98.6;
return temperature;
}
执行
# ./scope
Centigrade: 37
Fahrenheit: 98.6
3.6传递参数
函数调用经常向函数提供参数值。这些参数可以是任何数量和数据类型,但必须与函数原型声明中指定的参数一致。
传递给函数的参数仅提供原始值的副本,这种过程称为”按值传递”。
传递给参数的值可以是程序代码中指定的”静态”值,也可以是用户输入的”动态”值。在命令提示符下,C++ 的 cin 函数可以与 >> 输入流操作符一起使用。
在定义函数之前,必须先声明函数原型。通常,函数原型出现在主函数之前,而函数定义则出现在主函数之后。
函数原型可以为参数指定默认值,当调用没有传递参数值时,将使用默认值。可以在原型中为多个参数分配缺省值,但这些参数必须始终出现在参数列表的末尾,排在其他参数之后。
与主函数可以调用函数一样,函数也可以调用其他函数并传递参数。
#include <iostream>
using namespace std;
float fToC( float degreesF = 32.0 );
int main()
{
float fahrenheit, centigrade;
cout << "Enter a Fahrenheit temperature: ";
cin >> fahrenheit;
centigrade = fToC( fahrenheit );
cout << fahrenheit << "F is " << centigrade << "C";
cout << endl << "Freezing point: " << fToC() << "C";
cout << endl;
return 0;
}
float fToC( float degreesF )
{
float degreesC = ( (5.0 / 9.0 ) * ( degreesF - 32.0 ) );
return degreesC;
}
执行
# ./args
Enter a Fahrenheit temperature: 89
89F is 31.6667C
Freezing point: 0C
3.7函数重载
函数”重载”允许同名函数在同一程序中并存,前提是它们的参数在数量、数据类型或数量和数据类型上有所不同。编译器通过识别函数参数的数量和数据类型,将函数调用与正确版本的函数相匹配,这一过程被称为”函数解析”。
当要执行的任务相似但又有细微差别时,创建重载函数非常有用。
#include <iostream>
using namespace std;
float computeArea( float );
float computeArea( float, float );
float computeArea( char, float, float );
int main()
{
float num, area;
cout << "Enter dimension in feet: ";
cin >> num;
area = computeArea( num );
cout << "Circle: Area = " << area << " sq.ft." << endl;
area = computeArea( num, num );
cout << "Square: Area = " << area << " sq.ft." << endl;
area = computeArea( 'T', num, num );
cout << "Triangle: Area = " << area << "sq.ft." << endl;
return 0;
}
float computeArea( float diameter )
{
float radius = ( diameter / 2 );
return ( 3.141593 * (radius * radius) );
}
float computeArea( float width, float height )
{
return ( width * height);
}
float computeArea( char letter, float width , float height )
{
return ( width / 2 ) * height;
}
执行
# ./overload
Enter dimension in feet: 89
Circle: Area = 6221.14 sq.ft.
Square: Area = 7921 sq.ft.
Triangle: Area = 3960.5sq.ft.
# ./overload
Enter dimension in feet: 89.9
Circle: Area = 6347.6 sq.ft.
Square: Area = 8082.01 sq.ft.
Triangle: Area = 4041.01sq.ft.
3.8递归
函数可以递归调用自己,以重复执行其函数体中包含的语句,这与循环非常相似。与循环一样,递归函数必须包含递增器和条件测试,以便再次调用自身,或在满足条件时停止重复。递归函数的语法如下:
递增器将改变传递参数的值,因此后续调用将把调整后的值传递回函数。
return-data-type function-name ( argument-list )
{
statements-to-be-executed ;
incrementer ;
conditional-test-to-recall-or-exit ;
}
int main()
{
computeFactorials( 1, 8 );
return 0;
}
int computeFactorials( int num, int max )
{
cout << "Factorial of " << num << ": ";
cout << factorial( num ) << endl;
num++;
if( num > max ) return 0;
else return computeFactorials( num , max );
}
int factorial( int n )
{
int result;
if( n == 1 ) result = 1;
else
result = ( factorial( n - 1 ) * n );
return result;
}
执行
# ./optimize
Factorial of 1: 1
Factorial of 2: 2
Factorial of 3: 6
Factorial of 4: 24
Factorial of 5: 120
Factorial of 6: 720
Factorial of 7: 5040
Factorial of 8: 40320
输出会列出阶乘值(阶乘 3 是 3x2x1=6,等等),但可以通过优化阶乘()函数来改进程序。如果使用三元运算符编写该函数,就不需要变量。它只包含一条语句,因此其定义可以取代原型声明,成为 “内联 “声明。这意味着程序无需在声明和定义之间进行检查,从而提高了效率。
在C++中,”内联”(inline)是一个关键字,用于提示编译器在编译时将函数调用处的代码替换为函数体,以避免函数调用的开销。内联函数的目的是提高程序的执行效率。
使用内联函数可以减少函数调用的开销,因为函数调用涉及保存现场、压栈、跳转等操作,而内联函数的代码会直接插入到调用处,避免了这些开销。内联函数适用于函数体较短、频繁调用的情况。
内联函数的使用是一种建议,而非强制性要求。编译器会根据一些因素(如函数体大小、调用频率等)来决定是否将函数进行内联展开。此外,内联函数的定义通常应该放在头文件中,以便在多个源文件中进行内联展开。
需要注意的是,过度使用内联函数可能导致代码膨胀,增加可执行文件的大小。因此,在使用内联函数时,需要权衡代码大小和执行效率之间的平衡,合理选择使用内联的函数。
3.9小结
- if语句将给定的测试表达式评估为布尔值的真或假。
- 在if语句后面的大括号中包含的语句只有在评估结果为真时才会被执行。
- if和else关键字用于根据测试表达式的结果执行条件性分支。
- witch语句是条件性分支的另一种形式,它将case语句与给定值相匹配。
- for 循环结构有参数声明初始化器、测试表达式和增量器或减量器。
- while循环和do-while循环必须在其循环体中始终有一个递增器或递减器。
- 任何类型的循环都可以通过在循环体中加入break语句来立即终止。
- 任何类型的循环的单次迭代都可以通过在循环体中加入continue语句而被跳过。
- 函数通常在程序开始时被声明为原型,并在主函数之后定义。
- 在一个函数中声明的变量只能从该函数中访问,因为它们只有局部范围。
- 如果在函数原型和定义中声明了参数,那么值可以被传入函数。
- 重载函数具有相同的名称,但声明的参数数量或类型不同。
- 递归函数重复调用自己,直到满足测试条件。
- 只有一个或两个语句的简短的函数定义可以用inline关键字代替原型来声明。
声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/388766.html