另人沮丧的java

lishifeng 2003-05-09 01:44:56
What will the following class print ?

class InitTest
{
public static void main(String[] args)
{
int a = 1;
int b = 1;
a = a++;
b = b++ + b;
System.out.println(a+ " "+b);
}
}

THE ANSWER IS 1 3 !!

如果说JAVA是在C/C++基础上修改得来的语言(虽然这样说不尽恰当),我不明白为什么单在此处做如此修改,真令人困惑和沮丧。我不知道这是一个未解(甚至不想解决)的BUG,或者是JAVA设计者留给所有C/C++程序员的陷阱,还是什么技术上的革新。


...全文
45 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaofenguser 2003-05-13
  • 打赏
  • 举报
回复
你上面说的还是有很多东西不敢苟同.
只有学的时间长才有发言权的话,那么在java里我也没有发言权,我学java的时间也不过六七个月.我不是天才也不是神童,但是我可以想象,可以去试着理解创造C/C++和java的人的本意.而且C/C++本身不足以学六年,一门语言本身根本没有必要去学六年才能理解对不对呢?

你说我没有发言权的话,是因为我对C/C++的++运算符的理解有误还是根本就是错了?我们讨论的是++而已,并不涉及到C/C++太多的内容对不对?我们仅仅讨论的是java中的++还是C/C++中的++谁更合理是不是呢?这些东西的存在就有其理由,这些理由你都知道了,我只想知道而已,C/C++中的++更有理由存在的话才能说java中的++不合理对不对?

另外:
x = x + ++x + ++x + ++x 并不是x = 1+2+3+4;
这只是个简单的例子,只是说明一下,java中的++用C/C++中的++的难于表达.
你的表达式
for(x=1;x<=n;x++)
{
y+=x;
}

并不是我想要的,C/C++和java本就可以互相表达,我想要的是用++表达的.你也看到了,java中的++用C/C++中的++不是那么容易表达对不对?上面只是一个极简单的,你可以自己多写几个象下面这样的
x = x + ++x + ++x + --x + --x + --x + ++x;
来转成C/C++来试试.

好了,这个问题也不再讨论了.
lishifeng 2003-05-13
  • 打赏
  • 举报
回复
to gameboy999(预防非典,从我做起)

我知道我们的分歧在那里了。第一,你使用的是VC,我用的是TC;第二,你没有在TC下实验,我也没有在VC下实验。刚才我装了VC试了一下,如你所说。也请你在TC底下看看我所说是不是属实。

to xiaofenguser(风雨)

你对问题的执着令我感动。谢谢你让我受益非浅。不过看了你最后一篇帖子,我觉得你其实似乎不适合在这个问题上多发言,至少按你所说你并没有怎样使用过C/C++。而我本人从大学到现在使用C/C++已经6年了,而学习JAVA也有1年的时间了,而我再重申一遍,我很喜欢JAVA。当然不是说时间长就学得好,但是反过来,我觉得是可以的:如果你学得时间不长,并且你不是什么神童,天才之类的话,我可以说你掌握的还不够。
最后说说你希望我正面回答的问题:
我的回答是,
1。如果我要实现1+2+3+4,我不会用变量;直接写 x=1+2+3+4. 相信你也是。
2。而如果要实现1+2+3+4+...+n,我会用一个for循环
y=0;
for(x=1;x<=n;x++)
{
y+=x;
}
3。我说这个问题可笑是因为它不可能出现在你的代码里面,(注意我指得不是实验室的代码,而是你自己写工程软件时的代码,)那么它究竟带来什么好处呢?

to All

我很失望,因为++这样的操作居然也编译器化了,而不属于语言本身。
因此,讨论就此结束吧。谢谢诸位捧场。
鄙人的帖子时有用词不当之处,也有不注意言语中伤害别人的地方,但绝对出与讨论问题的真心,没有特意贬低或侮辱谁的意思。还请各位,特别是 gameboy999(预防非典,从我做起) 和 xiaofenguser(风雨) 两兄见谅。

如有问题和我讨论,My Email: lsfsohu@sohu.com
huguojunsy 2003-05-13
  • 打赏
  • 举报
回复
不错不错,这样的问题挖掘到如此的深度也是难能可贵,受益非浅。听课ing!!!!
lishifeng 2003-05-12
  • 打赏
  • 举报
回复
to xiaofenguser(风雨)

我实在不能确切明白你要表达的意思,只能猜了。

