Exercises and Solutions of Chapter 1

2023-12-25 23:10
文章标签 chapter solutions exercises

本文主要是介绍Exercises and Solutions of Chapter 1,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • Exercise 1-0——Test chapter programs
  • Exercise 1-1——Understanding string concatenation
  • Exercise 1-2——Understanding string concatenation
  • Exercise 1-3——Understanding scope
  • Exercise 1-4——Understanding scope
  • Exercise 1-5——Understanding scope
  • Exercise 1-6——Explore the “hidden” std::cin buffer operations

1-0 Compile, execute, and test the programs in this chapter.

Solution:

Program 1: say hello to a specific person. It will ask for a person’s name and generate a specific greeting as its output.

// ask for a person's name, and greet the person
#include <iostream>
#include <string>
int main()
{// ask for the person's namestd::cout << "Please enter your first name: ";// read the namestd::string name; // define namestd::cin >> name; // read into// write a greetingstd::cout << "Hello, " << name << "!" << std::endl;return 0;
}

7314beb7efbe4573999deeb703e514b5.png

Program 2: a more elaborate greeting. It will produce five lines of output. The first line begins the frame. It is a sequence of * characters as long as the greeting, plus a space and an * at each end. The second line will be an appropriate number of spaces with an * at each end. The third line is an *, a space, the greeting, a space, and an *. The last two lines will be the same as the second and first lines, respectively.

// ask for a person's name, and generate a framed greeting
#include <iostream>
#include <string>
int main()
{std::cout << "Please enter your first name: ";std::string name;std::cin >> name;// build the message that we intend to writeconst std::string greeting = "Hello, " + name + "!";// build the second and fourth lines of the outputconst std::string spaces(greeting.size(), ' ');const std::string second = "* " + spaces + " *";// build the first and fifth lines of the outputconst std::string first(second.size(), '*');// write it allstd::cout << std::endl;std::cout << first << std::endl;std::cout << second << std::endl;std::cout << "* " << greeting << " *" << std::endl;std::cout << second << std::endl;std::cout << first << std::endl;return 0;
}

b4b61ef95f4e403f85984f46ebde7d29.png

 

1-1 Are the following definitions valid? Why or why not?

const std::string hello = "Hello";
const std::string message = hello + ", world" + "!";

Solution:

Yes, these definitions are valid. Line 1 defines a string variable hello with length of 5 characters (which is “Hello”). Line 2 defines a string variable message with the concatenation operator. The logic looks like this:

message = ( ( hello + ", world" ) + "!")= ( ( a string + a string literal ) + a string literal )= ( ( a string ) + a string literal )= ( a string + a string literal )= ( a string )

The key in answering this question is to acknowledge the use of the string concatenation operator +.

  1. It is left associative.
  2. We can use + to concatenate a string and a string literal (and vice versa), or a string and a string, but not a string with a string literal (nor vice versa).

We could verify our conclusion by running this program:

#include <iostream>
#include <string>
int main()
{const std::string hello = "Hello";const std::string message = hello + ", world" + "!";std::cout << message << std::endl;return 0;
}

 

1-2 Are the following definitions valid? Why or why not?

const std::string exclam = "!";
const std::string message = "Hello" + ", world" + exclam;

Solution:

No, the use of the concatenation operator is not valid. i.e. we bump into a “taboo” scenario: string literal + string literal, which is not valid.

  • Line 1 defines a string variable exclam, which is valid.
  • Line 2 defines a string variable message with the concatenation operator. The logic looks like this:
message = ( ( "Hello " + ", world" ) + exclam)= ( ( a string literal + a string literal ) + a string )= ( ( compilation error! ) + a string)

We could verify our conclusion by running this program:

#include <iostream>
#include <string>
int main()
{const std::string exclam = "!";const std::string message = "Hello  + ", world" + exclam;std::cout << message << std::endl;return 0;
}

The compilation error may look like this:

