我声明了一个常量数组:
const vc:array[0..7] of byte=($FF,$FF,0,0,0,0,$10,1);
后来我发现有这样的语句:
longword((@vc[2])^)=1234;
我发现vc的2,3,4,5个元素恰好是1234的值;
我对上面的语句产生疑问,为什么能改变常量vc的值?vc不是常量吗??常量不可以改值的啊,不是吗??
const vc:array[0..7] of byte=($FF,$FF,0,0,0,0,$10,1);
后来我发现有这样的语句:
longword((@vc[2])^)=1234;
我发现vc的2,3,4,5个元素恰好是1234的值;
我对上面的语句产生疑问,为什么能改变常量vc的值?vc不是常量吗??常量不可以改值的啊,不是吗??
解决方案 »
- 如何实现这样的告警窗口?
- 用access数据库,查询语句后,会出现参数不正确的的提示.大家求一下我,急
- DEIPHLk如何获取当前程序所在的完全路径!急!
- 【Delphi技术讨论群欢迎大家加入】
- 初学者的头痛问题
- 一般进入一些商用软件后主界面的背景动态图形菜单是怎么做的?
- 用H1:=findwindow(nil,'某网页标题')后,如何遍历该网页窗口内的所有控件,然后对各控件发送消息?
- 哪位高手愿意和我一起做个项目?当然报酬很丰厚
- 在MDI中我调用一个子窗体,怎样不出现那个动画显示的过程,谢谢!
- 超级菜问------怎么点击按钮出现一个txt文本~~~~~~
- 征求delphi调用外部程序或文件的各种方法
- 在DBGRID里根据单价和数量取金额
意思的内容是
@vc[2]取得vc第二个索引的地址
(@vc[2])^取得vc第二个索引的地址的内容
longword((@vc[2])^)把上述内容转换为longword类型
const
s = 'Hello';
begin
longword((@s[1])^) := 1234;
end;
Syntax {$J+} or {$J-}
{$WRITEABLECONST ON} or {$WRITEABLECONST OFF}
Default {$J-}
{$WRITEABLECONST OFF}
Scope Local
longword((@vc[2])^)=1234;
这一语句所改变的内容,不是vc的内容,甚至不是当前进程可寻址范围内的内容。(1楼 SmallHand 已经分析过了)象下面的代码,编译可以通过的(语法上是没问题),但是运行是会出错的(逻辑上是有问题的)。const
S = 'Hello';
var
P : PChar;
begin
p := @S[1];
P^ := 'A';
end;
LongWord占4个字节
longword((@vc[2])^)=1234;
这样的话 它就从地址@vc[2]依次向上赋值
然后把vc的2,3,4,5的值覆盖了呢?
不知道这样理解对不对?
不是这样理解。@vc[2],得到的是vc[2]所在的地址
(@vc[2])^,得到的是这个地址里的内容
longword((@vc[2])^),是把得到的内容看作一个地址,一个指向一个Longword类型数据的地址
longword((@vc[2])^) := 1234; 往这个地址中写入1234。
你所说的“这个地址”就是指
一个指向一个Longword类型数据的地址,是不是??
vc的实际意义转换为longword类型了??
你所说的“这个地址”就是指
一个指向一个Longword类型数据的地址,是不是??
vc的实际意义转换为longword类型了??
重新测试了一下,我前面的解释是错误的。longword((@vc[2])^) := 1234; 等价于 (PLongWord(@vc[2]))^ := 1234;写成后面一种,会更容易理解些。@vc[2], 得到的是vc[2]的地址(相当于无类型指针Pointer)。
PLongWord(@vc[2]),将地址转换为指向LongWord类型的指针。
(PLongWord(@vc[2]))^ := 1234; 将1234值以Longword写入到vc[2]所在地址处,会改变4个字节的内容。
const
I : Integer = 0;
begin
PInteger(@I)^ := 12345678;
ShowMessage(IntToStr(I));
end;
可以把常量看作是在编译时做了限制的变量
一方面Delphi的编译器允许将常量作为普通变量使用,
比如对有类型常量,可以通过$J或者Assignable typed constants选项,修改常量值
另一方面,可以用指针“跳过”编译器的语法检查,直接操作内存,从而达到修改常量值的目的