Delphi基础1

注:本文由方圆(上海)翻译兼创作,文中如有不当之处欢迎给作者来信共同探讨
(E-mail:ilovejhx@163.net)

■本文的产生得到“Macula工作组”的大力支持!在此表示感谢! 
一:Object Pascal语言中的“构造类型”有如下四种:
⒈数组
⒉集合
⒊记录
⒋文件

下面分别详细讲述:
⒈数组
  数组是由一些具有相同类型的元素按一定顺序组成的序列,数组中的每个元素可以通过数组名加一序号来
存取。

怎样定义数组类型

在Object Pascal中,要定义一个数组类型,其形式如下:

数组类型=Array [下标号…] of 基类型

您可以这样定义一个数组:

Type MyArray=array[1..100] of Real;

表示定义一个下标类型是整数,共有100个元素,元素下标从1到100,每一个元素类型是Real,类型标识符
是MyArray的数组类型。

Object Pascal允许下标的类型可以是整数、字符类型、布尔、枚举类型等,而元素的类型可以是任意的,

例如您可以一个下标为枚举类型的数组类型:

Type AX=(X,Y,Z);
       MyArray=array [AX] of Integer;

怎样定义数组变量

前面已经多次强调,类型跟变量是两个不同的概念,程序不能直接使用类型,而必须通过变量说明语句,定
义一个变量,例如:

Var array1,array2:MyArray;

上例中定义了两个数组变量array1和array2,它们的类型是MyArray(前面已经定义为数组类型)。
当然,您可以把数组类型的定义和数组变量的定义合二为一,这样能够简化程序,如下例:

Var array1:array['a'..'z'] of real;

要访问数组中的元素,可以用数组名加方括号,方括号内是元素的下标值,如array1[13]等。
注意:方括号内的下标值必须符合数组类型中下标类型的定义,其类型必须与下标类型一致,其值在下标取
值的范围内。另外下标可以是表达式。
使用Object Pascal 提供的标准函数Low和High可以提到一个数组的最小下标值和最大下标值。
另外,我们把数组中元素的类型作为整个数组的类型,数组能参加的运算就是其元素能参加运算。


多维数组

上面讲的是一维数组,所谓一维数组,从形式上讲,就是只有一个下标的数组,如x[1..2],y[3..100]。而多
维数组是指数组中的元素本身还是个数组, 其一般形式为:

type 数组标识符=array[下标类型1] of array [下标类型2] of 元素类型

您也可以把上述形式简写成下面的形式:

type 数组标识符=array[下标类型1,下标类型2] of 元素类型

现在您可以定义这么一个两维数组变量:

Var array1:array[1..5,1..8] of Integer;

表示数组有5个元素,每个元素又是由8个元素组成的数组。

您可以把多维数组看作是一个矩阵,其中下标1是行,下标2是列,这样要访问多维数组的元素,可以这么写:
array1[2,3]表示访问第2行第3列的元素。


零基准数组

所谓零基准数组,就是下标从0开始的数组,例如:

array[0..5] of Char

零基准数组主要用于存贮NULL字符结束的字符串,元素类型为Char的零基准数组与Pchar类型赋值兼容。
在调用Windows的API需要用到以NULL字符结束的字符串。


数组的整体赋值

假设有两个数组,array1和array2,其变量定义如下:

Var array1,array2:[1..10] of Char;

如果要把Array2中每一个元素的值相应赋值给array1中的元素,一般是使用For语句,例如:

For I:=1 to 10 do array1[I]:=array2[I];

Object Pascal 语言允许只用一个赋值语句,就能把array2中每一个元素的值相应赋值给array1中的元素,
程序这么写:

array1:=array2;

注意:数组间的整体赋值只适用于同一个数组类型的数组,即使两个数组看上去完全一样,也不能整体赋值,
例如:

Var array1,array2:array[1..10] of Integer;
Var array3:array[1..10] of integer;

上述三个数组中,array1:=array2是合法的,但是array1:=array3是不合法的。因为由于它们并不是同时声
明,因此会视为两种不同类型,而产生类型相容的问题。但是,通过一个FOR循环是可以在这二者之间赋值,
因此它们的基类是赋值相容的。

如果这样声明:

type MyArray=array [1..10] of integer;

然后:

Var array1,array2:MyArray;
Var array3:MyArray;

