"一个让诸位喷血而死的发现!!"续集 :)

yjh1982 2003-11-13 11:37:29
前传:)http://expert.csdn.net/Expert/topic/2204/2204860.xml?temp=4.139346E-02

由于只能回复三十次,只好结帖.不过既然还有人关心,我就再发一贴:

Class struct是 非执行体,指的是
Class a
{
int I;
int j;//永远不能debug到这,因为这不是语句
};
即那是”宣告”,不是”定义”
int foo();//宣告
int foo()
{

}//定义
...........................................................................
class a
{
int I;
;;;;
int j
};//的确不影响执行效率,但影响编译效率

..............................................................................
yaoxinyan() 的论点:
首先由C语言讲起,C的语法里面,declaration和statement是不同的,在函数体的外部只能有declaration而不能有statement:

int i; //declaration. 合法的C代码
int main(){}

; //statement(null statement). 不合法的C代码
int main(){}

因此,单独一个“;”(即null statement)不能写在函数体的外面。这个大家理解起来应该没问题。
好,论到C++了。C++在刚出道的时候就支持一个新特性,内部变量可以在block的任何地方出现,这个特性方便程序员在真正用到的时候才声明内部变量:

int main()
{
int i=0;
f();
int g=g(); //合法的C++代码
++i;
double d; //合法的C++代码
...
}

相信大家对这个并不陌生,复合语句的loop部分很自然也是block的序列,于是在C++还可以这样:

for(int i=0; i<100; ++i){ ... }

上面for语句的iterator(即i)由于在block里面,因此可以到进入for的loop部分才声明i,C没有这项特性,C程序员必须这样写:

int i;
for(i=0; i<100; ++i){ ... }

好,一个问题现在就摆在C++的设计者面前:
这样的代码大量存在:

int i=0;
for( ; i<100; ++i){ ... }

看到那个null statement吗?在C里面,这种写法是合法的,C++没理由不支持。

如何实现declaration的语法呢?一方面,如果像C语言那样把declaration和statement截然分开,显然不行,因为这样就无法实现“随处声明内部变量的特性”;另一方面又要顾及到不能到处写statement,明显错的应该仍然是错的:

int i=0;
++i; //这明显是错的!
int main(){}

最后,C++的设计者基于各种考虑,采取了一种折中而又不失效率的做法:
把declaration处理成statement的一种,并且允许出现declaration的地方也就允许出现null statement,
这样就解决了问题:

1)可以“随地大小便”啦
int main()
{
int i;
++i;
int j; //合法的C++,因为declaration是statement,
//既然这里可以写statement也就意味着写declaration是合法的
--j;
}

2)兼容好又效率高
for (int i=0;i<100;++i){ ... }

int i=0;
for ( ; i<100; ++i){ ... }
要同样被接受。OK,本来null statement可以出现的地方就允许declaration出现(记住,declaration也是statement),现在写declaration的地方又要求可以接受null statement,既然这样,索性把null statement与declaration等价!于是,便出现了令yjh1982 (血精灵)吐血的一幕:

; //合法的C++代码!
int main(){}

class A
{ int i; ; ;;;}; //合法的C++代码!

3)危害性为零
declaration与null statement等价是出于提高效率的考虑(恰恰与yjh1982 (血精灵)的抱怨相反),注意,只有null statement才享有这个特权!那些明显错的还是错的:

int i=9;
++i; //小子,你又不是null statement,你站在这干嘛?!
//(你忘记了,我是那个印度阿三啊……)
int main(){}

到此,水落石出,不要义愤填膺地指责C++在declaration的地盘接受那些“无用的家伙”——null statement,事实恰恰是C++为了提升编译效率而又考虑到无损大局而接纳了null statement。

最后,补充知识:ISO C99已经允许C程序员在block里面随处声明内部变量:

int main()
{
int i=0;
++i;
int j=i; //合法的C++、C99代码。
--j;
}
…………………………………………..................................................................................................................
告诉的是”int I;”可当成语句,但我认为class 中的”int I”不是语句,是”宣告”.

现在我想通一些了:
class a
{
static const int i=0;
int j;
};
是为了使编译器解析不至于太复杂而作的妥协:(


........................................
另外我在那公司时脑子也不灵光:),原由请见:
http://expert.csdn.net/Expert/topic/2331/2331773.xml?temp=.9221155

