我声明了一个常量数组:
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不是常量吗??常量不可以改值的啊,不是吗??

解决方案 »

  1.   

    longword((@vc[2])^)=1234; 
    意思的内容是
    @vc[2]取得vc第二个索引的地址
    (@vc[2])^取得vc第二个索引的地址的内容
    longword((@vc[2])^)把上述内容转换为longword类型
      

  2.   

    你说的我懂,但你没说重点上,vc是常量const,常量能随便改值吗?
      

  3.   

    除了简单类型的常量,其他凡是可以获得常量内容存储地址的,楼主的这种写法都可以正常编译的,不过,并不一定能够正常运行。
    const
      s = 'Hello';
    begin
      longword((@s[1])^) := 1234;
    end;
      

  4.   

    Type Switch
    Syntax {$J+} or {$J-}
    {$WRITEABLECONST ON} or {$WRITEABLECONST OFF}
    Default {$J-}
    {$WRITEABLECONST OFF}
    Scope Local
      

  5.   


    longword((@vc[2])^)=1234;
    这一语句所改变的内容,不是vc的内容,甚至不是当前进程可寻址范围内的内容。(1楼 SmallHand 已经分析过了)象下面的代码,编译可以通过的(语法上是没问题),但是运行是会出错的(逻辑上是有问题的)。const
      S = 'Hello';
    var
      P : PChar;
    begin
      p := @S[1];
      P^ := 'A';
    end;
      

  6.   

    byte 占一个字节
    LongWord占4个字节
    longword((@vc[2])^)=1234; 
    这样的话 它就从地址@vc[2]依次向上赋值
    然后把vc的2,3,4,5的值覆盖了呢?
    不知道这样理解对不对?
      

  7.   


    不是这样理解。@vc[2],得到的是vc[2]所在的地址
    (@vc[2])^,得到的是这个地址里的内容
    longword((@vc[2])^),是把得到的内容看作一个地址,一个指向一个Longword类型数据的地址
    longword((@vc[2])^) := 1234; 往这个地址中写入1234。
      

  8.   

    longword((@vc[2])^) := 1234; 往这个地址中写入1234。 
    你所说的“这个地址”就是指
    一个指向一个Longword类型数据的地址,是不是??
    vc的实际意义转换为longword类型了??
      

  9.   

    longword((@vc[2])^) := 1234; 往这个地址中写入1234。 
    你所说的“这个地址”就是指
    一个指向一个Longword类型数据的地址,是不是??
    vc的实际意义转换为longword类型了??
      

  10.   


    重新测试了一下,我前面的解释是错误的。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个字节的内容。
      

  11.   

    用LZ的这种方法,的确可以改给这类常量的值。
    const
      I : Integer = 0;
    begin
      PInteger(@I)^ := 12345678;
      ShowMessage(IntToStr(I));
    end;
      

  12.   

    为什么可以改变?都定义是常量了,怎么还能改变?Why??
      

  13.   

    常量只是相对Delphi的语法规则而言,如果你一定要通过其它暴力方式改变这种约定规则,能耐你若何?
      

  14.   

    Delphi的常量是在编译器级别实现的,
    可以把常量看作是在编译时做了限制的变量
    一方面Delphi的编译器允许将常量作为普通变量使用,
    比如对有类型常量,可以通过$J或者Assignable typed constants选项,修改常量值
    另一方面,可以用指针“跳过”编译器的语法检查,直接操作内存,从而达到修改常量值的目的