则此时三个数组全部是一个类型,所以可以全部的赋值相容,即可以整体赋值。


把数组作为过程或函数的形参

Object Pascal 允许把数组作为形参传递给过程或函数,并且允许把数组的类型定义和传递合二为一,程序
示例如下:

Procedure MyProc(var Array1:array[1..10] of Integer);
Begin
       {代码略}
End;

上述程序中,数组的定义和传递并在一起进行,并且Array1是作为变参传递的,意即在过程中可以改变这个
参数的值。另外,数组也可以作为函数的返回类型。


开放式数组

Object Pascal语言实现了开放式数组;所谓开放式数组,是指数组作为形参传递给过程或函数时,其长度是
不确定的,这样在调用这个过程或函数时,可以传递不同长度的数组为作实参。

开放式数组的定义和用法请参考下列示范程序;

{定义两个长度不同的数组变量}

Var X1:Array[1..10] of Real;
Var X2:Array[1..20] of Real;

{过程的定义,其形参是开放式数组}

Procedure MyProce(X:Array of Real);
Begin
{过程体略}
End;

Begin
       MyProc(X1);
       MyProc(X2);
End;

注意:实参的类型必须与形参数组的类型相同,  上述例子中都是Real类型。

在过程或函数体中,开放式数组的长度是随实参的长度变化的,并且总是零基准数组,也就是说它的下界总
是0,上界是实参中元素的个数减1,这样实参和形能中元素的序号可能是不参应的。如果实参仅仅是一个简
单变量,就把它看作是只有一个元素的数组。

因为开放式数组的元素个数是不确定的,您可以调用high函数获得当前的最大下标值。
注意:一般的数组可以作为整体赋值,但作为形参的开放式数组是不允许整体赋值的,您只能访问它的元素。

您可以在过程或函数中把开放式数组再作为参数传递给另外一个过程或函数。
开放式数组可以作为数值参数,常量参数或变量参数。有关这几种参数的说明可以参见过程与函数介绍
当开放式数组作为数值参数时,编译器在内存中开辟一块区域存放实参的拷贝,等过程或函数退出后再释放
这块区域,这样当实参是个很大的数组时,可能会发生栈溢出的问题。而开放式数组作为常量参数或变量参
数时,编译器传递的仅仅是一个地址,当然这也带来一个新的问题,如果在过程或函数中修改了参数的值,
实际上就是修改了实参自身。

如果开放式数组的类型是字符,您可以把一个字符串作为实参传递给它。
上述例子中,被传递的实参是一个已定义的数组变量,事实上Delphi还允许更直接的调用,只要把希望传递的
元素值用方括号括起来,元素与元素之间用逗号分开,程序示例如下:

MyProc([1,2,3,4]);
MyProc([1,2,3,4,5,6]);

这样,您不需要事先定义数组变量,并且对数组变量赋值。


动态数组

动态数组可以使你不必定义数组的长度,而在程序中动态地分配数组的存储空间,以便更灵活地使用数组的
特性。
定义一个动态数组的语法是这样:

类型名:array of 数据类型

这里可以看到,你不必声明数组的长度,而在程序中使用动态数组之前,你需要这样写:
SetLength(数组名,数组元素个数)
最需要注意的一点是,动态数组是一个零基准数组,第一个元素的下标应该为0。


⒉集合
集合本来是数学中的概念,Object Pascal中引入集合的概念,是为了把一组相关的对象作为一个整体来
参加运算,其中每一个对象称为集合的元素。事实上,理解了数学中的集合概念对理解Object pascal语言
中的集合类型是有帮助的。


集合类型的声明

声明一个集合类型的语法如下:

type 集合标识符=set of 基类

其中Set of 是保留字,基类型可以是任何有序类型如整型,布尔型,字符型,枚举型和子界型,但不能是
实型或其它构造类型。

程序示例如下:

Type Set1=set of 'A'..'Z';{基类型是子界型}
       Set2=set of Char;{基类型是字符型}
       Set3=set of (jan,Feb,Mar,Apr);{基类型是枚举型}

类型本身是不能参加运算的,还必须声明一个集合类型的变量,例如:

Var MySet:Set1;

为了简化程序,还可以把类型明和变量声明合二为一,例如:

Var MySet:set of 'A'..'Z';

