洛谷 @ 2022-08-09 10:53:54
此贴禁水反馈前请先查看勘误表。
目前基础篇相关问题可直接在本贴留言。反馈前请先查看勘误表。
https://www.luogu.com.cn/blog/kkksc03/book1-corrigendum
https://www.luogu.com.cn/discuss/946364
此贴禁水
by CleanIce @ 2023-12-31 17:25:08
@kkksc03
一个不容易发现的小问题(但是却严重违反了 C++ 的语法规则):
4.1 节的:
这里使用
for
循环来进行重复的操作。for
循环语句的一般形式如下:for (循环变量初始值; 循环条件; 每轮循环结束操作) { 循环体 }
一般形式应改为:
for (循环初始化语句 循环条件; 每轮循环结束操作)
循环体
注意这里只有一个分号!因为语句自己包括分号!这里没有花括号!循环体是语句,而花括号表示复合语句,复合语句属于一种语句!
详细解释看:(摘自 Stephen Prata 的《C++ Primer Plus》第四版)
这一段文字前面讲述了表达式和语句的区别与联系,后一段阐述 C++ 标准的 for
语句句法。
表达式和语句
…………
记住:C++ 表达式时值或值与操作符的组合,每个 C++ 表达式都有值。
为判定表达式
x = 100
,C++ 必须将 100 赋给x
。当判定表达式的值这种操作改变了内存中数据的值时,我们说表达式有副作用(side effect)。因此,判定赋值表达式会带来这样的副作用,即修改被赋值者的值。有可能把赋值看作预期的效果,但从 C++ 的构造方式这个角度来看,判定表达式才是主要作用。并不是所有的表达式都有副作用。例如,判定x + 15
将计算出一个新的值,但不会修改x
的值。不过,判定++x + 15
就有副作用,因为它将x
加 1。从表达式到语句的转变是很小的异步,只需要加一个分号就可以完成。因此:
age = 100
是表达式,而:
age = 100;
则是语句。只要加上分号,所有的表达式都可以成为语句,但不一定有编程意义。例如,如果
rodents
是一个变量,则:rodents + 6; // valid, but useless, statement
就是有效的 C++ 语句。编译器允许这样的语句,但它没有完成任何有用的工作。程序仅仅是计算和,而没用使用得到的结果,然后便进入下一条语句(智能的编译器甚至可能跳过这条语句。)
非表达式和语句
有些概念对于理解 C++ 至关重要,如了解
for
循环的结构。不过句法中也有一些相对次要的内容,让认为自己理解语言得突然觉得不知所措。下面来看看这样的内容。对任何表达式加上分号都可以成为语句,但是这句话反过来说就不对了。也就是说,从语句中删除分号,并不一定能将它转换为表达式。就我们目前使用的语句而言,返回语句、声明语句和
for
语句都不满足语句 = 表达式 + 分号
这种模式。例如,虽然:int toad;
是语句,但
int toad
并不是表达式,因为它没有值。因此,下面的代码是非法的:eggs = int toad * 1000; // invalid, not an expression cin >> int toad; // can't combine declaration with cin
同样,不能把
for
循环赋给变量:int fx = for (int i = 0; i < 4; i++) cout >> i; // not possible
其中的
for
循环不是表达式,因此没有值,也不能给它赋值。修改规则
C++ 在 C 循环的基础上添加了一些特性,要求对
for
循环句法做一些微秒的调整。这是原来的句法:
for (expression; expression; expression) statement
具体地说,
for
结构的控制部分由 3 个表达式组成,它们由分号分隔。不过,C++ 循环允许这样做:for (int i = 0; i < 5; i++)
也就是说,可以在
for
循环的初始化部分中声明变量。这很方便,但并不使用于原来的句法,因为声明不是表达式。这种非法行为最初是通过定义一种新的表达式——声明语句表达式(declaration-statement expression)——来合法化的,声明语句表达式不带分号声明,只能出现在for
语句中。不过,这种调整以及被取消了,代之以将for
语句的句法修改成下面这样:for (for-init-statement condition; expression) statemen
乍一看很奇怪,因为这里只有一个分号(而不是两个分号)。但这是允许的,因为
for-init-statement
被视为一条语句,而语句有自己的分号。对于for-init-statement
来说,它既可以是表达式语句,也可以是声明。这种句法规则用语句替换了后面跟分号的表达式,语句本身有自己的分号。总之,C++ 程序员希望能够在for
循环初始化部分中声明和初始化变量,他们会做 C++ 句法需要和英语允许的工作。
by lsb0928 @ 2024-01-19 10:49:39
@洛谷 @kkksc03
买了深入浅出的书。 你们的课后习题与实验 答案在哪里 ? 书上没有啊 。
by littlesnake @ 2024-01-29 23:10:37
深基的第231页二叉搜索树模板题代码并不能通过P5076,会70分TLE。
by Asaka_Rum @ 2024-01-30 01:06:40
基础篇22年5月第五次印刷中,P231的程序是不是有点儿问题,提交了很多遍,检查了七八编了,都是70分,是数据加强了还是程序的问题呢?关于二叉树的
@kkksc03
by Asaka_Rum @ 2024-01-30 10:07:36
@xsy2013 我也是,卡了我一个星期,我一直以为我写的有问题
by littlesnake @ 2024-01-30 10:12:00
@Asaka_Rum 有没有一种可能,需要用平衡树。
by GZXUEXUE @ 2024-01-31 15:39:56
@kkksc03
《深基》第101页例7-2(质数筛)我貌似想出了一种稍快的解法: 在 _is_prime 函数中,可以在判断完 0 与 1_ 这两个特殊情况后,再判断是不是2的倍数(2除外):
else if (x % 2 == 0 && x != 2) return 0;
在做完以上步骤之后,我们就可以愉快的加快循环:
for (int i = 3;i <= x / i;i += 2) // 这里的i+=2得益于之前的“判断2的倍数(2除外)”这一步。并且,i <= x / i这一小段可以避免i * i的溢出问题
by LMR_Minecraft @ 2024-02-07 18:04:29
@kkksc03 深入浅出第3页随后几句有一句没有主语 (就那句阅读编译报错信息的)
by JunBzG @ 2024-02-10 20:50:09
《深基》2022年11月第6次印刷:P39第一行“Hello,my master!”,“my”前少了一个空格(跟例3-6的代码第7行对不上)。
by xk2013 @ 2024-02-21 10:51:29
《深入浅出程序设计竞赛(基础篇)》
2020 年第 7 次印刷
P178 页:
……也可以认为其返回值减去数组名 a(其实等于 a[0])……
应改为:
……也可以认为其返回值减去数组名 a(其实等于 a[0] 的地址)……