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