[Delphi]类型强制和转换

                                                              [Delphi]类型强制和转换    

Delphi是一种强类型转换的语言。在VC中,赋值符用″=″,例如x=1;到了Delphi赋值符就变成了″:=″,例如x:=1。 从赋值时用符号″:=″而不用″=″,就隐约可见Delphi对类型匹配要求之严,即赋值符右边的类型一定要和左边一致。用惯了VB或VC的程序员,初用Delphi,稍不留神,就会出现类型不匹配的错误。对初学者而言,类型转换也是学习Delphi的重点和难点,为此本文特对Delphi的类型转换做一总结,以供读者参考。

一、数的类型转换
  把表达式的类型从一种类型转化为另一种类型,结果值是把原始值截断或扩展,符号位保持不变。例如:
数的类型转换 举例
字符转换为整数 Integer('A')
整数转换为字符 Char(48)
整数转换为1个字节的逻辑型 Boolean(0)
整数转换为2个字节的逻辑型 WordBool(0)
整数转换为4个字节的逻辑型 LongBool(0)
整数转换为10进制pascal型字符串 caption:=intToStr(15)
整数转换为16进制pascal型4位字符串 caption:=intToHex(15,4)
地址转换为长整型数 Longint(@Buffer)

二、数的“分开”与“合成”
取32位longint型数的 高16位数为 hiword(longint_var)
低16位数为 loword(longint_var)
取16位数的 高8位数为 hibyte(integer_var)
低8位数为 lobyte(integer_var)
取32位地址的段选择符和偏移量 段选择符(高16位地址)为 selectorof(p)
偏移量(低16位地址)为 offsetof(p)
段选择符和偏移量合成为指针   Ptr(SEG, OFS: Word)相当于C语言的宏MK-FP(SEG,OFS)
例如在Windows中,Task DataBase结构0FAh偏移处包含'TD'标识,我们可以容易地编写如下代码观察到这个位于Windows内部的未公开的秘密:  

{函数ptr(seg,ofs)的用法,相当于C语言的MK-FP(seg,ofs)}
  var p:pbyte;ch:char;
  p:=ptr(getcurrentTask,$FA);
  ch:=char(p^); {结果为ch='T'}
  p:=ptr(getcurrentTask,$FA+1);
  ch:=char(p^);   {结果为ch='D'}

三、字符串string 字符数组与指向字
  符串的指针pchar的区别与联系
  这3者的基本概念相同,但有一些非常细微的差别,在编程时稍不注意就会出错,需高度重视。
  1、使用指向字符串的指针,如果不是以0结尾,运行时就会出现错误。为了避免这种错误,需要在字符串结尾人工加入0 即char(0),或用strpcopy函数在字符串结尾自动加0。
  例1: 指向字符串的指针,如果不是以0结尾,运行时会出现错误:  

{s[0]=3 s[1]='n' s[2]='e' s[3]='w'}
  var
  s:string;
       p:pchar;
  begin
  s:='new';
  label1.caption:=s; {new}
 label2.caption:=intTostr(integer(s[0]));{3是字符串的长度}
  p:=@s[1];{不是以0结尾,莫用pchar型指针}
   label3.caption:=strpas(p); {运行时出现错误}
  end;

  例2:在字符串结尾人工加入0即char(0),可使用指向字符串的指针。  

{s[0]=4 s[1]='n' s[2]='e' s[3]='w' s[4]=0;}
  {p-->'new'}
  var
       s:string;
       p:pchar;
  begin
  p:=@s[1];
  s:='new'+char(0); {以0结尾,可用pchar型指针}
  label1.caption:=strpas(p); {new}
  label2.caption:=s; {new}
     label3.caption:=intTostr(integer(s[0])); {4是字符串长度}
  end;

  例3: 用strpcopy函数赋值会在字符串s结尾自动加0。 

{s[0]=4 s[1]='n' s[2]='e' s[3]='w' s[4]=0;}
  {p-->'new'}
  var
       s:string; 
       p:pchar;
  begin
  p:=@s[1];
    strpcopy(p,'new');{strpcopy函数在字符串结尾自动加0}
  label1.caption:=strpas(p);{new}
     label2.caption:=s;{new}
  label3.caption:=intTostr(integer(s[0]));{4}
  end;

  2、下标为0的字符串标识符存放的是字符串长度,字符型数组基本相当于字符串,但不能存放字符串长度。字符串可以用s:='a string'的形式赋值,但是字符型数组a[ ]不可直接用a:='array'的形式赋值,用此种形式会出现类型不匹配错误,可选用strpcopy函数赋值。
  例4: 字符型数组s[ ]相当于字符串,但没有存放字符串长度的位置。 

{s[1]='n' s[2]='e' s[3]='w' s[4]=0;}
{p-->'new'}
var 
   s:array[1..10] of char; 
   p:pchar;
begin
   {s:='new'+char(0); error}{错误}
 p:=@s[1];
 {p:=@s; is not correct}
 strpcopy(p,'new');
 label1.caption:=strpas(p);{new}
 abel2.caption:=s;{new}
 {label3.caption:=intTostr(integer(s[0]));}{不会出现4, 下标超出错误}
end;

  例5:下标从0开始的字符数组s,s相当于@s[0]。 

{ s[0]='n' s[1]='e' s[2]='w' s[3]=0;}{p-->'new'}
var 
  s:array[1..10] of char; 
  p:pchar;
