当我不能在C:
中编译时,我很困惑int main()
{
for (int i = 0; i < 4; ++i)
int a = 5; // A dependent statement may not be declaration
return 0;
}
我习惯使用C ++编译。我只是愣了一会儿,直到我记得这里的答案是关于如何在C和C ++中考虑不同的事情&#34;陈述&#34;。这是关于switch语句的。 A&#34;陈述&#34;在for循环括号之后必须同时存在于C和C ++中。这可以在添加分号或创建{}波浪形支架块的情况下完成。
在C ++&#34; int a = 7;&#34;被视为声明,定义和初始化。在C中我相信它也被认为是所有这些,但是在C中它不被视为&#34;陈述&#34;。
有人可以准确地澄清为什么在C中这不是一个声明而在C ++中它是什么?这让我对一个陈述的概念感到困惑,因为一种语言说它是,而另一种语言说它不是,所以我有点困惑。
答案 0 :(得分:16)
C ++允许&#34;子语句&#34;迭代语句的含义是一个复合语句([stmt.iter])
如果iteration-statement中的子语句是单个语句而不是复合语句,那就好像 它被重写为包含原始语句的复合语句。例如:
while (--x >= 0)
int i;
可以等效地重写为
while (--x >= 0) {
int i;
}
C标准没有这种语言。
此外,语句的定义在C ++中已更改为包含声明语句,因此即使上述更改尚未生成,它仍将是合法的。
添加大括号使其工作的原因是因为您的声明现在变为复合语句,其中可以包含声明。
您可以在没有大括号的循环体中拥有标识符,因此您可以这样做:
int a = 5;
for (int i = 0; i < 4; ++i)
a;
答案 1 :(得分:11)
在C ++中,语句是(C ++ 17标准草案)
get_updates()
请注意,C ++中有声明语句,它们是声明,而且是语句。类似地,简单声明是init语句。但并非所有声明都是陈述。声明语法包含不在语句列表中的内容:
excerpt from [gram.stmt]
statement:
labeled-statement
attribute-specifier-seqopt expression-statement
attribute-specifier-seqopt compound-statement
attribute-specifier-seqopt selection-statement
attribute-specifier-seqopt iteration-statement
attribute-specifier-seqopt jump-statement
declaration-statement
attribute-specifier-seqopt try-block
init-statement:
expression-statement
simple-declaration
declaration-statement:
block-declaration
...
声明语法列表会持续几页。
在C中,陈述是(C11标准草案)
excerpt from [gram.dcl]
declaration:
block-declaration
nodeclspec-function-declaration
function-definition
template-declaration
deduction-guide
explicit-instantiation
explicit-specialization
linkage-specification
namespace-definition
empty-declaration
attribute-declaration
block-declaration:
simple-declaration
asm-definition
namespace-alias-definition
using-declaration
using-directive
static_assert-declaration
alias-declaration
opaque-enum-declaration
simple-declaration:
decl-specifier-seq init-declarator-listopt ;
attribute-specifier-seq decl-specifier-seq init-declarator-list ;
attribute-specifier-seqopt decl-specifier-seq ref-qualifieropt [ identifier-list ] initializer ;
...
请注意,C语句中没有声明声明。
因此,语句的含义在语言上明显不同。 C ++中的语句似乎比C中的语句具有更广泛的含义。
答案 2 :(得分:7)
根据cppreference,C++包含以下类型的statements
:
虽然C会考虑以下类型的statements
:
正如您所注意到的,声明在C中不被视为statements
,而在C ++中则不是这种情况。
对于C ++:
int main()
{ // start of a compound statement
int n = 1; // declaration statement
n = n + 1; // expression statement
std::cout << "n = " << n << '\n'; // expression statement
return 0; // return statement
} // end of compound statement
对于C:
int main(void)
{ // start of a compound statement
int n = 1; // declaration (not a statement)
n = n+1; // expression statement
printf("n = %d\n", n); // expression statement
return 0; // return statement
} // end of compound statement, end of function body
答案 3 :(得分:2)
在C ++声明中,语句是在C声明中不是语句。所以根据这个for循环中的C语法
for (int i = 0; i < 4; ++i)
int a = 5;
int a = 5;必须是循环的子语句。不过这是一个宣言。
您可以使用复合语句(例如
)使代码在C中编译for (int i = 0; i < 4; ++i)
{
int a = 5;
}
虽然编译器可以发出一条诊断消息,说明没有使用变量a
。
C声明中的另一个结果不是声明。您不得在C语句中放置标签。例如此程序
#include <stdio.h>
int main(void)
{
int n = 2;
L1:
int x = n;
printf( "x == %d\n", x );
if ( --n ) goto L1;
return 0;
}
虽然编译为C ++程序,但不会在C中编译。但是,如果在标签之后放置一个空语句,那么程序就会编译。
#include <stdio.h>
int main(void)
{
int n = 2;
L1:;
int x = n;
printf( "x == %d\n", x );
if ( --n ) goto L1;
return 0;
}