函数里的const怎么理解?

agui 2003-11-17 02:49:17
比如函数原型
function MidStr(const AText: AnsiString; const AStart, ACount: Integer): AnsiString; overload;

const表意常量??
---------------------------------------------------
procedure TForm1.FormCreate(Sender: TObject);
var
x,y: string;
begin
x := 'asdf';
y := ' aaa ';
showmessage(midstr(x,1,2));
showmessage(trim(y));
end;
-----------------------------------------------------
测试如上通过,用的是变量。记得以前有用一些函数,要求参数必须为字符串常量,应该没有记错,还要是用类型转换函数。

请达人解释一下。
另外字符串变量转换为字符串常量用什么函数?(或者我的问法不太正确?)

...全文
94 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
ezlz 2003-11-21
  • 打赏
  • 举报
回复
常量参数


常量(const)参数就象局部的常量或只读变量。常量参数与值参数很相似。不同的是,在过程或函数主体中不能对常量参数赋值,也不能将其作为变量(var)参数传递给其他例程。(但是,当把一个对象引用作为常量参数传递时,仍然可以修改对象的属性。)

使用const允许编译器对结构化和串类型的参数进行代码优化。同时也对无意中将其作为引用传递给另一个例程提供了安全保障。

例如,下面是SysUtils单元中CompareStr函数的首部:

function CompareStr(const S1, S2: string): Integer;

因为S1和S2在CompareStr函数主体中没有被修改,所以它们可以被声明为常量参数。

值参数和变量参数


大多数参数是值参数(缺省)或变量(var)参数。值参数传递值(by value),变量参数传递引用(by reference)。要明白这一点,可以考虑下面的函数,

function DoubleByValue(X: Integer): Integer; // X是一个值参数

begin

X := X * 2;

Result := X;

end;

function DoubleByRef(var X: Integer): Integer; // X是一个变量参数

begin

X := X * 2;

Result := X;

end;

上面的函数返回相同的结果,但只有第二个函数 – DoubleByRef可以改变传递给其的变量的值。假设如下调用这两个函数:

var

I, J, V, W: Integer;

begin

I := 4;

V := 4;

J := DoubleByValue(I); //执行后 J = 8, I = 4

W := DoubleByRef(V); //执行后 W = 8, V = 8

end;

这些代码执行后,传递给DoubleByValue的变量 I 与最初赋给它的值相同。而传递给DoubleByRef的变量 V 则具有不同的值。

值参数的表现就象一个具有初始化值并传递到过程或函数调用中的局部变量。如果把一个变量作为值参数传递,那么过程或函数会创建一个副本;对值参数的改变只改变副本而不影响原始变量,并且当程序执行返回给调用者时这些副本被自动销毁。

另一方面,变量参数的表现就象一个指针副本。在函数或过程主体中对变量参数的改变将一致持续,直到程序执行返回调用者并且变量参数名自身已经离开其作用域。

即使相同的变量作为两个或更多的变量(var)参数被传递,也不会创建任何副本。例如,

procedure AddOne(var X, Y: Integer);

begin

X := X + 1;

Y := Y + 1;

end;

var I: Integer;

begin

I := 1;

AddOne(I, I);

end;

这些代码执行后,变量 I 的值为3。

如果一个例程的声明指定了一个变量(var)参数,那么当调用该例程时必需向其传递可赋值的表达式,如变量、类型常量(在 {$J+} 状态下)、解除参照的指针、域,或者被索引的变量。对于前一个例子(DoubleByValue和DoubleByRef),DoubleByRef(7)将导致错误,而DoubleByValue(7)是合法的。

索引和指针解除参照可以作为变量(var)参数传递。例如,DoubleByRef(MyArray[I])在例程执行之前将被求值一次。


值参数相当于例程内部的局部变量,其内存分配自动完成:调用例程时分配,返回调用者时释放。因此在例程内部对其改变仅仅作用于参数值的副本。如果传递的是一个常量或者需要求值的表达式,那么常量或表达式的值回被存储到新创建的局部变量中。

变量参数相当于变量指针的别名,在例程内部并不为其分配内存。对于例程中每一次引用,都会自动解释成为传递进来的原始实体(变量或其他可赋值的表达式)。

