【讨论】编程

学c++语言需要学好c语言吗?还是只需要了解一点,
我个人认为不一定多精通,至少要学会c语言,才能学好c++语言,
请叫各位的意见呢?     Re:【讨论】编程

原则上是不要。但C++的书很少会从头开始,多少都假定你了解c。
C比较容易学,先学C也没什么不可。

不好意思的是我虽然都自学过,因为用得少,都不精通。     Re:【讨论】编程

C和C++差别太大,可以直接学C++
C的编程思想无益于对C++的理解     Re:【讨论】编程

转贴一篇自己的文章,比较有趣。晶禧千年学了C++之后尝试做一做。
这曾经是一道贵宾认证试题(意思是答对了就能成为论坛贵宾啦。事实上这道题的讨论结果是产生了一篇精华、两个版主)

这次的题非常非常简单的啦,不过还是慷慨地给出了10分哦:)
要求:(不要你编程了,我都写好了,我是不是很好啊)
给出程式的输出结果,并用专业术语解释为什么会有这样的输出结果。 程式也是非常非常的简单:)


#include <iostream.h>

class boy//男人类
{
public://他敞开胸怀
    void LoveYou(float result)
    {
        cout << "Preety, I love you, marry me!" << endl;
    }
    void KissYou(float result)
    {
        cout << "Pretty, you are too sexy, I want to kiss you..." << endl;
    }
};

class girl : public boy//上帝说女人是……
{
public://她也敞开胸怀……我什么都没看见:)
    void LoveYou(int result)
    {
        cout << "I love you too...But I am too shy to say..." << endl;
    }
    void KissYou(float result)
    {
        cout << "You do what you want..." << endl;
    }
};

void main(void)
{
    girl  pretty;//一个女孩叫pretty
    boy  handsome;//一个男孩叫handsome

    girl  *the_pretty_home  = &pretty;//女孩说:我不要离开家……不嫁给你(真的?)!
    boy  *the_handsome_home = &pretty;//男孩说:来我家吧,我爱你!

////////////////////////////////////////
//----------?????他们在干什么呀?请写出结果-------------

    the_handsome_home->LoveYou(52.1f);
    the_pretty_home  ->LoveYou(52.1f);

    the_handsome_home->KissYou(52.1f);
    the_pretty_home  ->KissYou(52.1f);

////////////////////////////////////////
}     Re:【讨论】编程

[I]以下引用stuman的内容:
[/I]转贴一篇自己的文章,比较有趣。晶禧千年学了C++之后尝试做一做。
这曾经是一道贵宾认证试题(意思是答对了就能成为论坛贵宾啦。事实上这道题的讨论结果是产生了一篇精华、两个版主)

这次的题非常非常简单的啦,不......
偶永远成不了贵宾了,都不会。C忘光了。     Re:【讨论】编程

只能猜是:
Pretty, I love you, marry me!
I love you too...But I am too shy to say...
Pretty, you are too sexy, I want to kiss you...
You do what you want...

C++对我来说从来都一笔糊涂帐。我还真看不出来这个程序的妙处。有个地方把float对应到int大概有些不妥     Re:【讨论】编程

[I]以下引用丸子的内容:
[/I]
偶永远成不了贵宾了,都不会。C忘光了。
倒。。。谁不知道你是软件高手
前几天我装了个redhat linux 8,正痛苦摸索中,呵呵     Re:【讨论】编程

[I]以下引用Thermo的内容:
[/I]只能猜是:
Pretty, I love you, marry me!
I love you too...But I am too shy to say...
Pretty, you are too sexy, I want to kiss you...
You do what you want...

C++对我来说从来都一笔糊涂帐。我还真看不出?.....
答案完全正确,呵呵,Thermo厉害啊     Re:【讨论】编程

这只是一个概念问题吧。girl的成员函数对boy的成员函数非常类似于重载(reload),但在概念上叫做“隐藏”(hide)。具体说,girl的LoveYou隐藏了boy的LoveYou,girl的KissYou隐藏了boy的KissYou,所以,对girl的派生类来说,boy的两个成员函数都是存在的。至于说参数为什么不一样,只是为了演示参数类型对“隐藏”的影响和与“重载”的重要区别:
girl和boy两个类中两个LoveYou()函数可能用“近似重载"来勉强解释,但是两个KissYou(float result)函数的形式一模一样,能用“重载”来解释吗?重载的函数必须参数不同的,对吧?重载也不可能发生在两个类中。
最让人迷惑的就是为什么the_pretty_home和the_handsome_home被赋予同样的地址(&pretty),按道理说the_pretty_home.LoveYou和the_handsome_home.LoveYou(还有两个KissYou)的结果应该完全一样,但竟然结果不同!那么更深层次的理解需要用类的内存构象来解释,涉及到编译器的处理,我想我们没必要探讨那么深入了。
这里,我们只要明白在隐藏的情况下,boy.LoveYou是能通过派生类girl调出来的。这在实践上可能没什么用处,不过在程序调试上万一出现这种错误,发现结果不对,百思不解,那么要当心这类问题了!