这里需要特别提醒的是:构造类型和枚举类型入子界类型的区别在于,构造类型的变量是一个整体,而枚举
类型和子界的变量在同一时刻,其值是它的一个元素,所以,尽管枚举类型和子界类型的类型描述比较复杂,
但仍然
属于简单类型。

一个集合类型的值域实际上就是它的基类型的值域的一个子集,可能是空集,而一个集合类型的数据它的值
域又可以是集合类型值域的子集或空集。

注意:object Pascal规定,集合的元素不能超过256个,并且基类型的值域的上界和下界必须在0到255的范
围内,像下面的声明是错误的:

Type Set1=set of Integer;

因为集合中的元素的个数远远超过了256个。


集合类型常量的表示方法

集合常量用一组列在方括号内的元素来表示,例如:

Type Digits=set of 0..9;
       Letters=set of 'A'..'Z';
Const
       MyDigits:Digits=[1,3,5,7,9];
       MyLetters:Letters=['A','B','C','D','E','F'];

上例中,先声明了两个集合类型Digits和Letters,然后声明了两个集合常量,其中MyDigits是Digits类型
的常量,根据上面的规定,它的值域可以是Digits的值域的子集,比如0到9之间的奇数部分,而MyLetters是
Letters类型的常量,其值域是letters的头6个字符。

您也可以声明一个Digits类型的空集,例如:

Const MyDigits:Digits=[];

注意:有的集合常量看上去有元素,实际上是空集,例如:

Const MyLetters:Letters=['Z'..'A'];


集合能参加的运算

集合类型可以参加赋值运算、关系运算和逻辑运算。

(1)赋值运算

跟简单类型一样,声明了一个集合类型的变量以后,这个变量还没有一个明确的值,必须通过赋值语句给它赋
一个值,例如:

Var Set1,Set2:Set of 1..10;

上例中,虽然声明了两个集合变量,但并不是说变量Set1和Set2就表示1到10组成的集合了,还必须对它们赋
值,例如:

Set1:=[1,3,4,6,9];
Set2:=[1..3,5..8];

这样Set1就是由1、3、4、6、9组成的集合,Set2就是由1、2、2、5、6、7、8组成的集合。

对集合变量赋值要特别注意赋值的相容性。

(2)关系运算

对集合类型的运算,遵循数学中关于集合运算的规则,运算的结果为布尔值。

集合的关系运算无非是判断两个集合相互之间的关系,包括=(等于),<>(不等于),>=(大于等于)
和<=小于等于,首先我们定义几个规则:

所谓集合A等于集合B,是指集合A中的元素和集合B中的元素完全一样(不管元素的排列顺序),否则就是不等
于,例如:

[1,2,3,4]=[1,3,4,2]
[1,2,3,4]<>[7,8,9]

如果集合B的元素在集合A中都能找到,我们称为集合A大于等于集合B,反之我们称为集合B大于等于集合A,
例如:

[1,2,3,4]>=[1,2,3]

注意:Object Pascal中不能用>或<来对集合类型进行关系运算,另外由于集合不是有序类型,也就不能使
用Ord,Pred,Succ等函。

Object Pascal中还有个特殊的操作符In用于判断某个元素是否在集合内,有关细节请参考关系运算符。

(3)逻辑运算

逻辑运算又称为集合运算,参考关系运算符一章的详细描述。


⒊记录
记录类型跟C语言的结构非常相似,前面我们介绍的几种数据以及后面要介绍的文件类型,构成类型的元素必
须是同一种数据类型,然而在现实中,往往都需要把一些数据类型不同的数据集中在一起,并作为一个整体操
作,典型的例子是客户的登记表,一般是由下列信息组成:

客户编号(整型)
客户姓名(字符串型)
地址(字符串型)
是否已付过款(布尔型)

熟悉数据库的朋友可能会想到,Object Pascal的记录类型跟数据库的记录概念很相似,记录类型中的元素可
以理解为数据库中的字段,事实上,Object Pascal正是借用了数据库中的记录和字段的概念。


记录类型的声明

声明一个记录类型的语法是这样的:

type  标识符=Record
       字段1:变量类型;
       字段2:变量类型;
       …
       字段n:变量类型
end;

例如上述客户表可以这样声明

Type Customer=Record
       CustNum:Integer;
       Name:string;
       Addr:string;
       IfPay:Boolean;
