学习《c++_primer》之第一章

借鉴github上一位大佬的

1.1 节练习

练习 1.1

在Linux终端里面:

首先利用vim编辑器写一个test.cpp文件

内容如下:

img

通过g++ -o test test.cpp生成了一个可执行文件test

img

img

在UNIX和Windows系统中,执行完一个程序后,都可以通过echo命令获得其返回值。

在UNIX系统中(Linux其实是类UNIX系统,也适用),通过如下命令获得状态:

echo $?

img

发现返回值为1,这肯定不正常。

然后这样做了:

img

明确指定文件位置,用一个“.”后跟一个斜线来指出可执行文件位于当前目录中。

发现返回0,这表明程序没有遇到任何错误,并且成功执行完毕。

补充:

在Windows系统中,执行完一个程序后,通过echo %errorlevel%命令获得其返回值。

补充(自己按照书上实验了一下):

如果省略了-o test,在UNIX系统中编译器会生成一个名为a.out的可执行文件。

img

真的自动生成了一个可执行文件a.out

img

然后运行这个文件,发现返回值为0,这表明程序没有遇到任何错误,并且成功执行完毕。

img

练习 1.2

改写test.cpp文件

img

img

居然返回255

换了a.out试了下,发现也是返回255,然后问了gpt

附上gpt的回答:

在Linux系统中,程序的返回值实际上是通过进程的退出状态码来传递的。C++程序的return语句返回的值会被转换成一个8位无符号整数,并且在进程退出时,这个返回值会被传递给操作系统。

具体来说,Linux中的进程退出状态码由两部分组成:

- 退出状态(exit status):这是程序的返回值,范围是0-255。

- 信号状态(signal status):如果程序是由于某个信号而终止的,信号会影响退出状态。

当你的程序返回-1时,它会被转换为255,这是因为-1在转换为无符号整数时的值是255

然后在Windows系统下试了一下:

test.cpp内容如下:

img

在visual studio自带的编辑器运行,发现返回值为-1。

img

1.2 节练习

练习 1.3

img

通过使用作用域运算符(::)来指出我们想使用定义在命名空间std中的名字cout

endl是一个被称为操纵符(manipulator)的特殊值。写入endl的效果是结束当前行,并将与设备关联的缓冲区(buffer)中的内容刷到设备中。

练习 1.4

img

练习 1.5

img

练习 1.6

不合法

img

改成:

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内容如下:

img

img

1.3 节练习

练习 1.7

img

练习 1.8

img

补充:

发现第一个warning警告: [Warning] command line option '-std=c99' is valid for C/ObjC but not for C++

如何去除?

原先这样:
img

改成这样:

img

即指定-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;	
}

img

练习 1.10

#include <iostream>

int main()
{
	int i = 11;
	while (i)
	{
		i --;
		std::cout << i << ' ';
	}
	
	std::cout << std::endl;
	return 0;
}

img

也可:

#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; 
}

img

记得要先判断输入的两个数之间的大小,避免循环出不来(死循环)的情况。

也看到了一种值得学习的写法:

#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;
}

img

虽然对于这个代码,当输入的第一个数大于输入的第二个数时,不能实现由第一个输入的数从大到小打印至输入的第二个数(即逆序输出),但是这个代码结构还是值得学习的。

1.4.2 节练习

练习 1.12

此循环将 −100 到 100 之间(包含 −100 和 100)的整数相加(即从 -100 加到 100 ),sum 的终值是 0。

练习 1.13

比较简单,不赘叙了

练习 1.14

在StackOverflow有类似的问题

蛮有意思的,可以看下

练习 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;
}

img

img

补充:

  • 当我们使用一个istream对象作为条件时,其效果是检测流的状态。

    如果流是有效的,即流未遇到错误,那么检测成功。

    当遇到文件结束符(end-ofFfile),或遇到一个无效输入时,istream对象的状态会变为无效。处于无效状态的istream对象会使条件变为假。

  • 文件结束符

    当从键盘向程序输入数据时,对于如何指出文件结束,不同操作系统有不同的约定。

    在Windows系统中,输入文件结束符的方法是敲Ctrl+Z(按住Ctrl键的同时按Z键), 然后按Enter或Retum键。

    在UNIX系统中,包括MacOSX系统中,文件结束符输入是用Ctrl+D。

1.4.4 节练习

img

img

img

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;
}

img

练习 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;
}

img

其中compareIsbn函数是在Sales_item.h文件中定义的,如下:

img

练习 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;
}

img

img

这个程序和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;
}

输出如下:

img

补充

这里我用了文件重定向(因为不想重复输入销售记录)

详细的请看这篇博客:对C++程序使用输入输出重定向

练习 1.24

在练习 1.23演示过了

练习 1.25

前面差不多了

posted @   hisun9  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示