选择结构
选择结构是用来控制程序流程,使得程序可以根据不同的条件执行不同的代码块。
if语句
简单结构
if (表达式)
{
// 表达式为真时执行的语句。
}
else
{
// 表达式为假时执行的语句。
}
#include <iostream>
#include <string>
using namespace std;
int assessment(int regular_grade, int midterm, int final, float regular_weight = 0.3, float midterm_weight = 0.2, float final_weight = 0.5)
{
if (regular_grade * regular_weight + midterm * midterm_weight + final * final_weight >= 60)
{
return 1;
}
else
{
return 0;
}
}
上述代码中使用到了一点函数内容,功能是计算一下科目是否通过(计算平时分,期中期末成绩以及不同加权)。代码使用了最简单的选择结构,如果三类成绩累计大于60分,那么本科通过,否则不通过。
嵌套结构
嵌套结构简单理解为if里面套if,进行多次判断,我们已经实现评估函数,我们可以继续设计一个评奖评优的函数,当评估函数返回1(成绩通过)的情况下,如果总绩点排在本专业前5%时拥有评奖评优资格,这就是嵌套结构。
if (表达式一)
{
if (表达式二)
{
// 表达式二为真时执行的语句。
}
else
{
// 表达式二为假时执行的语句。
}
}
else
{
// 表达式一为假时执行的语句。
}
需要注意的是,else总是与前面最近if 配对。如果要改变这种配对关系,可以使用花括号来确定新的配对关系。
多条件if语句
if (表达式一)
{
// 表达式一为真时执行的语句。
}
else if (表达式二)
{
// 表达式二为真时执行的语句。
}
else if (表达式三)
{
// 表达式三为真时执行的语句。
}
……
else if (表达式n)
{
// 表达式n为真时执行的语句。
}
else
{
// 全部表达式都不为真时执行的语句。
}
三目运算符
用的不多,因为逻辑一复杂,三目运算符可读性差,了解即可 。
表达式一 ? 表达式二 : 表达式三
max = a>b?a:b//返回a和b之间较大的
switch语句
多条件if语句有点不方便,如果条件具有很高的共性,比如月份,星期等等,这是使用switch会更方便。
switch (表达式)
{
case 值一:
语句一;
break;
case 值二:
语句二;
break;
......
case 值n:
语句n;
break;
default:
上述条件都不满足时执行的语句;
}
注意:
- case后面必须是整数和字符,或者是结果为整数和字符的表达式,但不能使用变量。
- default不是必须的,当没有default时,如果全部的case匹配失败,那么就什么都不执行。
- 每个分支不要漏写break语句。
循环结构
循环结构是用来重复执行某段代码,直至满足特定条件停止的控制结构。
while循环
while (表达式)
{
语句块
}
#include <iostream>
using namespace std;
int main()
{
int sum = 0;
int n = 1;
while (n <= 100)
{
sum += n;
n++;
}
cout << "Sum:" << sum << endl;
return 0;
}
上述代码功能就是计算1-100的累和
for循环
语法:
for (语句一 ; 表达式 ; 语句二)
{
语句块
}
1)循环开始的时候,先执行语句一,在整个循环过程中语句一只会被执行一次。
2)计算表达式的值,如果为真,就执行一次循环体中的语句块。
3)执行完语句块后,执行一次语句二。
4)重复第2)步和第3),直到表达式的值不为真才结束for循环。
注意:
- 不要纠结for循环与while循环的区别,它们本质上没有区别。
- for循环一般需要一个相当于计数器的变量,在语句一中对它进行初始化,在语句二中进行计数操作。
- 在for循环的语句一中,可以声明计数器变量。
- 在for循环中,语句一、表达式和语句二都可以为空,for (;;)等同于while (true)。
- continue和break两个关键字也可以用在for循环体中。
int *pass_rate_iteration(int form[3][3])
{
static int result[3] = {0};
int i;
for (i = 0; i < 3; i++)
{
int regular_grade = form[i][0];
int midterm = form[i][1];
int final = form[i][2];
int grade = assessment(regular_grade, midterm, final);
result[i] = grade;
}
return result;
}
上述代码功能为将每个学生的三类成绩的二维数组通过评估函数映射到一维数组(通过与否),每个学生的计算过程相似,所以我们使用循环结构。
嵌套循环
#include <iostream> // 包含头文件。
using namespace std; // 指定缺省的命名空间。
int main()
{
// 超女分4个小组,每个小组有3名超女,在控制台显示每个超女的小组编号和组内编号。
// 用一个循环,显示4个小组的信息。
// for (int ii=1; ii<=4; ii++)
//{
// // 再用一个循环,显示一组中3名超女的信息。
// for (int jj = 1; jj <= 3; jj++)
// {
// cout << "这是第" <<ii<<"个小组的第" << jj << "名超女。\n";
// }
//}
// 在控制台输出九九乘法表。
for (int ii = 1; ii <= 9; ii++)
{
for (int jj = 1; jj <= ii; jj++)
{
cout << ii << "*" << jj << "=" << ii * jj << " ";
}
cout << endl;
}
}
除此之外,还有do...while语句和goto语句,前者可以用while替换,后者容易造成逻辑混乱,一般不使用,这里就不赘述了。
函数
函数(Function)是一段可重用的代码,它执行特定任务并可能返回一个结果。函数有助于提高代码的模块化、可读性和可维护性。
声明与定义
在复杂的程序中,如果全部的代码都写在main函数中,main函数体将非常庞大臃肿。
把任务分工到其它的函数中,main函数只负责程序的核心流程,具体的任务由其它函数完成。
这种思想就是模块化编程。
声明和定义函数的语法:
返回值的数据类型 函数名(参数一的数据类型 参数一, 参数二的数据类型 参数二,……)
{
实现函数功能的代码。
return 返回值;
}
函数的声明:让编译器知道函数的存在,包括返回值的数据类型、函数名和参数列表。
函数的定义:函数的实现过程。
注意:
- 函数的声明和定义可以书写在一起,也可以分开,如果书写在一起,一般放在main函数的上面,如果分开,一般在main函数的上面声明,在main函数的下面定义。
- 如果函数的声明和定义分开书写,函数的声明后面一定要有分号,函数的定义后面一定不能写分号。
- 在同一个程序中,函数只需要声明和定义一次,也可以多次声明,但只能定义一次。
- 函数的声明必须和函数的定义一致(返回值的数据类型、函数名和参数列表),如果函数名和参数列表不同,表示它们不是同一个函数。
- return语句返回值的数据类型必须与函数的声明一致。
- 在函数体中,return语句可以多次使用。
- 如果函数的重点是实现功能,不关心返回值,返回值的数据类型填void,return语句后面就空着。
- 函数可以没有任何参数。
- 函数名是标识符,必须满足标识符的命名规则。
- 在函数的声明和函数的定义中,参数命名可以不同,但是没必要这么书写。
函数调用
语法:函数名(参数一,参数二,……)
注意:
- 声明函数的代码必须放在调用之前,定义函数的代码可以放在调用之后。
- 调用函数的时候,参数列表必须与函数的声明一致(参数的个数、书写的顺序和数据类型)。
- 不管在什么地方,都不能调用main函数,但是,在普通函数中,可以调用其它的普通函数。
- 调用函数的代码可以独占一条语句,也可以用于表达式(赋值运算、算术运算、关系运算、函数的参数)。
- 如果函数用于表达式中,返回值的数据类型要匹配(否则可能会被隐式转换或编译错误)。
- 如果函数有返回值,可以不关心它,忽略它。
变量作用域
作用域是指程序中变量存在(或生效)的区域,超过该区域变量就不能被访问。
变量分全局变量和局部变量两种,全局变量在整个程序中都可以访问,局部变量只能在函数或语句块的内部才能访问。
C++中定义变量的场景主要有五种:
1)在全部函数外面定义的是全局变量。
2)在头文件中定义的是全局变量。
3)在函数和语句块内部定义的是局部变量。
4)函数的参数是该函数的局部变量。
5)函数内部用static修饰的是静态局部变量。
1)全局变量
在整个程序生命周期内都是有效的,在定义位置之后的任意函数中都能访问。
全局变量在主程序退出时由系统收回内存空间。
2)局部变量
在函数或语句块内部的语句使用,在函数或语句块外部是不可用的。
局部变量在函数返回或语句块结束时由系统收回内存空间。
3)静态局部变量
用static修饰的局部变量生命周期和程序相同,并且只会被初始化一次。
其作用域为局部,当定义它的函数或语句块结束时,其作用域随之结束。
当程序想要使用全局变量的时候应该先考虑使用static(考虑到数据安全性)。
4)注意事项
- 全局变量和静态局部变量自动初始化为0。
- 局部变量不会自动初始化,其值是不确定的,程序中应该有初始化局部变量的代码,否则编译可能会报错(不同的编译器不一样)。
- 局部变量和全局变量的名称可以相同,在某函数或语句块内部,如果局部变量名与全局变量名相同,就会屏蔽全局变量而使用局部变量,如果想使用全局变量,可以在变量名前加两个冒号(::)。
- for循环初始化语句中定义的变量的作用域是for语句块。
函数参数的传递
调用函数的时候,调用者把数值赋给了函数的参数。
实参:调用者程序中书写的在函数名括号中的参数,可以是常量、变量和表达式。
形参:函数的参数列表。
在函数定义的代码中,修改形参的值,会不会影响实参。
#include <iostream>
#include <string>
using namespace std;
int assessment(int regular_grade, int midterm, int final, float regular_weight = 0.3, float midterm_weight = 0.2, float final_weight = 0.5)
{
if (regular_grade * regular_weight + midterm * midterm_weight + final * final_weight >= 60)
{
return 1;
}
else
{
return 0;
}
}
int *pass_rate_iteration(int form[3][3])
{
static int result[3] = {0};
int i;
for (i = 0; i < 3; i++)
{
int regular_grade = form[i][0];
int midterm = form[i][1];
int final = form[i][2];
int grade = assessment(regular_grade, midterm, final);
result[i] = grade;
}
return result;
}
int main()
{
int student[3][3] = {{90, 90, 90}, {70, 48, 49}, {100, 44, 38}};
int *pass_form = pass_rate_iteration(student);
for (int i = 0; i < 3; i++)
{
cout << pass_form[i] << endl;
}
return 0;
}
函数分文件编写
头文件(*.h):需要包含的头文件,声明全局变量,函数的声明,数据结构和类的声明等。
源文件(*.cpp):函数的定义、类的定义。
主程序:main函数,程序的核心流程,需要用#include "头文件名"把头文件包含进来。
编译:
Windows是集成开发环境,不需要写编译指令。