[考题]关于局部变量procedure TForm1.FormCreate(Sender: TObject)varS: stringI: Integerbeginfor I :
[考题]关于局部变量
procedure TForm1.FormCreate(Sender: TObject);
var
S: string;
I: Integer;
begin
for I := 1 to 3 do
S := S + IntToStr(I);
ShowMessage(S);
end;
请指出以上代码可能出现的问题。
[解决办法]咳,S没有初始化。。。应该没影响啊。。
[解决办法]String/AnsiString/UnicodeString/WideString
作为局部变量,不需要初始化,是因为begin里已经初始化了(自动完成了)
这段代码没问题
但是作为返回值就最好初始化
[解决办法]没问题, 我不知道你想考什么, 但是假如你要考察s是不是初始化的话, 代码本身是不严谨的, 常规来说我们应该写初始化的部分, 但是由于delphi的引用类型作为局部变量会自己初始化为空, 所以这一步可以省了
[解决办法]我觉得没问题,就這段程序而言s,i都不用初始化
[解决办法]这样吧, 我把几种自管理类型的数据列出来吧, 平时不用背,直接查delphixe里面rtti的IsManaged函数
function IsManaged(TypeInfo: PTypeInfo): Boolean;
var
elTypePtr: PPTypeInfo;
begin
if TypeInfo = nil then
Exit(False);
case TypeInfo^.Kind of
tkDynArray, tkUString, tkWString, tkLString, tkInterface, tkVariant:
Result := True;
tkRecord:
Result := GetTypeData(TypeInfo)^.ManagedFldCount > 0;
tkArray:
begin
elTypePtr := GetTypeData(TypeInfo)^.ArrayData.ElType;
Result := (elTypePtr <> nil) and IsManaged(elTypePtr^);
end;
else
Result := False;
end;
end;
根据以上函数 你就可以得到只要是
tkDynArray, tkUString, tkWString, tkLString, tkInterface, tkVariant: 类型的都不需要初始化, 系统会自己建立初始化的过程, 后面2个 record和arrary的意思是说当record和静态数组的成员类型是以上tkDynArray, tkUString, tkWString, tkLString, tkInterface, tkVariant的某一个的话也是不用初始化的
[解决办法]说返回值最好初始化那是有根据的,我很少主观地回答问题,都是经验所得.
Function XXX : String;
它的实际格式是
procedure XXX(var Result : String);
如果不初始化,Result的值是没改变的,
Function XXX : String;
begin 什么都不干
end;
var
S : String;
begin
S := 'aaaa';
S := XXX;
ShowMessage(S); //结果是 aaaa,明白了吧
[解决办法]Delphi函数默认规范是register,不是pascal
函数返回值不一定要通过EAX传递,如果我要返回一个Double,你EAX能装得下?
即使是stdcall规范,浮点数返回值也是把返回值写入FPU中的ST(0)返回,这时EAX就无明确意义
光一个EAX处理不了的事情多着了
[解决办法]返回值类型为 string、动态数组等引用计数管理类型时,实际上是传入隐含参数进行处理。否则如果在栈中使用临时变量的话,由于在函数退出前会对栈中变量进行清理,从而无法正确管理引用计数,导致无法正确实现函数应有的功能。类似的情况,如返回值类型不是很简单的 record 的话,也是采用隐含参数的方式处理的,从而避免在退出函数后仍使用已经失效的栈空间、减少复制变量的开销,各大语言基本上都采用这种方式处理的。