为什么一个衬垫功能需要支架?

时间:2015-08-05 17:14:05

标签: c language-design

我们可以做到这一点

if(condition)
    doThis();

和这个

while(condition)
    doThat();

但不是这个

int giveMeFive()
    return 5; // Error: expected a '{'

为什么不呢?

我知道语言语法在函数定义上需要{}。我问的是条件语句(不需要括号)和函数定义(确实如此)之间差异的基本原理。

3 个答案:

答案 0 :(得分:12)

原因似乎主要是历史性的。

在1989 ANSI C标准之前,C没有原型。类型int的参数可以隐式定义;必须在开始int之前明确定义除{以外的其他类型的参数。

例如,在现代C中我们可以写:

double sum(double x, double y) {
    return x + y;
}

在ANSI(K& R)C之前我们必须写:

double sum(x, y)
double x;
double y;
{
    return x + y;
}

函数体可能以声明局部变量开头:

double sum(x, y)
double x;
double y;
{
    double z;
    /* ... */
}

需要开头{将参数定义与函数正文分开,并且需要结束}以匹配开头{

(在现代C中,这种语法仍然是允许的,但是过时了;在C ++中不允许这样做。)

当原型被添加到语言中时,没有特别的理由允许在函数定义中省略{}

这个简单的答案就是语言语法所需要的。 函数定义的语法是:

  

declaration-speci firs声明者声明列表 opt 复合声明

其中复合语句{组成,后跟0或更多声明和语句,后跟}。这是 only 语法生成,需要复合语句;还有很多其他只需要语句

有趣的是,在C的前身语言B(documented here)中,函数定义的语法是:

name ( arguments ) statement

声明通常是复合语句(由{}分隔的块),但不是必须的。 B不需要甚至不允许参数和变量指定其类型,因此不需要使用特定语法将带括号的参数列表与函数体分开。在最早的C引用中,我可以找到(this one, from 1974),函数定义的语法已被更改为需要复合语句,可能是为了适应参数声明的添加。

答案 1 :(得分:10)

如果允许,函数声明之间没有区别:

void a()
  ;

和函数的函数定义:

RDFDataMgr.write(System.out, dataset, Lang.NQUADS)

肯定会增加更多问题而非获益。

答案 2 :(得分:-2)

我认为问题在于很难区分这种结构

int giveMeFive()
return 5;

和这个结构

int giveMeFive() //;
                 ^^^
return 5;

这就是程序员是否打错了。

目前编译器发出错误。但是,如果允许这样的函数定义该怎么办?这将使程序更加清晰。

实际上它可以像简化的内联函数一样使用

T function( parameter-list ) return expression;

但是在函数标题及其正文之间放置一个分号

T function( parameter-list ) ; return expression;

更改语义并使代码不清楚。

与while语句的区别在于,像while这样的while语句之后的分号

while( condition );

不会改变构造的定义。无论如何,它都是while语句。

然而,相对于功能定义,情况有所不同。