error: invalid operands of types 'const char [6]' and 'const char [8]' to binary 'operator+'

 

1-3 Is the following program valid?

#include <iostream>
#include <string>
int main()
{{ const std::string s = "a string";std::cout << s << std::endl; }{ const std::string s = "another string";std::cout << s << std::endl; }return 0;
}

Solution:

Yes, the program is valid. The key to this question is to understanding the term scope. Each pair of curly braces form a scope. Within the main function (scope), we have two sub-scopes (block), as defined by the two pairs of curly braces. Each block constitute its own scope——all local variables and statements within each scope are independent to each other. Because of this, even though there is a const std::string variable eq?s in block 1, it is okay to define another const std::string variable eq?s in block 2——due to the fact the two variables are in different scopes.

 

1-4 Is the following program valid? What if we add a semi-colon (;) between the second-last and third-last right curly braces?

#include <iostream>#include <string>int main()
{{const std::string s = "a string";std::cout << s << std::endl;{ const std::string s = "another string";std::cout << s << std::endl;}}
}

Solution:

Part one:

Yes, the program is valid. Each pair of curly braces {} form a scope. It is okay to have scopes nested within a scope. For clarity let me add some comments to the code to visualise these scopes:

#include <iostream>
#include <string>
int main()
{//scope main starts{   //scope main-1 startconst std::string s = "a string";std::cout << s << std::endl;{   //scope main-1-1 startsconst std::string s = "another string";std::cout << s << std::endl;}  //scope main-1-1 ends}  //scope main-1 ends
} //scope main ends

The const std::string variable eq?s in scope main-1 is not the same const std::string variable eq?s in scope main-1-1 (which is nested inside scope main-1). Even though scope main-1-1 is nested inside scope main-1, all local variables inside scope main-1-1 is hidden from view of main-1.

Notably, string eq?s is not overwritten in the inner scope——it is still available from the outer scope.

 

Part two:

Adding a semi-colon (;) between the second last and third last right curly braces will still constitute a valid program. For clarity, this is what the program would look like with that semi-colon:

#include <iostream>
#include <string>
int main()
{//scope main starts{   //scope main-1 startconst std::string s = "a string";std::cout << s << std::endl;{   //scope main-1-1 startsconst std::string s = "another string";std::cout << s << std::endl;}  //scope main-1-1 ends;  // the additional semi-colon}  //scope main-1 ends
} //scope main ends

The additional semi-colon essentially creates a null-statement within the main-1 scope. i.e. it has no effect to the code. I think the reason the authors ask this question is to solidify our understanding on scope. i.e. which scope does that semi-colon belong to? Writing a C++ code in the above manner helps us visualise this easier.

 

1-5 Is this program valid?

#include <iostream>
#include <string>
int main()
{{std::string s = "a string";{std::string x = s + ", really";std::cout << s << std::endl;}std::cout << x << std::endl;}return 0;
}

Solution:

No. The program is not valid and requires correction. Notably, one scope may not “see” what’s inside the other scope(s). For clarity let me add some comments to the code to visualise these scopes:

// original program with comments added to visualise scope
#include <iostream>
#include <string>
int main()
{ // scope main starts{ // scope main-1 startsstd::string s = "a string";{ // scope main-1-1 startsstd::string x = s + ", really";std::cout << s << std::endl;} //scope main-1-1 endsstd::cout << x << std::endl;} // scope main-1 endsreturn 0;
} // scope main ends

All local variables defined at the outer scope level may be seen/used by the inner scopes (at all levels); However, the reverse is not possible. i.e. All local variables defined at the inner scope level may NOT be seen/used by the outer scopes (at all levels), nor the scopes adjacent to it. (i.e. same level scopes). The permeation of variables go from outer scope, to inner scope. It does not permeate to other scopes at the same level, and/or the inner scopes (at all levels).

scope main-1-1 can see std::string variable s (which is defined in the outer scope main-1), and its own defined std::string variable x.

