我正在阅读一本关于C的介绍书,我看到了下面的一段话:
但下列程式码会以预期的输出进行编译:
#include <stdio.h>
int main()
{
for(int i = 0; i<=10; i++)
{
int val = i + 1;
int x = val * val;
printf("%d\n", x);
int y = x;
}
return 0;
}
我使用https://www.onlinegdb.com/,在上面的代码中,我在第一个可执行语句之后声明了许多变量。这对我来说与书中的章节所讲述的不匹配。
我是不是误解了这本书的意思?
3条答案
按热度按时间2ic8powd1#
在C 1990 6.6.2中,声明只能出现在文件范围(函数定义之外)或复合语句的开头。C 1990 6.6.2中复合语句的语法是:
复合语句 *
也就是说,复合语句是
{
,后面跟着零个或多个声明,然后是零个或多个语句,最后是}
,所以声明必须在前面。在C 1999 6.8.2中,此更改为:
复合语句 *
block-item-list* 是 block-item 的列表,其中的每一个都可以是 * 声明 * 或 * 语句 *,因此声明和语句可以自由混合。
在您的示例中,声明
int val = i + 1;
和int x = val * val;
没有出现在其复合语句中的可执行语句之后。复合语句以{
开头,{
紧接在int val = i + 1;
之前,因此该声明位于复合语句的开头。另一个变化是
for
语法在C 1990 6.6.5中有所改变:for
(
* 表达式 * 选择;
* 表达式 * 选择;
* 表达式 * 选择)
* 语句 *C 1999 6.8.5中的两种形式的选择:
for
(
* 表达式 * 选择;
* 表达式 * 选择;
* 表达式 * 选择)
* 语句 *for
(
* 声明**表达式 * 选择;
* 表达式 * 选择)
* 语句 *(Note* 声明 * 包括终止
;
。)这就解释了为什么
for(int i = 0; i<=10; i++)
中可以有int i = 0
。cnjp1d6j2#
这本书指的是 * 30多年前 * 的原始C规范,称为“ANSI C”或“C89”或“C90”。如果我们在C89模式下运行C编译器,
-std=c89
,我们会从您的代码中得到警告...C99,1999年对C语言的更新,使这一点变得不真实。用
-std=c99
运行你的代码不会给出任何警告。C99对语言做了这一点和其他有影响的修改,比如//
注解。还有C11和最新的稳定版本的C是C17,但编译器对两者的支持是不稳定的。
为什么这本书指的是这样一个旧版本的语言?C语言自1978年就已经存在,有很多旧代码和旧编译器。C编译器在完全采用新标准方面非常缓慢,这使得作者相当保守。一个很大的绊脚石是Microsoft Visual C++直到2013年才实现C99!因此,ANSI C在很长一段时间内都是最低公分母。
最近几年,C编译器在标准遵从性方面做得更好了,所以您可以依赖C99(它已经成熟到可以喝酒了)作为您的基线。
gj3fmq9x3#
示例中的所有变量在使用之前都已声明。
这些声明包括:
注意所有声明都发生在相应块中的第一个函数调用之前。换句话说:i、瓦尔和x都在printf之前声明。
正如评论中所说:一些旧书可能会参考C的旧版本。例如,for循环中的变量声明是C99附带的。从C99开始,你也可以在块的中间声明变量。所以你可以在printf之后声明一些
int y;
,你的代码仍然可以编译。