活跃一下D版的气氛,出个趣味只是题。下面的代码中,定义了一个记录类型,定义了2个同名的方法(同不同名无所谓),v1和v2的x字段都初始化为10,分别调用2个方法后。提问:
1、v1.x与v2.x的值分别为多少?(要求不要在机上测试)
2、加入从记录定义中去掉y字段,v1.x与v2.x的值又分别为多少?(要求不要在机上测试)
3、为什么会是这样的结果?希望大家讨论。
type
TTest = record
x: Integer;
y: Integer;
end;procedure IncX(var v: TTest); overload;
begin
Inc(v.x);
end;function IncX: TTest; overload;
begin
Inc(Result.x);
end;var
v1, v2: TTest;
begin
v1.x := 10;
v2.x := 10;
v1 := IncX;
IncX(v2);
end;
1、v1.x与v2.x的值分别为多少?(要求不要在机上测试)
2、加入从记录定义中去掉y字段,v1.x与v2.x的值又分别为多少?(要求不要在机上测试)
3、为什么会是这样的结果?希望大家讨论。
type
TTest = record
x: Integer;
y: Integer;
end;procedure IncX(var v: TTest); overload;
begin
Inc(v.x);
end;function IncX: TTest; overload;
begin
Inc(Result.x);
end;var
v1, v2: TTest;
begin
v1.x := 10;
v2.x := 10;
v1 := IncX;
IncX(v2);
end;
解决方案 »
- 请教:如何判断软件已升级?用FTP下一个txt文件,读一下吗?如何在线升级呢?
- 问一关于网页表格写入EXCEL的问题
- 请教各位高手,在程序中如何实现以下功能,给定一个字符串,程序会调用以该字符串为函数名称的函数?
- 寻找链表结构
- 初学者高分提问:在一个panel里,有 6 个edit框输入的数据,分别代表3个时间值和3个电压值。如何根据着6个数据在一个坐标里画出曲线??
- 哪位大哥有dsgniftf.pas或DsgnIntf.dcu发一件。
- 如何实现通过SQL语句,查询一个表中的某个字段的类型和长度。
- 关系动态建立FRAME时的问题
- 怎样读取Delphi里按钮控件(TButton)的所有属性?
- 今日有感之刚上大学
- 考考Delphi的基础
- 求助!远程数据操作问题。
v2.x 11不知道对不对
2 v1 结果随机 v2 结果11v1是局部变量的时候是直接把v1当result的
如果改成全局变量result是栈中的另一块地址 返回后再赋值给v1 这样的话就得到随机的值了当v1只有一个integer的字段的时候 好像就没有特殊处理
这样的赋值?
没见过
这样的语句不懂,
偶是delphi新手
v1.x因为incX()是对一个未初始化的result进行inc,结果是不确定的
一般未初始化就是0,看编译器是统一更新为0还是不做处理
incX()这样的函数应该绝对不允许出现
一般来说,编译系统再返回值时应该会在堆栈上建立临时变量,Pascal更应该如此。
在实际使用中搞这个有点无聊。
哎,被发哥忽悠了猜错了,Delphi对结构体的处理方式是一样的,都是在栈上面创建临时变量,赋值后再Copy。连续运行两次就知道了。
v1 := IncX;
v1 := IncX;唯一一点不同是有y的时候第一次Result的初始化的值均为0,不知道这是和编译器有关的,还是说,其中有什么玄机?
T1 = packed record
a: Byte;
b: Word;
end;T2 = record
x: array[1..3]of Byte;
end;T3 = record
DynArr: array of Integer;
end;T4 = record
S: string;
end;
它们可都是32位及32位以下的delphi传参数的细节多着呢,传 procedure/function of object 类型的参数还有bug,但这些东西只是编译器的实现,跟基础一点关系都没有。
DynArr: array of Integer;
end; T4 = record
S: string;
end;
这两个的字段在Delphi内部本身就属于指针
x: array[1..3]of Byte;
end;
这个为什么是传递指针而不是靠eax返回?表面看来,这个数据却是不超过32位,但实际上数组类型在Delphi是另外处理的,它的第一个元素前面还有隐含的计数字段,这和string类型有些相似,所以实际上是大于32位的
我当然会测了,只是不知道别人会不会。比如这样的代码
type
T1 = packed record
a : Byte;
b : Word;
end;
function foo: T1;
begin
end;
var t : t1;
begin
t := foo;
~~~~~~~~
我看到反汇编成了
mov eax, esp
call foo
当然就知道是传指针了而不是eax返回了,不知道您测过没?
让人说啥好吧……静态数组没有数组长度和引用计数信息,Low/High/Length对静态数组来说都是编译期运算符。而且这个也很好测啊,SizeOf(T2)明明就是3的,不知道隐含计数字段还能放哪
x: array[1..3]of Byte;
end;
这个确实是我张冠李戴搞错了,搞成动态数组了,谢谢指正,它是靠eax返回的,而 T1 = packed record
a : Byte;
b : Word;
end;
是eax返回没错的,不知你是怎么测试的
mov eax, esp
call foo
还能坚持说是靠eax返回,那我也没啥好说的了
结贴,以后再也不搞此类游戏把戏了。
呵呵,我见C/C++版经常有此类趣味贴,一时兴起,发了这么个贴,没想到D版这么无趣,也给我自己带来没趣。
Pascal快忘光了
========================================
http://bbs.dameng.com
========================================
Inc(Result.x);相当于引用了一个没初始化的变量,其值应该不确定,以前遇到过。
IncX(v2); 这个传进来的是地址,函数内的操作将影响到函数外的变量。
第二种方法本人经常用到:
procedure ReagSrvInfo(var v:TSrvInfo);
var
IniFile:TiniFile;
CrFileName:string;
begin
CrFileName:=GetExePath+IniFileName;
try
IniFile:=TiniFile.Create(CrFileName);
v.IP:=IniFile.ReadString('SqlSrvInfo','IP','');
try
v.DBName:=IniFile.ReadString('SqlSrvInfo','DBName','');
if v.DBName<>'' then
v.DBName:=Decrypt(v.DBName,MyKey);
v.UserName:=IniFile.ReadString('SqlSrvInfo','UserName','');
if v.UserName<>'' then
v.UserName:=Decrypt(v.UserName,MyKey);
v.UserPWD:=IniFile.ReadString('SqlSrvInfo','UserPWD','');
if v.UserPWD<>'' then
v.UserPWD:=Decrypt(v.UserPWD,MyKey);
except
v.UserName:='';
v.UserPWD:='';
end;
finally
FreeAndNil(IniFile);
end;
end;