用调侃的解释来说:男孩娶了女孩以后,如果女孩管教不严,那么男孩可能会隐藏一些私房钱(好危险哦,小心他花心哦),这些私房钱是他自己的,但是没有上交给女孩,所以适当的时候他还是能花掉这些钱的。要彻底拿掉这些私房钱,女孩必须用强力手段“override”(覆盖)来镇压!

正确的输出结果是:

Preety, I love you, marry me!
I love you too...But I am too shy to say...
Pretty, you are too sexy, I want to kiss you...
You do what you want..

我祝福天下有情人终成眷属!     Re:【讨论】编程

ask:
对于C++来说,最强的功能是指针,最容易犯错的也是指针。本例中,关键是二个类的结构是完全相同的。这时候C++的编译器会根据最适合的方法来解释:

girl *the_pretty_home = &pretty;//女孩说:我不要离开家……不嫁给你(真的?)!
boy *the_handsome_home = &pretty;//男孩说:来我家吧,我爱你!

换句话说,这时,编译器并不知道the_handsome_home,the_pretty_home  到底是boy还是girl。必须根据具体的方法调用时才能确定。

。上例的结果实际上,严格来说并不准确,只能说对VC是正确的,对不同的编译器会有不同的处理方法,其结果也不同。

answer1:
我试过了,在C++Builder的编译器中,结果是一样的。

answer2:
我们需要更深层次来讨论这个问题,我反汇编了相关代码,这里是main()段:

:00401060 55                      push ebp
:00401061 8BEC                    mov ebp, esp
:00401063 83EC10                  sub esp, 00000010

:00401066 8D45FC                  lea eax, dword ptr [ebp-04]                    ;[ebp-04]为&pretty
:00401069 8945F8                  mov dword ptr [ebp-08], eax                  ;[ebp-08]为[the_pretty_home]
;girl  *the_pretty_home  = &pretty;

:0040106C 8D4DFC                  lea ecx, dword ptr [ebp-04]
:0040106F 894DF0                  mov dword ptr [ebp-10], ecx                  ;[ebp-10]为[the_handsome_home]
;boy  *the_handsome_home = &pretty;

:00401072 6866665042              push 42506666
:00401077 8B4DF0                  mov ecx, dword ptr [ebp-10]
:0040107A E890FFFFFF              call 0040100F
;the_handsome_home->LoveYou(52.1f);

:0040107F 6A34                    push 00000034
:00401081 8B4DF8                  mov ecx, dword ptr [ebp-08]
:00401084 E890FFFFFF              call 00401019
;the_pretty_home  ->LoveYou(52.1f);

:00401089 6866665042              push 42506666
:0040108E 8B4DF0                  mov ecx, dword ptr [ebp-10]
:00401091 E86FFFFFFF              call 00401005
;the_handsome_home->KissYou(52.1f);

:00401096 6866665042              push 42506666
:0040109B 8B4DF8                  mov ecx, dword ptr [ebp-08]
:0040109E E87BFFFFFF              call 0040101E
;the_pretty_home  ->KissYou(52.1f);

:004010A3 8BE5                    mov esp, ebp
:004010A5 5D                      pop ebp
:004010A6 C3                      ret

可以看到,the_pretty_home和the_handsome_home指针的数值的确是相同的,都指向了&pretty
但是为什么
the_handsome_home->LoveYou(52.1f);和
the_pretty_home->LoveYou(52.1f);
却得到了不同的结果。汇编代码提示出,在调用成员函数的时候已经被编译成不同的地址:一个是call 0040100F,一个是call 00401019。
经过函数跳转表后,call 0040100F是下面的代码:
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040100F(U)
|
:004010C0 55                      push ebp
:004010C1 8BEC                    mov ebp, esp
:004010C3 51                      push ecx
:004010C4 894DFC                  mov dword ptr [ebp-04], ecx
:004010C7 6814104000              push 00401014