...全文
44 39 打赏 收藏 转发到动态 举报
写回复
用AI写文章
39 条回复
切换为时间正序
请发表友善的回复…
发表回复
yjh1982 2003-12-01
  • 打赏
  • 举报
回复
没有驳斥ross33123的吧?
那"喷血"系列要圆满结束咯......总算解开心结了:)
yjh1982 2003-11-27
  • 打赏
  • 举报
回复
多谢ross33123() .
我也一直怀疑标准怎么会支持这种无意义的东西;
另外VC编译*.c时也不容许出现空分号. 看来是C++的某些特性使得容忍了
这种写法
catowl 2003-11-27
  • 打赏
  • 举报
回复
UP
收藏
thuers 2003-11-27
  • 打赏
  • 举报
回复
我也收藏。
oo 2003-11-27
  • 打赏
  • 举报
回复
收藏
ross33123 2003-11-26
  • 打赏
  • 举报
回复
哈哈,我好像找到答案了。

严格来说,这种写法是 ISO C++ 标准不允许的。

C++ 对类成员的语法定义如下(下划线加opt 表示标准原文中是opt下标,即可选)

member-specification:
member-declaration member-specification_opt
access-specifier : member-specification_opt

member-declaration:
decl-specifier-seq_opt member-declarator-list_opt ;
function-definition ;_opt
others

从这里看似乎多余的分号是允许的

但是这一段 syntax specification后面附的说明里有一段话:

Except when used to declare friends, or to introduce the name of a member of a base class into a derived class, member-declarations declare members of the class, and each such member-declaration shall declare at least one member name of the class.

这样看,多余的分号就是不符合标准的了。

我没看明白的是:
为什么member-declaration定义的第一选择
decl-specifier-seq_opt member-declarator-list_opt ;
两个都是可选的呢?

zhu1981 2003-11-26
  • 打赏
  • 举报
回复
真的吐血拉
bestfyj 2003-11-26
  • 打赏
  • 举报
回复
享受ing 思考的乐趣
wl820406 2003-11-26
  • 打赏
  • 举报
回复
解我心中困惑!
ross33123 2003-11-26
  • 打赏
  • 举报
回复
确实有点意思。

为此贴我专门装了个 BC 3.1,结果是不允许这种语法。

希望有高人继续解惑。
lemon520 2003-11-26
  • 打赏
  • 举报
回复
我还没有喷血!
:)
playboyxp 2003-11-26
  • 打赏
  • 举报
回复
呵呵,有意思
BenWong1981126 2003-11-26
  • 打赏
  • 举报
回复
我觉得还是叫声明比较好听
gad1star 2003-11-26
  • 打赏
  • 举报
回复
针对你上篇帖子中的一个问题:
http://www.luocong.com/bbs/dispbbs.asp?boardID=2&replyID=1270&ID=242
dxmdxs 2003-11-26
  • 打赏
  • 举报
回复
我的大脑为NULL!
yjh1982 2003-11-26
  • 打赏
  • 举报
回复
laomai(老迈).....我发现我又得吐血了.....你没看过csdn的规则吗?
laomai 2003-11-26
  • 打赏
  • 举报
回复
我也吐血了,楼主居然能给出150分?提问顶多能给100分吧?

问 题 分数 回复 时间 功能
"一个让诸位喷血而死的发现!!"续集 :) (yjh1982 ) 150 23 11-26 14: 22 管理

难道楼主和CSDN的总斑竹有.....?
zhouqingyuan 2003-11-26
  • 打赏
  • 举报
回复
吐血了,三升,还好没死!
piaoairy 2003-11-26
  • 打赏
  • 举报
回复
个人觉得哪种语言都不是10全10美的,
肯定会存在这样或那样的缺陷,
语言设计者在设计过程中也不能对所有标准全部兼顾,
只能尽可能的去折中设计,
由于个人的取舍和考虑的不足,
差错几乎无法避免。
不过对程序员来说, 最重要的是熟悉自己使用的语言,
了解它的优缺点, 并且知道如何去避免。
在下愚见, 盼大家指正。
leyt 2003-11-26
  • 打赏
  • 举报
回复
mark
加载更多回复(19)

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