end;

上例中声明了一个Customer类型的记录,记录由4个字段组成,其中每个字段都有其确定的标识符和数据类
型,它们在内存中分别占用不同的区域,我们把这几个字段称为记录的固定部分。

一个记录类型可以一个字段都没有。

类型本身是不能直接参加运算的,还必须声明记录类型的变量,例如:

Var Cust1,Cust2:Customer;

上例中声明了两个Customer类型的变量Cust1,Cust2 .

为了简化程序,您也可以把类型的声明和变量的声明合二为一,不过由于记录类型的类型描述比较,建议您
还是分开来声明。

注意:记录中的字段可以是任意类型,包括简单类型和构造类型,甚至是另一个记录类型。



如何访问记录中的字段

声明了一个记录类型的变量后,您就可以访问记录中的每一个字段了,在object Pascal中,访问记录中某个
字段的语法是这样的:记录变量名.字段名,例如:

Cust1.Name:='Smith';
Cust2.IfPay:=True;

注意:字段所以参加的运算以及赋值由该字段的数据类型确定。



记录的整体赋值

尽管记录中的每一个字段可以进行种种合法的运算,但记录作为一个整体,只能进行赋值运算,即把一个记录
整体赋给另一个类型一致的记录(参考类型一致及赋值相容),如:

Var Cust1,Cust2:Customer;
Cust1:=Cust2;

注意:赋值号右边的记录变量必须是有值的,所谓有值的是指记录的每个字段都已赋值。



记录与数组

记录与数组是两种即有区别又有联系的构造类型。

数组中的元素其类型是相同的,但元素的个数在一定范围内是可变的。而记录中的字段可以是不类型,但字段
的数量是固定的。

数组的元素是通过数组变量名加方括号和下标来访问的,而记录中的字段是通过记录变量名加一个小圆点和字
段名来访问的。

在描述复杂的总是时,往往把数组和记录结合起来使用,例如一个班级有若干名同学,每个同学的情况用一个
记录来描述,这就需要构造一个元素类型为记录的数组类型。

对,这就是数据库的表雏型。



With语句

上面提到,记录变量中的字段是通过记录变量名加一个小圆点和字段名来访问的,如果程序中有多处要
访问字段,每次都要写记录变量名,可以简化吗?

Object pascal提供了一个With语句,其语法是:

With 记录变量名 do…

do后面可以是单条语句(单条语句对WITH的意义不大),也可以是复合语句(要用BEGIN和END括起来),
在这些语句中,对字段的访问不需要再加记录变量名,程序示范如下:

With Cust1 Do
Begin
       CustNum:=2;
       Name:='Zhang';
       IfPay:=True;
       Addr:='This is a test';
End;

With 语句中还可以有With语句,这称为With嵌套,例如:

With Cust1 Do
       With Cust2 Do…

嵌套的WITH语句可以简写成下面的形式:

With Cust1,Cust2 Do…

不过,在使用嵌套简写形式时,要注意避免字段访问的二义性,例如下面的一个记录声明:

Type Rec=Record
       X:integer;
       Y:integer;
       AX:Record
              X:Real;
              Y:Real;
       end;
end;

Var MyRec:Rec;

上例中,声明了一个REC类型的记录,其中AX字段本身又是一个记录,并且AX的字段也叫做X和Y,不同的是
它们的类型跟REC中的X和Y的类型不同,这在Object Pascal中是允许的。

我们先不用简写形式写一段程序:

With MyRec Do
Begin
       X:=1;
       With AX Do
              X:=1.0;
End;

如果我们换成简写形式,就可能产生二义性:

With MyRec,AX Do
Begin
       X:=1;
       X:=1.0;
End;

上例中,X到底是Integer还是Real 就说不清了。

With 除了应用于类型之外,更多地应用在访问Delphi元件的特性和方法上。



记录的可变部分

前面讲的记录的字段,都有确定的标识符和数据类型,但在现实生活中,往往有这种情况,例如在一张履历
表上有这第一栏"参加工作时间",如果填表的人工作了,那就填上时间,如果待业,那就让它空白。

为了描述这样一张履历表,在声明记录类型时就要用到记录的可变部分,可变部分的语法是这样的:

Case 识别字段标识符:识别字段类型  Of
       常量1:(字段列表1);
       常量2:(字段列表2);
       …
       常量n:(字段列表N);