* Possible StringData Ref from Data Obj ->"Preety, I love you, marry me!"
                                  |
:004010CC 6850BD4100              push 0041BD50
:004010D1 B9E0F44100              mov ecx, 0041F4E0
:004010D6 E875030000              call 00401450
:004010DB 8BC8                    mov ecx, eax
:004010DD E81EFFFFFF              call 00401000
:004010E2 8BE5                    mov esp, ebp
:004010E4 5D                      pop ebp
:004010E5 C20400                  ret 0004

非常明显,这就是boy类的成员函数LoveYou();而call 00401019同样可以证明是girl类的成员函数LoveYou();

最后我的结论是:上面的隐藏规则在编译的时候就确定和实现了,也即是“静态绑定”。C++类的指针不仅和它的值有关系,还和它的类别有关系。也就是说,编译器一定要知道the_handsome_home,the_pretty_home 到底是boy还是girl,才能确定具体的方法调用。这和C具有重大的区别。     Re:【讨论】编程

听君一分析,胜读十本书。
静态绑定类的成员函数调用还可以理解。我想知道的是:如果boy和girl类中定义有相同的数据(变量)的话,这些数据应该是动态的吧?也就是说the_pretty_home 和 the_handsome_home 会有相同的数值?     Re:【讨论】编程

Thermo太谦虚了。高水平的人就是不一样,难怪“自从小小结婚以后,眼中只有Thermo”~~
好象变量没有上述“覆盖”之类的概念啦。变量是谁的就是谁的,在the_pretty_home 和 the_handsome_home 会是各自不同的值。     Re:【讨论】编程

July,真的是你吗?你在学校里也学计算机语言吗?你的计算机知识好象在猛长耶!

我的意思是如果boy类中定义有变量比如age=21文(as the defualt value),和girl类中age=25, 在将pretty赋给the_hansome_home时,age会是什么?     Re:【讨论】编程

你好啊
作个朋友     Re:【讨论】编程

thermo真厉害,问题非常深入,有些问题确实出乎意外。我试了一下,那样得到的age是一个不定的值,也就是说the_hansome_home无法取到age的值。

我按你的意思在程序中加了age,如下:

#include <iostream.h>

class boy//男人类
{
public://他敞开胸怀
  int age;
  void LoveYou(float result)
  {
    cout << "Preety, I love you, marry me! My age is:" << age << endl;
  }
  void KissYou(float result)
  {
    cout << "Pretty, you are too sexy, I want to kiss you...my age is:" << age << endl;
  }
};

class girl : public boy//上帝说女人是……
{
public://她也敞开胸怀……我什么都没看见:)
  int age;
  void LoveYou(int result)
  {
    cout << "I love you too...But I am too shy to say...My age is:" << age << endl;
  }
  void KissYou(float result)
  {
    cout << "You do what you want...My age is:" << age << endl;
  }
};

void main(void)
{
  girl  pretty;//一个女孩叫pretty
  boy   handsome;//一个男孩叫handsome

  pretty.age=25;
  handsome.age=21;

  girl  *the_pretty_home   = &pretty;//女孩说:我不要离开家……不嫁给你(真的?)!
  boy   *the_handsome_home = &pretty;//男孩说:来我家吧,我爱你!

  boy   *the_handsome_Boyhome = &handsome;

////////////////////////////////////////
//----------?????他们在干什么呀?请写出结果-------------

  the_handsome_home->LoveYou(52.1f);
  the_pretty_home  ->LoveYou(52.1f);

  the_handsome_home->KissYou(52.1f);
  the_pretty_home  ->KissYou(52.1f);

  the_handsome_Boyhome->LoveYou(52.1f);
  the_handsome_Boyhome->KissYou(52.1f);
////////////////////////////////////////
}

输出结果是:
Preety, I love you, marry me! My age is:4219448
I love you too...But I am too shy to say...My age is:25
Pretty, you are too sexy, I want to kiss you...my age is:4219448
You do what you want...My age is:25
Preety, I love you, marry me! My age is:21
Pretty, you are too sexy, I want to kiss you...my age is:21

说明the_handsome_home根本就得不到任何类的age值。the_handsome_home只能访问被隐藏的成员函数,而不能访问到变量。     Re:【讨论】编程

真有些出乎意料,我原猜想The_handsome_home会被初始为girl的age。也许如果用赋值的方式的话The_handsome 才会有girl’s age。

