1.1 节练习
练习 1.1
在Linux终端里面:
首先利用vim编辑器写一个test.cpp文件
内容如下:
通过g++ -o test test.cpp
生成了一个可执行文件test
。
在UNIX和Windows系统中,执行完一个程序后,都可以通过echo
命令获得其返回值。
在UNIX系统中(Linux其实是类UNIX系统,也适用),通过如下命令获得状态:
echo $?
发现返回值为1,这肯定不正常。
然后这样做了:
明确指定文件位置,用一个“.”后跟一个斜线来指出可执行文件位于当前目录中。
发现返回0,这表明程序没有遇到任何错误,并且成功执行完毕。
补充:
在Windows系统中,执行完一个程序后,通过echo %errorlevel%
命令获得其返回值。
补充(自己按照书上实验了一下):
如果省略了-o test
,在UNIX系统中编译器会生成一个名为a.out
的可执行文件。
真的自动生成了一个可执行文件a.out
。
然后运行这个文件,发现返回值为0,这表明程序没有遇到任何错误,并且成功执行完毕。
练习 1.2
改写test.cpp
文件
居然返回255
换了a.out
试了下,发现也是返回255,然后问了gpt
附上gpt的回答:
在Linux系统中,程序的返回值实际上是通过进程的退出状态码来传递的。C++程序的return语句返回的值会被转换成一个8位无符号整数,并且在进程退出时,这个返回值会被传递给操作系统。
具体来说,Linux中的进程退出状态码由两部分组成:
- 退出状态(exit status):这是程序的返回值,范围是0-255。
- 信号状态(signal status):如果程序是由于某个信号而终止的,信号会影响退出状态。
当你的程序返回-1时,它会被转换为255,这是因为-1在转换为无符号整数时的值是255。
然后在Windows系统下试了一下:
test.cpp
内容如下:
在visual studio自带的编辑器运行,发现返回值为-1。
1.2 节练习
练习 1.3
通过使用作用域运算符(::)来指出我们想使用定义在命名空间std
中的名字cout
。
endl
是一个被称为操纵符(manipulator)的特殊值。写入endl
的效果是结束当前行,并将与设备关联的缓冲区(buffer)中的内容刷到设备中。
练习 1.4
练习 1.5
练习 1.6
不合法
改成:
std::cout << "The sum of " << v1
<< " and " << v2
<< " is " << v1 + v2 << std::endl;
或者改成:
std::cout << "The sum of " << v1;
std::cout << " and " << v2;
std::cout << " is " << v1 + v2 << std::endl;
补充:
在Linux环境下也试了下:
demo.cpp
内容如下:
1.3 节练习
练习 1.7
练习 1.8
补充:
发现第一个warning警告: [Warning] command line option '-std=c99' is valid for C/ObjC but not for C++
如何去除?
原先这样:
改成这样:
即指定-std=c++0x
参数来打开对C++11的支持,或者使用-std=c++11
参数来打开对C++11的支持。
chatgpt是这样介绍的:
C++0x是C++11标准的一个早期名称。在C++标准化过程中,C++11最初被称为C++0x,因为它的最终版本在2011年之前尚未发布。这个标准引入了许多新特性,如自动类型推导、范围for循环、智能指针等,极大增强了C++的功能和易用性。
C++11是C++标准的正式名称,包含了C++0x的所有特性。C++0x是一个过渡名称,表示当时尚未正式发布的标准。C++11引入了许多新特性,如:
自动类型推导(auto)
范围for循环
智能指针(std::unique_ptr和std::shared_ptr)
线程支持
lambda表达式
因此,C++0x和C++11指的是同一个标准,但C++11是其正式名称。
1.4.1 节练习
练习 1.9
#include <iostream>
int main()
{
int sum = 0;
int i = 50;
while (i <= 100)
{
sum += i;
i ++;
}
std::cout << sum << std::endl;
return 0;
}
练习 1.10
#include <iostream>
int main()
{
int i = 11;
while (i)
{
i --;
std::cout << i << ' ';
}
std::cout << std::endl;
return 0;
}
也可:
#include <iostream>
int main()
{
int i = 10;
while (i >= 0) {
std::cout << i << " ";
i--;
}
std::cout << std::endl;
return 0;
}
练习 1.11
#include <iostream>
int main()
{
std::cout << "请输入两个数";
std::cout << std::endl;
int v1, v2;
std::cin >> v1 >> v2;
if (v1 > v2) // 由大至小打印
while (v1 >= v2) {
std::cout << v1 << " ";
v1--;
}
else // 由小至大打印
while (v1 <= v2) {
std::cout << v1 << " ";
v1++;
}
std::cout << std::endl;
return 0;
}
记得要先判断输入的两个数之间的大小,避免循环出不来(死循环)的情况。
也看到了一种值得学习的写法:
#include <iostream>
void print_range(int lo, int hi)
{
if (lo > hi)
{
print_range(hi, lo);
return;
}
while (lo <= hi)
{
std::cout << lo << std::endl;
++lo;
}
}
int main()
{
int low, high;
std::cout << "please input two numbers : " << std::endl;
std::cin >> low >> high;
print_range(low, high);
return 0;
}
虽然对于这个代码,当输入的第一个数大于输入的第二个数时,不能实现由第一个输入的数从大到小打印至输入的第二个数(即逆序输出),但是这个代码结构还是值得学习的。
1.4.2 节练习
练习 1.12
此循环将 −100 到 100 之间(包含 −100 和 100)的整数相加(即从 -100 加到 100 ),sum 的终值是 0。
练习 1.13
比较简单,不赘叙了
练习 1.14
蛮有意思的,可以看下
练习 1.15
不赘叙
1.4.3 节练习
练习 1.16
#include <iostream>
int main()
{
int sum = 0, value = 0;
while (std::cin >> value)
{
sum += value;
}
std::cout << sum << std::endl;
return 0;
}
补充:
-
当我们使用一个
istream对象
作为条件时,其效果是检测流的状态。如果流是有效的,即流未遇到错误,那么检测成功。
当遇到文件结束符(end-ofFfile),或遇到一个无效输入时,
istream对象
的状态会变为无效。处于无效状态的istream对象会使条件变为假。 -
文件结束符
当从键盘向程序输入数据时,对于如何指出文件结束,不同操作系统有不同的约定。
在Windows系统中,输入文件结束符的方法是敲Ctrl+Z(按住Ctrl键的同时按Z键), 然后按Enter或Retum键。
在UNIX系统中,包括MacOSX系统中,文件结束符输入是用Ctrl+D。
1.4.4 节练习
1.5.1 节练习
练习 1.20
#include <iostream>
#include "Sales_item.h"
int main()
{
Sales_item book;
std::cout << "请输入销售记录:"
<< std::endl;
while (std::cin >> book) {
std::cout << "ISBN、售出本数、销售额和平均售价为 "
<< book << std::endl;
}
return 0;
}
练习 1.21
#include <iostream>
#include "Sales_item.h"
int main()
{
Sales_item trans1, trans2;
std::cout << "请输入两条 ISBN 相同的销售记录:"
<< std::endl;
std::cin >> trans1 >> trans2;
if (compareIsbn(trans1, trans2))
std::cout << "汇总信息:ISBN、售出本数、销售额和平均售价为 "
<< trans1 + trans2 << std::endl;
else
std::cout << "两条销售记录的 ISBN 不同" << std::endl;
return 0;
}
其中compareIsbn
函数是在Sales_item.h
文件中定义的,如下:
练习 1.22
#include <iostream>
#include "Sales_item.h"
int main()
{
Sales_item total, trans;
std::cout << "请输入几条 ISBN 相同的销售记录:"
<< std::endl;
if (std::cin >> total) {
while (std::cin >> trans)
if (compareIsbn(total, trans)) // ISBN 相同
total = total + trans;
else { // ISBN 不同
std::cout << "ISBN 不同" << std::endl;
return -1;
}
std::cout << "汇总信息:ISBN、售出本数、销售额和平均售价为 "
<< total << std::endl;
}
else {
std::cout << "没有数据" << std::endl;
return -1;
}
return 0;
}
这个程序和1.4.4 节练习中的程序巧妙处有点像,但是又不完全一样
看了一位大佬写的:
#include <iostream>
#include "Sales_item.h"
int main()
{
Sales_item currItem, valItem;
if (std::cin >> currItem)
{
int cnt = 1;
while (std::cin >> valItem)
{
if (valItem.isbn() == currItem.isbn())
{
++cnt;
}
else
{
std::cout << currItem << " occurs " << cnt << " times " << std::endl;
currItem = valItem;
cnt = 1;
}
}
std::cout << currItem << " occurs " << cnt << " times " << std::endl;
}
return 0;
}
这个程序和1.4.4 节练习中的程序就基本一样了
练习 1.23
#include <iostream>
#include <cstdio>
#include "Sales_item.h"
int main()
{
FILE* file = nullptr;
errno_t err = freopen_s(&file, "input.txt", "r", stdin);
if (err != 0) {
std::cerr << "Failed to redirect input." << std::endl;
return 1;
}
Sales_item trans1, trans2;
int num = 1;
std::cout << "若干销售记录在input.txt里,已文件重定向到输入:" << std::endl;
if (std::cin >> trans1)
{
while (std::cin >> trans2)
if (compareIsbn(trans1, trans2)) // ISBN相同
num++;
else
{
//ISBN不同
std::cout << trans1.isbn() << " 共有 "
<< num << " 条销售记录" << std::endl;
trans1 = trans2;
num = 1;
}
std::cout << trans1.isbn() << " 共有 "
<< num << " 条销售记录" << std::endl;
}
else
{
std::cout << "没有数据" << std::endl;
return -1;
}
return 0;
}
输出如下:
补充
这里我用了文件重定向(因为不想重复输入销售记录)
详细的请看这篇博客:对C++程序使用输入输出重定向
练习 1.24
在练习 1.23演示过了
练习 1.25
前面差不多了
标签:std,cout,int,练习,C++,第一章,include From: https://www.cnblogs.com/hisun9/p/18530916