例如,我们用下面的记录类型来描述上述的履历表:

Type Rec=Record
       Name:=String;
       Age:integer;
       BirthPlace:String;
       Case IfWord:Boolean Of
              True : (WhenWork:string);
             Faslse : ()
End;

上例中我们用IFWORD来判断是否工作,如果是就是WHENWORK来描述工作时间,如果不是,就什么没有。

注意:类型声明中的常量彼此之间必须是互斥的,它们的类型必须是与识别字段类型相容的有序类型。另外可
变部分的字段的类型不能是长字符串类型和可变类型(Variant) ,同样也不能是包含长字符串或可变分量的构
造类型。



⒋文件
前面介绍的各种数据类型都只是在程序运行阶段有意义,一旦程序退出运行,这些数据不再存在,而文件类型
则是一种永久性的数据类型,因为文件类型的数据存在计算机的磁盘上。

其次,前面介绍的各种数据类型,它们的数据容量是有限的,即受数据类型本身在的局限,也受计算机内存的
限制,而文件类型的数据几乎没有容量的限制。


文件类型的声明

所谓文件,就是一些具有相同基类型的元素组成的线性序列,其声明的语法有两种形式:

Type 类型标识符=File;或
type 类型标识符=File of 基类型

前一种形式声明一个无基类型的文件类型,主要用于对磁盘上的文件进行低级的I/O。

后一种形式声明一个指定式类型的文件,基类型可以是任何简单类型和构造类型,但不能是文件类型或者包含文
件类型分量的构造类型,也不能是类类型和类
引用类型。

程序示例如下:

type
       Student=Record
       Name:String[15];
       Age:Integer;
end;

StudentFile=file of Student;
NumBerFile=File Of Integer;
TempFile=File;

上例中,首先声明了一个记录类型Student,然后声明了一个基类型是Student的文件类型StudentFile,一个基类
型为Integer的文件类型NumberFile,一个无基类型的文件类型TempFile。

跟其他类型一样,类型是不能直接在程序中使用的,还必须声明文件类型的变量,例如:

Var MyFile:StudentFile;

上例中,声明了一个StudentFile类型的变量MyFile。

为了简化程序,您还可以把类型声明和变量声明合二为一,例如:

Var MyFile:File Of Stduent;

Object Pascal中还有个预定义的文件类型Text,如果一个变量被声明为Text类型,表示这个文件是由ASCII字符组
成的文件。



文件类型的操作

文件类型是一种构造类型,也就是说,文件类型是个整体概念,而在编程过程中,往往需要对构成文件的元素进行
操作,这里介绍"文件缓冲区变量"的概念。

Object Pascal在声明了一个文件类型的变量后,自动给这个文件变量附上一个"文件缓冲区变量",该变量的类型跟
文件变量的基类型一致,例如:文件变量MyFile的"文件缓冲区变量"的类型就是记录类型,该变量写为MyFile^,所
以"文件缓冲区变量"也称为文件指针,只有文件指针当前所指的元素是可见的。

有了文件指针后,我们就可以访问文件中的每一个元素了,Object Pascal提供了一些标准的过程和函数用于对文件
指针进行操作诸如移动指针、读数据、写数据等。

声明了一个文件变量后,首先要用AssignFile给文件赋一个文件名,然后用Reset或ReWrite打开这个文件,这时候
文件指针指向文件的第一个元素,要移动文件指针,是使用seek过程,它可以把文件指针从当前位置移动N个元素。
要读或写当前元素,是使用Read和Write过程,对于ASCII文件来说,还可以使用ReadLn和WriteLn。

下面举例说明文件类型的操作:

Var F:File Of integer;
       I:Integer;
Begin
       AssignFile(F,'XXH.DAT');
       ReWrite(F);{建立并打开新文件}
       I:=0;
       While(I<10) Do Write(F,I);
       CloseFile(F);
End;

另外,object Pascal中的文件是随机,也就是说您可以对同一个文件同时读和写,不过要注意文件指针的变化。

文件操作好以后,一定要用CloseFile过程把文件关闭。

最后提醒,所有用于文件类型操作的过程和函数都在System单元中定义,切莫和sysUtils 单元的文件管理例程混淆,
后者主要是同文件句柄打交道。


二:Object Pascal语言中的“指针类型”
⒈指针类型的声明
指针类型的声明