scope main-1 can see only its own defined variable std::string s. It cannot see the std::string variable x that lives at the inner scope main-1-1 level. It fails to perform that “std::cout << x << std::endl” step because it doesn’t know what x is. From scope main-1’s perspective, the variable x is not declared.

scope main has no idea of any variables defined in the inner scopes main-1 nor main-1-1. All it knows is that whenever the implementation hits the return statement, it is done.

The compilation error may look like this:

line(12): error: ‘x’ was not declared in this scope

To make the std::string x visible to the scope main-1, we can simply move the scope main-1-1 up one level by removing the curly braces. Like this:

// corrected
#include <iostream>
#include <string>
int main()
{ // scope main starts{ // scope main-1 startsstd::string s = "a string";std::string x = s + ", really";std::cout << s << std::endl;std::cout << x << std::endl;} // scope main-1 endsreturn 0;
} // scope main ends

 

1-6 What does the following program do if, when it asks you for input, you type two names at a time(for example, Samuel Beckett)? Predict the behavior before running the program, then try it.

#include <iostream>
#include <string>
int main()
{std::cout << "What is your name? ";std::string name;std::cin >> name; // first std::cin stepstd::cout << " Hello, " << name<< std::endl  << "And what is yours?";std::cin >> name;  // second std::cin stepstd::cout << "Hello, " << name<< "; nice to meet you too!" << std::endl;return 0;
}

Solution:

At the first std::cin step we type in two words, “Samuel Beckett”, followed by hitting the enter key. The following happens:

(1) The two words initially get stored in the buffer (corresponding to std::string variable name)

Samuel Beckett

Note that the buffer automatically discard the leading and trailing blanks. Each word is separated by a space character.

(2) The first std::cin step causes the buffer to flush out the first word “Samuel” to the std::string variable assignment. The std::string name has now a value of “Samuel”. Because the first word has now been flushed out from the buffer, the buffer for name now looks like this:

Beckett

Note that the first word Samuel is now gone. It has been flushed away from the buffer.

(3) At the second std::cin step, becuase there is already a word in the buffer, it just simply asks the buffer to flush out that value and assign that to the std::string variable name. The std::string name has now a value of “Beckett” (and replace the old value “Samuel”). Now, the buffer for name looks like this:

 

The buffer is now empty!

If there turn out to be a third std::cin step, the user will be asked to supply more values to the buffer, so that the std::cin facility may read from it. (But in this case, the program only has two std::cin steps).

In summary, the std::cin checks the buffer corresponding to the std::string variable:

  1. If there is at least one word stored inside the buffer, it flushes the first word from the buffer, read and assign that word to the std::string variable. The program does not need to pause and ask the user to supply values.
  2. If the buffer is empty, the program would pause and ask the user to supply values (words) to the buffer. Only when there are words inside the buffer, the std::cin would then read from it and assign the value to the std::string variable (and flush that word away from the buffer as a consequence).

For completeness, let us run the program and confirm our understanding:

9f1d0b14dd124f68bdfdb8cad7f120f2.png

Notably, if, we provide no word at the first std::cin step, we will find that hitting the enter button does not get us anywhere——the program insists us to provide at least one word to the buffer.

 

这篇关于Exercises and Solutions of Chapter 1的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/537293

相关文章

C# step by step 学习笔记8 CHAPTER 9 使用枚举和结构创建值类型

C# 2012 step by step 学习笔记8 CHAPTER 9 使用枚举和结构创建值类型 本章内容 声明一个枚举类型创建并使用一个枚举类型声明一个结构类型创建并使用一个结构类型解释结构和类之间行为的差别 声明一个枚举         enum Season { Spring, Summer, Fall, Winter } 使用枚举         You

Chapter 1 总结