C++难学就在于有些东西是在编译阶段处理的,有些却要等到运行。前者偏于约定,后者纯属逻辑。C++看过却没用过。不怕他笑话,我用得最多的是Fortran,老式的工程计算语言。

你的Linux弄得怎么样了?我前两年装过Red Hat,上星期装了红旗服务器版本2.0(找不到3.0),后来发现有的东西太老了,干脆重装了新的红旗桌面版。自己下载了apache,Perl,PHP和MySQL。今天才重装好。如果你碰到有什么问题的话也许我能点忙。我一直用Unix系统,所以比较熟     Re:【讨论】编程

我猜想The_handsome_home会被初始为boy的age……结果让我大跌眼镜,呵呵
C++我几乎没用过,我害怕使用它,尽量使用C来写。后来还有MFC的框架太痛苦,就转为Delphi了。一个朋友也这样说“c++太深奥了,越来越不敢碰;-)”呵呵。任何语言只是一个描述工作的工具,关键看解决的问题方式,写程序象写文章一样,不同的思路和不同的方法,都是一种艺术。
我是个UNIX盲,以后全靠你啦,嘻嘻。Fortran我完全不懂。以前我用过一段时间的Turbo Linux,记得一些命令而已。Linux下的编程完全不懂。现在装RedHat Linux 8。本打算好好研究一番,朋友托我写个程序,现在只好忙编程了。感觉时间太少了     Re:【讨论】编程

我说“初始”并不确切,我真正意思是指“男孩说:来我家吧,我爱你!”的时刻。我相信你的猜想并没错,只是男孩说完后,他就找不到家了。

Fortran是所谓的“scientific computational language”,没有几个人会。其实和C差不多。以后也许会被C慢慢替代。

Linux下编程选择很多,你会慢慢喜欢的。     Re:【讨论】编程

明白。Thermo越来越幽默了,哈哈
这问题把我也搞昏掉了……还是Delphi亲热:)
对于Linux,我的路还很远……     Re:【讨论】编程

我最近比较忙。没有精力把这个论坛搞得活跃起来。我想退位让给你。你和wmsztw都有主持论坛的经验。你们一定会搞得很好。

我当然还会经常来的。你看怎么样?     Re:【讨论】编程

非常谢谢你的好意:)
我也是因为太忙,只能经常来看看,学点东西,要主持论坛却实在有点力不从心。其实并不必苛求这个版块的活跃,带技术含量的版面通常文章都比较少,可能写一篇文章要花好几天时间。
我也会经常来的。并尽可能带点好文章来。
只要大家一起努力,不在乎努力的结果,也不在乎谁是版主谁是会员,一个版面就有一种大家喜欢的和谐环境。     Re:【讨论】编程

鹰派也是好久不来。要不你来当斑竹,wmsztw和我给你当帮手。怎么样?     Re:【讨论】编程

==========
此ID发言被屏蔽
==========

Remind:此消息由stuman在03-08 07:28:45做过手脚,呵呵……     Re:【讨论】编程

==========
此ID发言被屏蔽
==========

Remind:此消息由stuman在03-08 07:28:58做过手脚,呵呵……     Re:【讨论】编程

C++和C语言没有直接的联系,两者在编程体系上差别太大,所以学完C之后对C++没什么益处,当然如果你完全没有学过编程,先学C也是不错的。     Re:【讨论】编程

[I]以下引用stuman的内容:
[/I]对了,我现在发在空网的最后一贴。因为某些原因我想一个人安静。以后也不会来空网了。
你是一个非常和气的朋友,在空网,认识你,我特别高兴和荣幸,好像也只有和你、丸子在知识结构上比较能够沟通一点。算是我们的?.....
很遗憾你要走了。丸子会处理贵宾的事,ID还是保存的好。谁要是能破解你的密码,也算是够格用你的ID了。

I knew you worked in 灌水区 for a while. That is a place would kill one's enthusiatism if stay there too long. I am sorry that I missed the chance to know you earlier because I don't like to go there. Please come back to visist us sometime. We will miss you.     Re:【讨论】编程

==========
此ID发言被屏蔽
==========

Remind:此消息由stuman在03-08 07:28:28做过手脚,呵呵……     Re:【讨论】编程

I read your message。 I totally agree with you。Unfortunately you ID has been deleted as you requested。I asked 丸子 to restore your ID. But if this is what you want. I will tell 丸子 not to do so.

Thank you very much for your support. I will always cherish your time here.




欢迎光临 空网论坛 (http://bbs.kongweb.net/) 作者: Thermo    时间: 2003-3-4 22:05