指针类型在任何语言中都是比较难理解也是比较灵活的一种数据类型,指针通常是它所指的变量的内存地址。

声明指针类型的语法如下:

Type 指针类型标识符=^基类型;

程序示例如下:

Type
       BytePtr=^Byte;
       WordPtr=^Word;

上例中,声明了两个指针类型,一个是bytePtr,指向byte类型的数据,另一个是WordPtr,指向word类型的数据。

Object pascal不表示基类型一定要是在前面已声明的,也可以只是一个标识符,然后在同一个块内声明基类型。

声明了指针类型之后,就可以声明指针类型的变量,例如:

Var
       BP:BytePtr;
       WP:WordPtr;

为了简化程序,也可以把类型的声明和变量的声明合并在一起,例如:

Var BP:^Byte;

指针所指的基类型可以是简单类型,也可以是构造类型,例如:

Type Student=Record
       name:String;
       Age:Integer;
       Sex : (Man, Woman);
End;
Var StuPtr:^Student;

上例中,声明了一个指向记录类型Student的指针变量Studptr,以后程序中就可以用StuPtr^来表示记录类
型的Student的动态变量,要访问其中的Name字段,可以写成StuPtr^.Name。

这里介绍动态变量的概念,动态变量是这样构成的,用指针类型的变量标识符后加一个^符号,就构成指针
所指向的基类型的动态变量,像上例中的StuPtr^就是Stduent的动态变量。

(在Delphi程序中,很多程序都习惯这样声明

Type PStudent=^TStudent;
       TStudent=Record
       name:string;
       Age:Integer;
       Sex : (Man, Woman);
End;



⒉指针的操作
实际上前面已介绍了指针的简单用法,这里还要介绍几个用于指针操作的过程和操作符。

New是object pascal中的标准例程(System 单元声明),用于在应用程序的堆中为动态变量分配一块区域,
并把该区域的地址赋给指针变量,所分配区域的大小由指针所指的类型决定。如果应用程序的堆上已没有足
够的空间,将触发EOutOfMemory异常。

New过程的声明如下:

Procedure New(var P:Pointer);

其中P是一个指针变量,调用了New过程之后,程序就可以用p^作为指针所指类型的动态变量。

相应地,用当程序不再需要使用动态变量时,就应当调用标准例程Dispose删除New创建的动态变量,并释放
所分配的空间。

程序示例如下:

Type
       PListEntry=^TListEntry;
       TListEntry=Record
              Next:PListEntry;
              Text:string;
              count:Integer;
End;

Var
       List,P:PlistEntry;
Begin
       …
       New(P);
       P^.Next:=List;
       p^.Text:='Hello World';
       p^Count:=1;
       List:=P;
       Dispose(P);
       …
End;

上例中,首先声明了一个指针类型PListEntry,指向TListEntry类型,TListEntry类型的声明在下面,是一
个记录类型。然后声明了两个PListEntry类型的变量List和P。

Object Pascal中还有一个例程GetMem,其作用与New差不多,也是在应用程序的堆中为动态变量分配一块区
域,并把该区域的地址赋给指针变量,不同的是GetMem例程指定了要分配区域的大小,GetMem的声明如下:

Procedure GetMem(Var P:Pointer;Size:Integer);

其中P是指针变量,Size是字节数。

相应地,用GetMem创建的动态变量必须用FreeMem例程删除,并释放分配的空间。

Object Pascal语言中还有一个@操作符,用于获得操作数的地址,操作数可以是变量、过程、函数或类类型
中的方法,关于@操作符的详细介绍请参考操作
符。

Object Pascal中有一个特殊的保留字nil,这是个空指针常量,当指针的值为nil时,表示指针当前没有指
向任何动态变量。注意:您不能用值为nil的指针变
量去访问动态变量。

指针变量除了能被赋值以外,还能进行相等或不相等的比较,比较只限于类型兼容的指针变量之间。当两个
指针指向同一个对象时(不是同一个类型)指针才
相等。


⒊无类型指针
无类型的指针是指指针变量声明时没有有确地给出基类型,无类型的指针是这样声明的:

       Var Ptr:Pointer;

无类型指针的作用在于它可以指向任何类型,不过对于无类型的指针,您不能用类似ptr^的形式来引用它的
动态变量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值