1.整数/整数=整数,浮点数/浮点数=浮点数。 分析:要正确的区分整数除法和浮点数除法。比如 8/5可以写成 1.0*8/5 或者 8.0/5 2.调试时使用 system("pause") 或者 cin.get() 3.尽量使用 const 来申明常量 4.一种的巧妙的变量交换(了解) 分析:举个实例就很容易看清! #include<io

《算法竞赛入门经典 第二版》 Chapter 3

讲解部分 1.开灯问题 分析:输出m个数,m-1个空格,利用一个中间变量做到 #include<iostream>#include<cstdio>using namespace std;int main(){const int maxn = 1010;int a[maxn] = { 0 };int n, k,first=1;cin >> n >> k;for (int i =

《算法竞赛入门经典 第二版》习题——Chapter 2

习题2-1 水仙花数(daffodil) #include<iostream>#include<cstdio>using namespace std;int main(){int a, b, c;for (int num = 100; num < 1000; num++){a = num / 100;b = num / 10 % 10;c = num % 10;if (num == a

机器学习Chapter-1(线性模型)

引言 先验条件好了下面开始正文本节的主角是线性模型 线性模型理论 概述线性回归 什么是回归什么是线性回归如何确定参数w和b如何求解w和b线性回归小结 广义线性模型 概述 逻辑回归 怎么用线性模型做分类什么样的函数满足分类要求怎么计算逻辑回归模型的参数估计 极大似然估计 从感性上认识数学表示 多分类回归模型该怎么办逻辑回归总结 线性判别分析 什么线性判别分析怎样找到线性判别分析的优化目标怎

NumPy实战:Chapter-1(初识NumPy)

为什么学习NumPy使用Ipython 打开IPython的shell界面保存会话执行系统的shell命令显示历史记录 使用notebook 运行notebook初试notebook导出基于Web的notebook导入基于Web的notebook SciPy和PIL 安装软件 安装SciPy 检查安装是否完成 安装PIL 检查安装是否完成 SciPy和PIL的实例 调整图像大小

TensorFlow实战:Chapter-6(CNN-4-经典卷积神经网络(ResNet))

ResNet ResNet简介相关内容论文分析 问题引出解决办法实现residual mapping实验实验结果 ResNet在TensorFlow上的实现 ResNet ResNet简介 ResNet(Residual Neural Network)由微软研究院的何凯明大神等4人提出,ResNet通过使用Residual Unit成功训练152层神经网络,在ILSCRC20

TensorFlow实战:Chapter-5(CNN-3-经典卷积神经网络(GoogleNet))

GoogleNet GoogleNet 简介GoogleNet大家族GoogleNet的发展 Inception V1Inception V2Inception V3Inception V4 GoogleNet论文分析 引言 详解 介绍相关工作动机和高层次考虑动机和高层次考虑 详解 GoogLeNet 详解 训练方法ILSVRC 2014 Classification Challenge

TensorFlow实战:Chapter-4(CNN-2-经典卷积神经网络(AlexNet、VGGNet))

引言AlexNet AlexNet 简介AlexNet的特点AlexNet论文分析 引言介绍数据集网络架构 注解注解 减少过拟合训练细节结果讨论参考文献略 AlexNet在TensorFlow里面实现 TensorFlow官方给出的AlexNet实现 实现代码输出 AlexNet应用在MNIST数据集上 实现代码 AlexNet应用在CIFAR10数据集上 总结 VGGNet VGGNet简

TensorFlow实战:Chapter-3(CNN-1-卷积神经网络简介)

卷积神经网络简介 CNN的提出CNN的壮大 卷积神经网络结构 卷积神经网络的常见网络结构卷积 信号处理中的卷积图像处理中的卷积卷积的类型的参数 卷积层 卷积层原理卷积层算法卷积层特点 权值共享多卷积核 池化层 池化层原理池化层算法池化层特点 池化单元的平移不变性显著减少参数数量 TensorFlow中的CNN 卷积 strides参数padding参数 tfnnconv2dtfnnco