由此可见,如果要将长串作为参数传递,则应当尽可能定义为变量(var)参数,以减少内存开销和提高代码效率。当然,这只是针对值参数和变量(var)参数而言。有时还需要考虑将长串参数声明为输出(out)参数

HopeRemains 2003-11-21
  • 打赏
  • 举报
回复
up
agui 2003-11-18
  • 打赏
  • 举报
回复
那我的示例代码中并没有用常量也能通过呀,为什么?
光明山人 2003-11-18
  • 打赏
  • 举报
回复
访问能力的问题:
0、常量类型不能被更改;
1、变量可以修改,常量只能读取,所以变量的访问能力更高。变量可以传递给需要常量参数的函数,因为该参数需要的访问能力较低;
如以上例子。
3、常量不能传给可修改的参数,如用var, out声明的参数。下面的代码会导致编译错误:
const str1 = 'aaaaaaaaaaaaaa';

procedure a( var s: string );
begin
s := 'bbbbbbbbbb';
end;

procedure b;
begin
a( str1 ); // 编译错误!!!
end;

futureyre 2003-11-18
  • 打赏
  • 举报
回复
借问一下:
如果这样定义一个数组:const arr=array[0..2] of integer=(1,2,3);
那么这个数组的值还可以在程序中更改吗?
citytramper 2003-11-18
  • 打赏
  • 举报
回复

参数定义

func1(var param: integer;);
func2(param: integer);
func3(const param: integer);

这三种参数的区别:
1。第一种,param可以在函数内部改变,并返回给调用它的函数。
2。第二种,param可以在函数内部改变,但不返回给调用它的函数。这样param在函数内部也可以作为一个变量来用。
3。第三种,param在函数内部就是一个常量。
citytramper 2003-11-18
  • 打赏
  • 举报
回复
function MidStr(const AText: AnsiString; const AStart, ACount: Integer): AnsiString; overload;

const 只说说明这几个参数在这个函数中是不可改变的,不表示调用这个函数是要用常量,楼主可能搞混了。

要求参数必须为字符串常量

应该没有这样的,假如是这样,这个函数就没什么作用了
比如
showmsg(const msg: string); //用来弹出一个对话框,现实msg

要是调用 showmsg 必须用常量,那就要这么调用 showmsg('aaaa');

而是现实中,我们经常是要这么调用的

s:= 'aaaa';
showmsg(s);






asj 2003-11-18
  • 打赏
  • 举报
回复
一,这个参数的值在函数中不可改变,避免意外的错误
二,这个参数是传址而不是传值
三,对于string类型的参数,声明成const有助与编译器优化代码,提高程序效率
angelface 2003-11-18
  • 打赏
  • 举报
回复
我理解的是, 这是一个不可以被改变的值 , 也就是说, 当传递参数的时候, 传递的参数不会被接收这个参数的的函数所改变, 或是说意外的改变
tonylk 2003-11-18
  • 打赏
  • 举报
回复
哦,没仔细看你的程序,
函数参数const型。。。这可以避免你在该函数中改变该变量的值,如:
procedure TForm1.DoSth(const btn:TButton);
begin
btn:=Button2; //这样是非法的。
btn.Caption:='aaa';
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
DoSth(button1);
end;
tonylk 2003-11-17
  • 打赏
  • 举报
回复
就上常量呀,只不过这个常量只被这个函数用刀,那就没有必要写成全局的,不然反而难于查找,
又,之所以写成常量,不将它直接写道程序中,使为了程序便于维护,让维护者一目了然,这个数值时可以变动的,并且变动时也不需要顾虑改了这边,那边忘记的情况。
tiger19760407 2003-11-17
  • 打赏
  • 举报
回复
就是常量!
delphipan 2003-11-17
  • 打赏
  • 举报
回复
想知道
ezlz 2003-11-17
  • 打赏
  • 举报
回复
就相当于函数里的常量,不能被改变的。
sailer_shi 2003-11-17
  • 打赏
  • 举报
回复
const我的理解是这个参数不可以变化的,不知道对不对

828

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