关于Boolean型函数在 IF then 判断语句中的写法。(50分)

  • 主题发起人 主题发起人 delhpi
  • 开始时间 开始时间
D

delhpi

Unregistered / Unconfirmed
GUEST, unregistred user!
unit Unit3;

interface

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

type
TForm3 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form3: TForm3;

implementation

{$R *.dfm}

function Test:boolean;
begin
//假设有这个空的返回值是boolean型 函数
end;
procedure TForm3.Button1Click(Sender: TObject);
begin
if test then //写法差异在这句
caption:='true'
else
caption:='false';
end;

procedure TForm3.Button2Click(Sender: TObject);
begin
if test =true then //写法差异在这句
caption:='true'
else
caption:='false';
end;

end.

if test then

if test=true then

有什么区别吗?
 
if then之间可以是任何合法的布尔表达式,两种写法在逻辑上没有任何区别——无论是
变量还是表达式,它们的值都是布尔类型——它们只是在写法的清晰性上有差别而已。

类似的写法还有:
var
i:Integer;
b:Boolean;
begin
//以下两句等价
b:=(i=0);
if i=0 then b:=true else b:=false;

//以下两句等价
if b=false then i:=0 else i:=1;
if not b then i:=0 else i:=1;
end;
 
谢谢。

我印象里好像也是这样

if test then

if test=true then

好像是没有区别。test函数里如果没有任何语句设置result:=true的话,那么他的返回值默认是false;

但是实际上,如果你运行这个代码的话,会发现,有差异。

点击button1 caption会显示 true,也就是说 if test then 判断的结果是 true,感觉这个有点意外。

点击button2 caption会显示 false ,这个没有出乎大家的预料。
 
看来以后写函数一定要
设置默认返回值
如果执行终止时未曾向Result或函数名赋值,那么函数的返回值是未定义的。

或者
引用函数写判断表达式时,一定要用
if functionname=true then


如果上面2个地方都不注意的话,有时候判断的结果不对。
 
>>test函数里如果没有任何语句设置result:=true的话,那么他的返回值默认是false;
Delphi的函数没有“默认返回值”——如果没有显式的Result:=xxx;那么,返回值就是不
确定的。不要让你的代码处于不可控的混乱。
 
应该返回是不确定的,最后是加上=ture
 
看看汇编代码就会知道——Delphi函数的返回值存放在EAX寄存器中——若没有显式EAX寄
存器的值在进入函数时是不确定的(受函数的调用环境控制),所以在未为Result赋值时,
Result的值就是不确定的(即便你用了if test=true then的模式,也会因为不同的编译优
化情况而无法绝对保证!)。
置于如何避免——Delphi编译器对没有设置Result的函数会给出编译警告(对函数内部未
初始化就直接使用的局部变量也会一样给出警告):

function A:Boolean;
begin
end;
[Warning] Unit1.pas(27): Return value of function 'A' might be undefined.

不要忽略任何编译警告——对代码负责就是对自己负责。
 
谢谢,我已经发现这个编译器提示了。虽然大致知道他的意思,但以前不是很重视。

主要是很多自己写的函数,通常情况下,里面的语句会设置result的值,也就是说会执行到赋值的语句。所以对 Return value of function 'A' might be undefined 一直没有引起注意。

碰巧昨天写的函数,因为条件不符合,所以函数内设置result值的语句没有执行到。结果函数就处于“返回值没有定义的状态”。

然后在别的地方IF语句里判断时,结果就不是自己想象的那样了。

至于d里的函数是否有默认返回值的说法,我也是自己猜测的,请别见怪。至于汇编状态下的情况,就更不懂了。

比如
function StrTest:string;//没有设置返回值 我猜测认为 返回值是 ''
begin
if 1>2 then
strtest:='1>2';
end;


procedure TForm3.Button3Click(Sender: TObject);
begin
if strtest='' then //判断结果,是真
self.Caption:='Blank';

end;

反正我现在记得2条
1、尽量设置函数的返回值,确保任何条件下,都有明显的result赋值结果语句执行。
2、比较的时候写全,比如对于boolean 的比较 后面加个=true。
 
有第一条够保证正确性了,第二条属多余,呵呵:)

if ((((1=2)=true)=true)=true)<>false then ... [:D]


猜测没错,但是结论要建立在对原理的掌握上才牢靠。
第一条要绝对严格的执行,因为我们可以确定“未初始化 = 不确定”,而“未赋值 = 空
或 false”则属于“臆断”——不要在不能确定效果的地方偷工减料。
第二条无需理会,因为只要保证了一切都有确定值,最简单的写法就是最有效的、同时也
是正确的——不用怀疑。
 
谢谢

下面3个函数有什么区别吗?哪个属于为未初始化,哪个属于未赋值?

function BoolTest:boolean;
begin
//下面2行其实永远也不会执行,相当于这个函数没有语句
if 1>2 then
result:=false;
end;
function StrTest:string;
begin
//下面2行其实永远也不会执行,相当于这个函数没有语句
if 1>2 then
strtest:='1>2';
end;

function IntTest:Integer;
begin
//下面2行其实永远也不会执行,相当于这个函数没有语句
if 1>2 then
result:=1;
end;
 