第一,“我问的是既然表达式相等,那么a和b应该相等. ”这个好象不是个问题。你能不能表达清楚呢?比如加上“为什么a和b不相等呢?”等等。(至少应该有问号吧)我只能权且按照猜想这样理解。那么回答这个问题很简单。我说过C/C++里++操作是语句级的,它出现在表达式里面应该先分离出来。从理解上并没有什么困难的,即使在形式上x=f(x)与y=f(x)(f中有++这样的操作)并不等价。其实每一种操作都有其特殊性不是吗。我不相信JAVA因为要让x=f(x)与y=f(x)等价而去修改++的概念,要知道从++诞生到JAVA诞生中间的岁月里,无数的程序员和代码对于++的概念都是C/C++形式的。最重要的是,在这些无数次的使用++里面,没有很多人对它的概念提出质问,没有很多人认为这样的方式带来了不变。那么,为什么要修改?设想一下,如果推出的新的语言都对++作不同的诠释,那会带来多少不便。

第二,
“在数学上除交换律外还有:
result = f1(a) + f2(a) + f3(a)
也可以化成:
result = f1(a);
result =result + f2(a); // 数学上也没有这种表达式的.
result =result + f3(a); ”
你的这一段我就更不明白了。数学里面东西多了,可是被列为运算基本定律的就这么几个。你这个是什么定律呢?看看离散数学吧,你会明白运算满足基本定律意味着什么。
sjc0722 2003-05-12
  • 打赏
  • 举报
回复
路过~ 你们争你们的 我学学东西~

加油~
xiaofenguser 2003-05-12
  • 打赏
  • 举报
回复
result = f1(a) + f2(a);
result2 = f1(a) + f2(a);
C/C++中:result完全可以不等于result2,这用语句级的来解释我无意见,语句级也就无所谓什么交换律对不对?
但是别忘了,它的写法完全是一个表达式!拿表达式来解释应该更合理对不对?

那么,为什么要修改?设想一下,如果推出的新的语言都对++作不同的诠释,那会带来多少不便。
// 你的理由是已经存在的东西就不能改,难道还不能去伪存精?那么语言的发展的意义在哪里?对于推出新的语言都对++作不同的诠释,这一点你放心,如果新的诠释不合理,那么它就没有前途。如果java诠释的不及C/C++它也没有今天。
至于不便嘛,我只学过一星期C,没感觉到不便。

result = f1(a) + f2(a);
我现在在后面加一个f3(a);
在c/c++里,你可更要小心了,加的东西不仅f1(a),f2(a)对f3(a)影响,而且f3(a)还会来影响f1(a),f2(a),甚至把本来有理的东西变得完全没有理了。根据result的不同f3(a)的影响还可以把它完全改观!
如果在C/C++中:
a = a + a++ + ++a;
可以转化为:
a++;
a = a+a+a;
a++;
的话,那么这个功能是不是更可笑?除了简化一点表达式,其它的好处呢?
满足了交换律?请问你写的程序几时这么注重交换律了?离散数学说白了不过是指导,难道还对++或--符号有指导作用?满足交换律的几种运算符里没有++和--对不对?

java的有序给你看一看它的功能吧:
a = 1;
a = a + ++a; // a = 1 +2 = 3;
a = ++a + a;// a = 2 + 2 = 4;
看到了吗?同一个表达式只要换一个顺序就能表达出完全不同的意义,
这点功能C/C++有无序能够达到吗?

问:难道仅仅为了得到在计算1+2+3+4这样可笑的问题时的简便的书写方式?
你用C/C++来实现几个java中的可笑表达:
x = x + ++x + ++x + ++x;
x = x * ++x * ++x * ++x;
就这两个白痴或者是可笑的表达式吧(希望你正面回答,可笑的东西不是没有用)。

java与C#难道是笨蛋吗?离散数学基本定律,嘿嘿
为什么我说的话很多人都难理解。
lishifeng 2003-05-10
  • 打赏
  • 举报
回复
to gameboy999(预防非典,从我做起)

如果你在这里钻下去,你离题目越来越远了。

temp=a++ + ++a; 虽然在C/C++里都是temp=4但原因是不同的。
C/C++里的过程是:
1.转换成三个语句:++a;temp=a+a;a++;
2.这样temp=4;a=3;
JAVA里的过程是:
1.计算表达式的值(用x表示):x=a;a++;++a;x+=a;很简单x=4;
2.将表达式的值赋给temp,这样temp=4.

temp=a + a++ + ++a; 在C/C++里temp=6,在JAVA里是5

最后,我收回“可以看出你是个年轻的程序员”这句话,看得出你挺在乎,所以我向你道歉。
gameboy999 2003-05-10
  • 打赏
  • 举报
回复
to 历史风,我学java不久,但是c/c++应该说还是比较久了。
请问你如何解释在c/c++下面

int a=1;
int tmp=0;
tmp= a++ + ++a; tmp=4;
但是。。
tmp= a + a++ + ++a; tmp=4

注意看两个结果都是等于4!!
xiaofenguser 2003-05-10
  • 打赏
  • 举报
回复
C/C++里: b=a++ + a; => a++;b=a+a; (变成两个语句)所以结果是a=2,b=2
JAVA里: b=a++ + a; => temp=a;a++;temp+=a;b=temp; (temp是表达式的值)所以a=2,b=3

