您的位置:首页 > 编程语言 > C语言/C++

《C++大学教程》学习笔记(五)

2018-02-09 16:25 423 查看

《C++大学教程》学习笔记(五)

for循环、do…while循环的基本运用很简单,不再赘述。

1.计算复利问题

计算复利,会用到cmath头文件内的pow函数,pow函数接受两个double类型的实参。

使用流操纵符格式化输出,除了之前学过的setprecision和fixed外,本节引入了setw流操纵符,具体用法如下:

cout << setw(4) << year << setw(21) << amount << endl;


set(4)规定了下一个输出值(year)应占用的域宽是4,set(21)规定了下一个输出值(amount)应占用的域宽是21。值得注意的是,如果输出的值小于设定的域宽,则默认向右对齐;如果超出域宽,则向右侧扩展。

关于流操作符setprecision和fixed,再额外提一句,当我们在代码中写过了一句:

cout << fixed << setpricision(2);


这些格式的设置如果不被更改则会一直起作用,没有必要在之后再次设置它们,我们称这样的设置为黏性设置(sticky setting),具体可以参考下面的完整代码。

main.cpp文件:

//银行复利问题
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;

int main(){

double principal = 1000.0;       //本金
double amount;                   //本利总和
double rate = 0.05;              //利率

cout << setw(4) << "Year" << setw(21) << "Amount on deposit" << endl;
//这里的setw(4)不加也不影响输出格式,因为year正好就占4个域宽
cout << fixed << setprecision(2);           //格式化浮点数,保留两位

for (int year = 1; year <= 10; year++) {

amount = principal * pow(1.0 + rate, year);

cout << setw(4) << year << setw(21) << amount << endl;
}

}


输出的结果如下图所示:



根据图片就很好理解不同流操纵符的作用。

2.switch语句

switch语句也是一个较为常见的选择语句,值得一提的是switch语句内的case只可用于测试整形常量表达式——字符常量or整形常量。

在MacOS中,EOF的输入可以通过Ctrl+d来实现。

下面给出一个基于GradeBook类的switch实例代码:

GradeBook.h文件:

#include <iostream>
#include <string>
using namespace std;

class GradeBook{
private:
string courseName;
unsigned int aCount;
unsigned int bCount;
unsigned int cCount;
unsigned int dCount;
unsigned int fCount;

public:

explicit GradeBook(string);
void setCourseName(string);
string getCourseName() const;
void displayMessage() const ;
void determineClassAverage() const;
void inputGrades();
void displayGradeReport() const;
};


GradeBook.cpp文件:

#include "GradeBook.h"
#include <iomanip>

GradeBook::GradeBook(string name)
:aCount(0),bCount(0),cCount(0),dCount(0),fCount(0)
{
setCourseName(name);
}

void GradeBook::setCourseName(string name){

if (name.size() <= 25)
courseName = name;
else{
courseName = name.substr(0,25);            //复制子字符串:从下表0开始,长度为25
cerr << "More than 25!\n" ;                //cerr用来输出错误信息
}
}

string GradeBook::getCourseName() const{
return courseName;
}

void GradeBook::displayMessage() const {
cout << "Welcome to:" << getCourseName() << endl << endl;
}

void GradeBook::determineClassAverage() const{
int total = 0;
unsigned int gradeCount = 0;

cout << "Enter grade or -1 to quit: ";
int grade = 0;
cin >> grade;

while (grade != -1) {
total += grade;
gradeCount++;

cout << "Enter grade or -1 to quit: ";
cin >> grade;
}

if (gradeCount != 0){
double average = static_cast<double>(total) / gradeCount;
//static_cast显式类型转换,不改变原total的类型(int),仅生成一个total的浮点数(double)副本

cout << "Total is: " << total << endl;
cout << setprecision(2) << fixed;               //C++中格式化浮点数,setprecision属于iomanip头文件
cout << "Average is: " << average << endl;
//printf("Average is: %.2f\n",average);         //传统C式保留小数点后两位
}
else
cout << "No grades were entered!" << endl;
}

void GradeBook::inputGrades(){

int grade;       //存储输入字符的ASCII码

cout << "Enter the grade.\n" << "Enter the EOF character to end input.\n";

while ((grade = cin.get()) != EOF) {        //MacOS中EOF输入符是ctrl+d
switch (grade) {
case 'A':
case 'a':
aCount++;
break;

case 'B':
case 'b':
bCount++;
break;

case 'C':
case 'c':
cCount++;
break;

case 'D':
case 'd':
dCount++;
break;

case 'F':
case 'f':
fCount++;
break;

case '\n':
case '\t':
case ' ':
break;

default:
cout << "Incorrect grade entered.Enter a new grade:\n";
break;
}
}
}

void GradeBook::displayGradeReport() const{
cout << "\n\nSummary: ";
cout << "\nA: " << aCount;
cout << "\nB: " << bCount;
cout << "\nC: " << cCount;
cout << "\nD: " << dCount;
cout << "\nF: " << fCount << endl;
}


main.cpp文件:

#include "GradeBook.h"

int main(int argc, const char * argv[]) {

GradeBook myGradeBook("CS Programming Learning");

myGradeBook.displayMessage();
myGradeBook.inputGrades();
myGradeBook.displayGradeReport();

return 0;
}


程序测试结果如下图所示:



3.仍然是流操纵符

一道自测练习题,很有代表性:

分别以精度1、2和3,域宽为15个字符打印333.546372,要求打印出的三个值在同一行上,在各自的域宽内向左对齐

下面是代码:

#include <iostream>
#include <iomanip>
using namespace std;

int main(int argc, const char * argv[]) {

cout << fixed << left
<< setprecision(1) << setw(15) << 333.546372
<< setprecision(2) << setw(15) << 333.546372
<< setprecision(3) << setw(15) << 333.546372
<< endl;

return 0;
}


运行结果如下图所示:



4.break与continue

这两句语句本身没有什么可说的,但书中提到了“有些程序员认为break和continue语句违背了结构化编程的思想”,细思之下确实如此。尽管这两句语句没有goto那么强的“破坏力”,但一定程度上的确不够结构化。

结构化编程提倡简单性,即任何形式的控制都可以用顺序、选择和循环语句来表达,并且这些语句的组合方式只有两种——堆叠和嵌套。

可惜的是习惯没那么好改,让我不用break,基本做不到。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: