深入看待常量的不同声明: const i=1 和 const i:integer=1的区别

=================本人学识水平有限======望请批评指正=========================== 

delphi中const i=1 和 const i:integer=1的区别

昨天我们qq群内几个常上线的灌客,接到一位群友的提问:

const i=1和
const i:integer=1 有什么区别?

我最开始以为,这没有什么分别,实际编程中也不见得有什么明显的区别。
因为,这么写法,外在程序实际运行结果都一样。
而事实上,从编译器角度分析和追踪,这两种写法还是有很大的区别的!
我们群的猴哥,最先搞起了试验。声明了两个这样的变量:

const i = $1;
const j: integer = 8;

procedure TForm2.Button1Click(Sender: TObject);
var s: string;
begin s:= inttostr(i);
 showmessage(s);
 s:=inttostr(j);
 showmessage(s);
end;

用调试跟踪器跟踪发现:

mov eax, $00000001---->这是const i=1;
mov exa [$0045b72c]---->这是const j:integer=8;

后改变了i的值,发现第一条 mov eax 后的内容始终也跟着变,也就是静态的保存了直接数值;
而后者则一直是一串地址,也就是真正的开辟了内存地址!

后来又将i=一个浮点数,跟踪结果:
Unit2.pas.33: s:= floattostr(i);
00457F0F 6805400000       push $00004005
00457F14 686666E6F6       push $f6e66666
00457F19 6866666666       push $66666666  ---------〉为了保存这个静态浮点数,将其压入了栈中。
00457F1E 8D45FC           lea eax,[ebp-$04]
00457F21 E86A1BFBFF       call FloatToStr
Unit2.pas.34: showmessage(s);
00457F26 8B45FC           mov eax,[ebp-$04]
00457F29 E84244FDFF       call ShowMessage
Unit2.pas.35: s:=inttostr(j);
00457F2E 8D55FC           lea edx,[ebp-$04]
00457F31 A12CB74500       mov eax,[$0045b72c]-----〉而后者仍然是存放一个地址!
00457F36 E8A506FBFF       call IntToStr
Unit2.pas.36: showmessage(s);
00457F3B 8B45FC           mov eax,[ebp-$04]
00457F3E E82D44FDFF       call ShowMessage
Unit2.pas.38: end;
00457F43 33C0             xor eax,eax

前一种写法编译器直接将值保存到寄存器,后一种是将常量地址保存到寄存器。

这也是为什么以下这样的程序写法可以更改后者常量的原因:

const a :integer=1;
pn:poniter;
pn:=@a;
integer(pn^):=5;  //最后a却等于了5

得出初步结论

const i=1 要比 const i: integer=1 安全一些,因为后者可以在程序运行期间直接修改内存地址的数值从而被破坏者利用。

 

program hydrogen_atom implicit none integer, parameter :: dp = kind(0.d0) ! 双精度浮点 real(dp), parameter :: L = 100.0_dp ! 坐标范围 real(dp), parameter :: d = 0.5_dp ! 步长 integer, parameter :: N = int(L/d - 1) ! 节点数 real(dp) :: dt1, dt2, x0 real(dp) :: xs(N) ! 节点位置 real(dp) :: H(N, N) ! 哈密顿矩阵 real(dp) :: Y(N, N) ! 本征向量 real(dp) :: E(N) ! 本征值 integer :: i, j, k, iter real(dp) :: Epai(N), temp logical :: sorted ! 初始化节点 x0 = 0.0_dp do i = 1, N x0 = x0 + d xs(i) = x0 end do ! 设置动能矩阵参数 dt1 = 1.0_dp / (d*d) dt2 = -0.5_dp / (d*d) ! 初始化哈密顿矩阵 H = 0.0_dp do i = 1, N ! 对角元素 (动能 + 势能) H(i, i) = dt1 - 1.0_dp / xs(i) ! 次对角元素 (仅动能) if (i < N) then H(i, i+1) = dt2 H(i+1, i) = dt2 end if end do ! 假设 H 是 n×n 的哈密顿矩阵 integer :: k1, j1, n1 n1 = size(H, 1) ! 获取矩阵维度 print *, "哈密顿矩阵 H:" do k1 = 1, n1 do j1 = 1, n1 write(*, '(F12.6, 2X)', advance='no') H(k1, j1) ! 每元素占12字符宽,保留6位小数 end do print * ! 换行 end do更改后报错PROGRAMadd_numbers.f90:41:25: 41 | integer :: k1, j1, n1 | 1 Error: Unexpected data declaration statement at (1) PROGRAMadd_numbers.f90:46:12: 46 | do j1 = 1, n1 | 1~ Error: Symbol 'j1' at (1) has no IMPLICIT type; did you mean 'j'? PROGRAMadd_numbers.f90:45:8: 45 | do k1 = 1, n1 | 1~ Error: Symbol 'k1' at (1) has no IMPLICIT type; did you mean 'k'? PROGRAMadd_numbers.f90:42:5: 42 | n1 = size(H, 1) ! 鑾峰彇鐭╅樀缁村害 | 1~ Error: Symbol 'n1' at (1) has no IMPLICIT type; did you mean 'n'? PS D:\win_fortran>
06-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安优小青和他的程序生活

我的文档对您有很大的帮助吗?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值