C/C++里:a++运算符优先级低于算术运算符,赋值运算符.++a运算符优先级又高于算术运算符,赋值运算符,即b = a++ + a;<==> b = a + a++; b = a + ++a; <==>b = ++a + a;
JAVA里: ++运算符与算术运算符同级,高于赋值运算符.
b = a++ + a;<!=> b = a + a++; b = a + ++a; <!=>b = ++a + a;

优劣很明显.抛弃糟粕是应该的。
nettman 2003-05-10
  • 打赏
  • 举报
回复
个人看法:

Java和C#是一种纯粹的OOP工具,考虑的是如何将开发工具和现实世界的对应关系;

C/C++由于历史的原因,有了更多的和计算机硬件的血肉联系(用词有点不当,呵呵~~!),更多地考虑的是硬件操作和执行效率的问题。

所以在“++”操作这个地方出现分歧是难免的。
nettman 2003-05-10
  • 打赏
  • 举报
回复
下面是对应的C#代码,输出也是:1和3。

class InitTest {
public static void Main() {
int a = 1;
int b = 1;
a = a++;
b = b++ + b;
System.Console.WriteLine("a = " + a);
System.Console.WriteLine("b = " + b);
}
}

看来MS的C#抄Java抄得太厉害,连Bug也抄,嘿嘿~~!
xiaofenguser 2003-05-10
  • 打赏
  • 举报
回复
我认为java的比c/c++的自增设计更合理!
a = a++;并不是a = a; a++;
而应是a++在=运算符之前,返回的是没有自增的a;即a++; a = 1(自增前的a).
mengz 2003-05-10
  • 打赏
  • 举报
回复
还是C++对这个问题的处理更合理一些,应该是BUG吧?
mengz 2003-05-10
  • 打赏
  • 举报
回复
a = a++;
头大了... 自增之后怎么会是1呢... 那么自增之后的那个增量跑到哪去了?
gameboy999 2003-05-10
  • 打赏
  • 举报
回复
<quote>
关于有序好还是无序好,请你看看下面的代码:
result=f1(a)+f2(a);
很简单,自然的理解是它将等价于
result=f2(a)+f1(a);
对了,小学生都知道这是加法交换律。
</quote>

历史风的意思是说c/c++是无序的,而java是有序的,错了。。至少在vc的编译方式下是错的!请看例子
#include "stdio.h"
void main()
{
int a=1;
int tmp=0;
tmp= ++a + a + a; //tmp = 6;
tmp = a + ++a + a; //tmp =6;
tmp = a + a + ++a; //tmp =4;
}
这三个表达式如果在无序的状态下,应该是一样的结果对巴,事实上不是!请历史风亲手在vc或tc下面试试!
gameboy999 2003-05-10
  • 打赏
  • 举报
回复
#include "stdio.h"
void main()
{
int a = 1;
int temp;
temp=a + a++ + ++a;
printf("%d",temp);
cout<<"press any key to contine:";
getchar();
}

to 历史风,你理解错我的意思了,上面的语句输出的是4!!不是6!!


#include "stdio.h"
void main()
{
int a = 1;
int temp;
temp= a++ + ++a;
printf("%d",temp);
cout<<"press any key to contine:";
getchar();
}

输出的也是4!!!!


你来解释一下好吗 :)
xiaofenguser 2003-05-10
  • 打赏
  • 举报
回复
呵,不用说看不懂啦.
a = a + a++ + ++a;和
b = a + a++ + ++a;
我问的是既然表达式相等,那么a和b应该相等.

在数学上除交换律外还有:
result = f1(a) + f2(a) + f3(a)
也可以化成:
result = f1(a);
result =result + f2(a); // 数学上也没有这种表达式的.
result =result + f3(a);
这么看:
a = 1;
f1(a) = 10/a;
f2(a) = a*100;
f3(a) = a--;

如果用前后两种表达式运算结果也应该一样的.
lishifeng 2003-05-10
  • 打赏
  • 举报
回复
抱歉,看不懂。
xiaofenguser 2003-05-10
  • 打赏
  • 举报
回复
至于temp=a + a++ + ++a;的理解我是失误了,呵呵.
那你解释
a = a + a++ + ++a;和
b = a + a++ + ++a;

result1 = fl(a);
result2 = fl(a);
自然的,result1 = result2.请你解释一下吧.问题可笑也罢,再让你笑一下又何妨?
mercury1231 2003-05-10
  • 打赏
  • 举报
回复
首先楼主说的一点都没错:
C++: 2, 3
Java: 1, 3

至于为什么,我也是只知其然,不知其所以然。
但是至于这说不说明Java是有bug的语言,我想绝对不能这样说吧。


其次感谢gameboy999(预防非典,从我做起)的解释,我觉得你讲得很仔细哦。
希望以后能多多指教。
加载更多回复(15)

23,404

社区成员

发帖
与我相关
我的任务
社区描述
Java 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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