上面的几种情况么?问编译器自己最保险——BoolTest和IntTest都有警告,而StrTest则
没有——这至少说明在我使用的Delphi 7编译器中,返回值为Boolean和Integer的函数中的
结果值在未显式赋值时是不确定的,而返回值为字符串的函数没有警告,说明编译器对字符
串变量有自己的处理(考虑到Delphi编译器会通过引用计数等机制管理每个字符串变量的生
命周期,没有初值的字符串变量本身就会导致问题,所以,编译器对字符串有特别处理也是
可以理解的)——但是,多写一个Result:=''就可以绝对保证不同编译器或编译选项时都有
绝对正确的结果,而在if中多写一个 =true 不会有任何实际帮助(即便有时候“看起来”
有效果,也不是必然)。
 
谢谢 学习了。不过我 有时候 在用D2007时,发现

procedure TForm1.Button1Click(Sender: TObject);
if self.showing then
....

代码编辑器在 self.showing 下面显示红色的波浪形,说什么没有定义,不是一个boolean表达式。

改成
procedure TForm1.Button1Click(Sender: TObject);
if self.showing = true then
....

就好了。

不知道什么原因,也许是IDE问题,也许是我的代码问题。

反正通过这个问题,又学到了一点点。
 
if Self.Showing then —— 我在Delphi 2009的IDE中没有遇到任何警告或错误...
 
是的,我也是偶然几次遇到。如果是固定的,大家早就提出来了。

一开始我提问题时,以为是我的表达式写得有问题,因为我以为那个函数会默认是false,后来发现,是函数写的有问题。
 
if function=true then ...我认为是脱裤子放屁-------多余,本身函数不写返回值,就是编程人员最不好的习惯,而且我认为function=true 的效率肯定比 if function then 效率低(有研究过delphi编译器的朋友请发言).
 
本来就是菜鸟才会遇到这样的问题。不过,同样是没有写返回值,不同的情况,还是有差异的。结贴啦。
 
test函数没有写对
result 应该给个明确的初始值,或者要在每种情况下要人RESULT附一个值,不然RESULT可能会是当时申请内存时的那个值.
 
如果是多年前,我会写出if test then
但现在我会写if test = false then
我觉得,让人看得轻松一些比较重要,再说了,编译器产生的代码效率应该是一样.
另外说起bool,在混合编程的时候,要小心的,Boolean类型比较多,有Object Pascal原生的Boolean,有扩展的WordBool,LongWord,和在OLE Automation中使用的Variant Bool,有些语言没有bool类型,它们在判断true和false可能有一些差别,编程中如果不太留意的话,可能会出错.
 
其它语言且不提,我们使用的Delphi是强类型语言,所以不存在“可能会出错”的问题。

if test = false then 与 if not test then ——似乎可读性没啥区别吧?
if test = true then 与 if test then ——看个人习惯了(有人读过VCL源码么?:)
 
是的,不过一开始没有注意到。
一开始是这样写的,就是最正常的写法
if test then
.......
我也知道函数本身就是boolean型,没有必要再用 test = true。

只不过当时 if test then ,判断的结果是true,而是实际的情况应该是false,所以测试时随便试试
if test =true then
的写法。

不过居然判断的结果不同,所以我还以为表达式写法上有什么奥秘,就提问了。

提问后,看了回复,同时又去看了,苏勇的那个中文pascal语法翻译说明,注意到
“如果执行终止时未曾向Result或函数名赋值,那么函数的返回值是未定义的。”

问题的原因应该是
Return value of function 'Test' might be undefined

之所以犯这个错误,一方面是菜鸟的原因,另外一方面有点受 字符型函数 的影响

function StrTest:string;//没有设置返回值 我猜测认为 返回值是 ''
begin
if 1>2 then
strtest:='1>2';
end;
procedure TForm3.Button3Click(Sender: TObject);
begin
if strtest='' then //判断结果,是真
self.Caption:='Blank';
end;

以为函数定义后,如果没有语句对函数赋值,那么函数会有个默认值(当然这个是错误的想法),比如StrTest就是'',BoolTest就是false。

我后来对过程或者函数内声明的局部变量也测试了一下,和函数的情况类似。
procedure TForm3.Button4Click(Sender: TObject);
var
intVar:integer;
boolVar:boolean;
Strvar:string;
begin
if intvar=0 then
Caption:='0'
else
caption:=inttostr(intvar); //结果是4410684

showmessage('intVar'); //让程序停一下,否则不能分别看到结果

if boolvar then
Caption:='True' //结果是 true
else
Caption:='False';

showmessage('boolVar');//让程序停一下,否则不能分别看到结果

if strvar='' then
caption:='Blank' //结果是blank
else
caption:='Not Blank';

end;

不过全局变量应该是有默认初始值的,自己平时把这些概念没有区分的很清楚,所以有时候就返错误了。
var
Form3: TForm3;
isok:boolean;
int:integer;
str:string;
implementation

{$R *.dfm}

procedure TForm3.Button2Click(Sender: TObject);
begin
if( isok =false) and (int=0) and (str='') then
Caption:='true' //结果是 true
else
caption:='false';

end;


还发现有个有趣的现象,对于函数
function BoolTest:boolean;
begin
//下面2行其实永远也不会执行,相当于这个函数没有语句
if 1>2 then
result:=false;
end;
测试下面的语句
procedure TForm3.Button1Click(Sender: TObject);
begin
if booltest =true then
caption:='true'
else
caption:='false'; // 结果是false


if booltest =false then
caption:=caption+'true'
else
caption:=caption+'false'; //结果也是false

if booltest then
caption:=caption+'true' // 结果是true
else
caption:=caption+'false';
end;

呵呵。
 

Similar threads

I
回复
0
查看
699
import
I
I
回复
0
查看
891
import
I
I
回复
0
查看
775
import
I
后退
顶部