begin
  {s:='new'+char(0); error}{错误}
  p:=s;
  {p:=@s[0] is also correct}
  strpcopy(p,'new');
  label1.caption:=strpas(p);{new}
  label2.caption:=s;{new}
  label3.caption:=s[0];{n}
end;

  3、下标从0开始和从1开始的字符数组地址的表示方法也有细微不同:
  例6:下标从1开始的数组a 与下标从0开始的数组b 的比较。 

var
  a:array[1..10]of char;
  b:array[0..10]of char;
  {a:='1..10';}{type mismatch}
  {b:='0..10';}{type mismatch}
begin
  strpcopy( b, 'from 0 to 10'); {正确 因为b即是@b[0] }
  strpcopy(@b[0], 'from 0 to 10'); {正确 与上个表达式结果相同}
  strpcopy(@a[1], 'from 1 to 10'); {正确 }
  strpcopy( a, 'from 1 to 10'); {类型匹配错误 因为a即是@a[0]}
end;  

时间: 2024-09-23 09:53:32

[Delphi]类型强制和转换的相关文章

java虚拟机在进行类型强制转换的时候究竟做了什么

问题描述 java虚拟机在进行类型强制转换的时候究竟做了什么 打个比方 A a = new A(): B b = (B)a: 这两行代码究竟是怎样在Jvm中实现的? 解决方案 子类继承父类之后,在new子类的时候,实际上父类也被构造出来了,因此子类实际上包含着父类的完整信息,也就因此可以完成向上转型,. 至于具体怎么实现的,我查了一下好像是堆分配的过程,贴两个链接,不误导了.http://blog.csdn.net/anjayxc/article/details/6063210http://ww

类中的内存分配和指针类型强制转换问题

问题描述 类中的内存分配和指针类型强制转换问题 问题描述: template //element type class list { private: EleT data;//数据本身,即是需要的信息 list* prio;//the pointer of prior element list* next;//the pointer of next element list* last;//the last pointer of list int len;//the length of list

指针-数组名进行类型强制转换的问题

问题描述 数组名进行类型强制转换的问题 int main(void) { int a[4] = {1, 2, 3, 4}; int *ptr1=(int *)(&a+1); int *ptr2=(int *)((int)a+1); printf("%x, %x/n", ptr1[-1], *ptr2); return 0; } 为什么ptr2指向a[0]的第二个字节? 个人理解是数组名a是指向a[0]的指针,强制转换为int型变量,再加1,就相当于将原来所存放a[0]的地址当作

C++中Operator类型强制转换成员函数解析_C 语言

类型转换操作符(type conversion operator)是一种特殊的类成员函数,它定义将类类型值转变为其他类型值的转换.转换操作符在类定义体内声明,在保留字 operator 之后跟着转换的目标类型.转换函数又称类型强制转换成员函数,它是类中的一个非静态成员函数.它的定义格式如下: 复制代码 代码如下: class <类型说明符1> { public: operator <类型说明符2>(); - } 这个转换函数定义了由<类型说明符1>到<类型说明符2

C语言中自动隐式转换与类型强制转换实例分析_C 语言

本文通过一个C程序实例对C语言中自动隐式转换与类型强制转换的注意点进行深入分析,详情如下: 先看一个C程序: #include<stdlib.h> #include<stdio.h> #include<conio.h> double proc(int q){ int n; double sum,t;//本例的关键就在这几个变量的类型上 sum = 2.0; while(sum<=q){ t=sum; //sum = sum+(n+1)/n;//自动隐式转换 sum

Swift数字类型之间的转换

Swift数字类型之间的转换Swift是一种安全的语言,对于类型的检查非常严格,不同类型之间不能随便转换.一.整型之间的转换在C和Objective-C等其他语言中,整型之间有两种转换方法:从小范围数到大范围数转换是自动的:从大范围数到小范围数需要强制类型转换,有可能造成数据精度的丢失.而在Swift中这两种方法是行不通的,我们需要通过一些函数进行显式地转换,代码如下: let historyScore:UInt8 = 90 let englishScore:UInt16 = 130 let t

超过10位的String类型的整数转换成整型问题。

问题描述 超过10位的String类型的整数转换成整型问题. 请问下各位,我现在有个超过了10位的String类型的整数,想要把它转换成整型,然后用这个整型去跟其它的整型去作比较,请问下该怎么转换呢,Integer.parseInt()方法试了,要报java.lang.NumberFormatException异常,该怎么弄呢呢呢呢呢呢!!!! 解决方案 转成long怎么样,或者将其他整数转成string 解决方案二: Integer.parseInt()方法只用的一个参数,两个参数的不会用 解

Swift类型检查与转换

继承会发生在子类和父类中,如图所示,是一系列类的继承关系类图,Person是类层次结构中的根类,Student是Person的直接子类,Worker是Person的直接子类.这个继承关系类图的具体实现代码如下: class Person { var name : String var age : Int func description() -> String { return "\(name) 年龄是: \(age)" } convenience init () { self.

《从零开始学Swift》学习笔记(Day48)——类型检查与转换

原创文章,欢迎转载.转载请注明:关东升的博客   继承会发生在子类和父类之间,是一系列类的继承关系. 例如:Person是类层次结构中的根类,Student是Person的直接子类,Worker是Person的直接子类. 这个继承关系类的具体实现代码如下: class Person { var name: String var age: Int func description() -> String { return "\(name) 年龄是: \(age)" } conven