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

相关文章

Chapter 13 普通组件的注册使用

欢迎大家订阅【Vue2+Vue3】入门到实践 专栏,开启你的 Vue 学习之旅! 文章目录 前言一、组件创建二、局部注册三、全局注册 前言 在 Vue.js 中,组件是构建应用程序的基本单元。本章详细讲解了注册和使用 Vue 的普通组件的两种方式:局部注册和全局注册。 本篇文章参考黑马程序员 一、组件创建 ①定义 Vue 组件是一种具有特定功能的 Vue 实

Chapter 10 Stability and Frequency Compensation

Chapter 10 Stability and Frequency Compensation Chapter 8介绍了负反馈, 这一章介绍稳定性, 如果设计不好, 负反馈系统是要发生震荡的. 首先我们学习理解稳定判断标准和条件, 然后学习频率补偿, 介绍适用于不同运放的补偿方式, 同时介绍不同补偿对两级运放slew rate的影响, 最后介绍Nyquist’s判断标准 10.1 Gener

[学习笔记]《CSAPP》深入理解计算机系统 - Chapter 3 程序的机器级表示

总结一些第三章的一些关键信息 Chapter 3 程序的机器级表示结构 updating... Chapter 3 程序的机器级表示 局部变量通常保存在寄存器中,而不是内存中,访问寄存器比内存快的多. 有些时候,局部数据必须存放在内存中, 寄存器不足够存放所有的本地数据对一个局部变量使用地址运算符 &, 因此必须能够为它产生一个地址某些局部变量是数组或结构,因此必须能够通过数组或

Chapter 10 async函数 await关键字

欢迎大家订阅【Vue2+Vue3】入门到实践 专栏,开启你的 Vue 学习之旅! 文章目录 前言一、async 函数二、await 关键字 前言 在现代 JavaScript 开发中,异步编程是一个重要的概念。随着 ES2017 的引入,async 函数和 await 关键字为处理异步操作提供了更简洁和可读的方式。本章详细讲解了这两个关键字的特性及其用法。 一、

Chapter 2 multi-armed Bandit

引用:https://blog.csdn.net/mmc2015/article/details/51247677 https://blog.csdn.net/coffee_cream/article/details/58034628 https://blog.csdn.net/heyc861221/article/details/80129310   The most importa

MATH36022 Numerical Analysis 2 Approximation of Functions – Week 3 Exercises

Show that the Chebyshev polynomials are orthogonal on ( − 1 , 1 ) (−1, 1) (−1,1) with respect to the weight function ( 1 − x 2 ) − 1 / 2 (1 − x^2)^{−1/2} (1−x2)−1/2. Ans: T n ( x ) = cos ⁡ ( n arcc

第三章 少量(无)标记增强现实——Chapter 3:Marker-less Augmented Reality

注释: 1、翻译书名:Mastering OpenCV with Practical Computer Vision Projects 2、翻译章节:Chapter 3:Marker-less Augmented Reality 3、电子书下载,源代码下载,请参考:http://blog.csdn.net/raby_gyl/article/details/11617875 4、本章程序

Focus On 3D Terrain Programming·Chapter 5(1)

写在前面的话 原著:《Focus On 3D Terrain Programming》 章节:Chapter5 Geomipmapping for the CLOD Impaired 说明:图形渣、英语渣,学习的同时记录下来的(主要是不翻译就读不下去TT),希望能和大家相互交流学习,翻译有误的地方欢迎指出^^ 正文开始↓ 哦吼!你将要学习地形编程中的核心内容,里面包含了相当复杂的算法。实

MATH36022 Numerical Analysis 2 Approximation of Functions – Week 2 Exercises

Attempt these exercises in advance of the tutorial in Week 3 Find the best L ∞ L_\infin L∞​ approximation to f ( x ) = x n + 1 + ∑ k = 0 n a k x k f (x) = x^{n+1} + \sum_{k=0}^na_kx^k f(x)=xn+1+∑k=