基于PHP和AJAX创建RSS聚合器 移动IP与DHCP、VPN等技术的比较 五招让Vista电脑更具个性化 Oracle 如何搞垮他的数据库——谈Oracle安全

足让你打吃一惊:一小段奇异的代码

[ 482 查看 / 100 回复 ]

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
   Button1: TButton;
   Button2: TButton;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
  private
   function GetTrue: Boolean;
   function GetValue1(var s: string): Variant;
   function GetValue2(var s: string): Boolean;
  public
   { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

function TForm1.GetTrue: Boolean;
begin
  Result := True;
end;

function TForm1.GetValue1(var s: string): Variant;
begin
  Result := True;
  s := 'World';
end;

function TForm1.GetValue2(var s: string): Boolean;
begin
  Result := True;
  s := 'World';
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  s: string;
begin
  if GetTrue or GetValue1(s) then
   ShowMessage('Hello ' + s);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  s: string;
begin
  if GetTrue or GetValue2(s) then
   ShowMessage('Hello ' + s);
end;

end.


//看看会Show什么出来?
TOP

足让你打吃一惊:一小段奇异的代码

hello world
hello
TOP

足让你打吃一惊:一小段奇异的代码

为什么呢?
TOP

足让你打吃一惊:一小段奇异的代码

楼上的高手是否评论下
TOP

足让你打吃一惊:一小段奇异的代码

引用 3 楼 baseyueliang 的回复:
楼上的高手是否评论下

你想知道什么,哪里不明白,var s: string,你把值付给了s,然后'Hello ' + s,不就是要显示的字符串吗
TOP

足让你打吃一惊:一小段奇异的代码

这没什么奇怪的吧
TOP

足让你打吃一惊:一小段奇异的代码

这是显而易见的。我问的是二次操作的区别。
TOP

足让你打吃一惊:一小段奇异的代码

引用 6 楼 baseyueliang 的回复:
这是显而易见的。我问的是二次操作的区别。

两次操作有何区别var s: string都是一样的
TOP

足让你打吃一惊:一小段奇异的代码

引用 7 楼 bdmh 的回复:
引用 6 楼 baseyueliang 的回复:
这是显而易见的。我问的是二次操作的区别。

两次操作有何区别var s: string都是一样的


最终显示上的区别是何引起的?
TOP

足让你打吃一惊:一小段奇异的代码

有什么奇怪的啊?
难道不是
Hello
Hello
?
TOP

足让你打吃一惊:一小段奇异的代码

引用 9 楼 chys3584 的回复:
有什么奇怪的啊?
难道不是
Hello
Hello
?

如果仅仅如此,我有必要发此帖么
TOP

足让你打吃一惊:一小段奇异的代码

Delphi(Pascal) code

function TForm1.GetValue2(var s: string): Boolean;
begin
Result :
= True;
ShowMessage(
'af');//加上这行再试试,会发现没有执行
s :
= 'World';
end;

TOP

足让你打吃一惊:一小段奇异的代码

有,这个问题很有意思
引用 10 楼 baseyueliang 的回复:
引用 9 楼 chys3584 的回复:
有什么奇怪的啊?
难道不是
Hello
Hello
?

如果仅仅如此,我有必要发此帖么
TOP

足让你打吃一惊:一小段奇异的代码

引用楼主 baseyueliang 的帖子:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    function GetTrue: Boolean;
    function GetValue1(var s: string)…




 我想這應該是一個典型的編譯器優化的結果吧。 不過的確寫成這樣代碼挺有意思的。
TOP

足让你打吃一惊:一小段奇异的代码

Delphi(Pascal) code



unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1
= class(TForm)
    Button1: TButton;
    Button2: TButton;
   
procedure Button1Click(Sender: TObject);
   
procedure Button2Click(Sender: TObject);
  private
       
function GetTrue: Boolean;
   
function GetValue1(var s: string): Variant;
   
function GetValue2(var s: string): Boolean;

  public
   
{ Public declarations }
 
end;

var
  Form1: TForm1;

implementation

{$R *.dfm}



function TForm1.GetTrue: Boolean;
begin
  Result :
= True;
end;

function TForm1.GetValue1(var s: string): Variant;
begin
  s :
= 'World';
  Result :
= True;

end;

function TForm1.GetValue2(var s: string): Boolean;
begin
  Result :
= True;
  s :
= 'World';
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  s: string;
begin
 
if GetTrue or GetValue1(s) then
    ShowMessage(
'Hello ' + s);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  s: string;
begin
 
if  GetValue2(s) or (GetTrue) then
    ShowMessage(
'Hello ' + s);
end;


end.





這樣看下就不會錯了。 我不知道這算不算一個BUG,但對於程序來說這是可以避免的。 從優化的角度的來說是對的。只是碰上這個VAR 搞慘了。
TOP

足让你打吃一惊:一小段奇异的代码

第二個GetValue2(s)沒有執行,可能是因為if GetTrue or GetValue2(s) then 
的函數GetTrue 得到真後,就不執行GetValue2(s)了,第一個GetValue1(s)因為返回值是
Variant,編譯器不直接認為是布爾類型,所以執行了GetValue1(s)。
ˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍ
不知道大家認同不?
 
TOP

足让你打吃一惊:一小段奇异的代码

引用 8 楼 baseyueliang 的回复:
最终显示上的区别是何引起的?


procedure TForm1.Button2Click(Sender: TObject); 
var 
  s: string; 
begin 
  if GetTrue or GetValue2(s) then //这个判断条件是'或',第一个GetTrue 条件满足,就不会再判断第二个了
   ShowMessage('Hello ' + s); 
end;
TOP

足让你打吃一惊:一小段奇异的代码


執行函數判斷,你可以跟一下匯編,從左到右去執行,第一個因為第二個是變體無法確定,所以優化不了。

因為第二個二個都返回BOOL值,在OR的情況下優化是很正常的。 所以出現了上述的結果。看我上邊的代碼應該明白的。
TOP

足让你打吃一惊:一小段奇异的代码

同意,看法一样
引用 15 楼 fengjsSoft 的回复:
第二個GetValue2(s)沒有執行,可能是因為if GetTrue or GetValue2(s) then
的函數GetTrue 得到真後,就不執行GetValue2(s)了,第一個GetValue1(s)因為返回值是
Variant,編譯器不直接認為是布爾類型,所以執行了GetValue1(s)。
ˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍ
不知道大家認同不?
TOP

足让你打吃一惊:一小段奇异的代码

引用 15 楼 fengjsSoft 的回复:
第二個GetValue2(s)沒有執行,可能是因為if GetTrue or GetValue2(s) then
的函數GetTrue 得到真後,就不執行GetValue2(s)了,第一個GetValue1(s)因為返回值是
Variant,編譯器不直接認為是布爾類型,所以執行了GetValue1(s)。
ˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍ
不知道大家認同不?

应该是这样的
TOP