Delphi学习第三天

时间:2022-08-07 20:54:05

The third day.战争才刚刚开始。

Fighting 是不变的主旋律。

今天周末,长沙的天时雨时晴,未外出,基本在实验室呆着。

接触的内容略多,慢慢做个总结。

先前不太明白Delphi和Pascal语言的关系,今天看书,有一句话算是解除了我的疑惑:Delphi是以Object Pascal语言为基础的可视化开发工具;

这关系就像eclipse和java一样。

Delphi开发的程序主要有3种:1、图形界面程序;2、控制台程序;3、服务器程序。

今天所有的编程练习都是控制台程序,所以在这里先对控制台程序做个解释。

控制台程序:指一些没有图形用户界面的32位Windows应用程序。和在DOS环境下运行的程序类似。截个图,方便弄懂,如下:

Delphi学习第三天

为了加深对控制台程序的理解,编一个小例子,如下:

program Project1;

{$APPTYPE CONSOLE} //编译器指令,它告诉编译器这个程序是一个控制台程序。

//uses SysUtils;
var
str:string;

begin
{ TODO -oUser -cConsole Main : Insert code here }
writeln('您好,这是一个示范程序,请输入一行文字:'); //输出
readln(str); //输入
writeln('您输入的是:',str);
readln; //锁定窗口,否则结果会很快消失
end.

运行结果如下图:

Delphi学习第三天


接下来,针对具体问题,编写一些控制台程序。

1、简单的指针操作(最头疼的也是最有用的。)

program Project2;   //指针实例工程

{$APPTYPE CONSOLE}

//uses SysUtils;
type
PInt=^Integer; //定义指针类型
var
I,K:Integer;
PI:PInt; //整型指针
P:Pointer;// 无类型指针,可以指向任何数据类型,但要注意类型的转换
begin
{ TODO -oUser -cConsole Main : Insert code here }
I:=3;
K:=5;
PI:=@K;//整型指针指向整型数据
writeln('K=',PI^);
P:=@I;
K:=Integer(P^);//无类型指针指向整型数据
writeln('K=',K);
PI:=P; //指针之间赋值
writeln('PI^:',PI^);
readln;
end.

可以先试着自己写结果,再和运行的进行核对,后面的例子可同样这么做。

实际结果如下:

K=5
K=3
PI^:3

知识补充:指针是一个表示内存地址的变量。“@”运算符放在变量前面,获取的是变量的地址,并可以将地址赋值为相同数据类型的指针。把“^”运算符放在数据类型的前面,可以定义该类型的一个指针类型;放在一个指针的后面,可以获得该指针所指地址空间的内容。

2、函数调用

调用前先进行函数声明,格式如下:

function  函数名(<形式参数表>):<类型>;

begin

     <语句>

end;

函数调用格式:   <函数名>(<实参表>)

具体例子:

program FuntionDemo;

{$APPTYPE CONSOLE}

uses
SysUtils;

function Total(a,b:Integer):Integer;
begin
Total:=a+b;
end;

var
a,b,c:Integer;
begin
{ TODO -oUser -cConsole Main : Insert code here }
try
writeln('请输入a值:');
readln(a);
writeln('请输入b值:');
readln(b);
c:=Total(a,b);
write('a和b的和为: ');
writeln(c);
readln;
except
writeln('输入内容有误!');
end;
end.

运行结果:

请输入a值:
6
请输入b值:
9
a和b的和为: 15

3、选择语句的使用(if 和case)

(1)if语句的使用

格式:

  • if<条件> then      

                  <语句>;

  • if<条件> then      

                  <语句>                                        //注意这里没有分号;

              else

                    <语句>;

例子:

program Project1;

{$APPTYPE CONSOLE}

uses
SysUtils;

var
date:Integer;
begin
{ TODO -oUser -cConsole Main : Insert code here }
writeln('输入Date: ');
readln(date);
if(date>=1)and(date<=10) then
writeln('上旬')
else if (date>=11)and(date<=20) then
writeln('中旬')
else if (date>=21)and(date<=31) then
writeln('中旬')
else
writeln('错误的日期');
readln;
end.
结果:

输入Date:
9
上旬

(2)Case的使用

格式:

case<表达式> of

     <数值>:<语句>;

else

      <语句>;

end;

实例:

program CaseDemo;

{$APPTYPE CONSOLE}

uses
SysUtils;

var
S:char;
begin
{ TODO -oUser -cConsole Main : Insert code here }
readln(S);
Case S of
'a'..'z','A'..'Z':writeln('字符');
'0'..'9':writeln('数字');
else
writeln('其他');
end;
readln;
end.

结果:

a
字符

4、循环语句的使用(repeat、while、for)

(1)repeat的使用

格式:   repeat

                   <语句>

              until<条件表达式>

例子:

program RepeatDemo;

{$APPTYPE CONSOLE}

uses
SysUtils;

var
I:Integer;
begin
{ TODO -oUser -cConsole Main : Insert code here }
I:=0;
repeat
I:=I+1;
writeln(IntToStr(I)); //整型转化为字符型
until I>6;
readln;
end.

(2)while的使用

格式:

while<条件表达式> do

begin

     <语句>

end;


例子:

program RepeatDemo;

{$APPTYPE CONSOLE}

uses
SysUtils;

var
I:Integer;
begin
{ TODO -oUser -cConsole Main : Insert code here }
I:=0;
while i<5 do
begin
writeln(IntToStr(I)); //整型转化为字符型
Inc(I); // 相当于I=I+1
end;
readln;
end.

(3)for的使用

格式:

for<条件表达式> do

begin

    <语句>

end;


例子:

program RepeatDemo;

{$APPTYPE CONSOLE}

uses
SysUtils;

var
I:Integer;
begin
{ TODO -oUser -cConsole Main : Insert code here }
I:=0;
for I:=5 downto 1 do
begin
writeln(IntToStr(I)); //整型转化为字符型
end;
readln;
end.

5、Break和Continue

通过两个实例对比出break和continue的区别。

实例1(break):

program RepeatDemo;

{$APPTYPE CONSOLE}

uses
SysUtils;

var
I:Integer;
begin
{ TODO -oUser -cConsole Main : Insert code here }
I:=0;
for I:=10 downto 1 do
begin

if I=6 then
break;
writeln(IntToStr(I)); //整型转化为字符型
end;
readln;
end.

结果:

10
9
8
7

实例2(Continue):

program RepeatDemo;

{$APPTYPE CONSOLE}

uses
SysUtils;

var
I:Integer;
begin
{ TODO -oUser -cConsole Main : Insert code here }
I:=0;
for I:=10 downto 1 do
begin
if I=6 then
continue;
writeln(IntToStr(I)); //整型转化为字符型
end;
readln;
end.

结果:

10
9
8
7
5
4
3
2
1

6、函数参数的使用

program Project1;

{$APPTYPE CONSOLE}

uses
SysUtils;//为了使用函数Format
function OutputNum(number:double;n:integer=5):Boolean;//n默认为5
var
Str:string; //浮点数显示输出的内容
begin
{ TODO -oUser -cConsole Main : Insert code here }
if n<=-1 then
begin
Result:=False;
Exit;
end
else
begin
Str:=Format('%*.*f',[10,n,number]);//设置显示的格式
Result:=True;
writeln(Str); //显示数据
end;
end;
begin
OutputNum(12.345);//n默认为5
OutputNum(123,3);//参数对数据类型进行升级
if OutputNum(123.456789,-3)=False then
writeln('输出失败。');
Readln;
end.

输出结果:

  12.34500
   123.000
输出失败。

知识补充:

解释这一句:Str:=Format('%*.*f',[10,n,number]); 
返回number变量格式化后的字符。整数位为10位,小数后为n为。

7、通过例子,加深对数值参数、变量参数和常量参数的理解
实例1:数值参数在运行过程中只改变其形参的值,不改变其实参的值
<pre name="code" class="delphi">program ShucanDemo1;

{$APPTYPE CONSOLE}

uses
SysUtils;

procedure Calculate(CalNo:Integer); //数值参数、占内存,注意此处
begin
CalNo:=CalNo*10;
end;
var
Number,a:Integer;
begin
{ TODO -oUser -cConsole Main : Insert code here }
readln(Number); //6
Calculate(Number);
writeln(IntToStr(Number)); //此处输出结果6
readln;
end.

实例2:
program ShucanDemo1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

procedure Calculate(Var CalNo:Integer);     //变量参数,不占内存注意此处
begin
  CalNo:=CalNo*10;
end;
var
  Number,a:Integer;
begin
  { TODO -oUser -cConsole Main : Insert code here }
  readln(Number); //6
  Calculate(Number);
  writeln(IntToStr(Number));   //此处输出结果60
  readln;
end.

 

结果分析:

Number进入Calculate函数后,会把Number实参拷贝给形参CalNo,在此过程中CalNo增大10倍,但并未传递出来,所以说Number值并未改变。形参
和实参占用不同的内存地址,在过程或函数被调用是,将实参的值复制到形参占用的内存中。因此,在跳出过程或函数后,形参和实参的数值是不同的,但实参的值并不发生变化。
在被调用的参数表中的形参前加上保留字Var,则CalNo不在内存中占据一个位置,而是指向实参Number。当一个实参被传递时,任何对形参所作的改变都会反映到实参中,这是因为两个参数指向同一个地址。

-----------------------------------------------------------------------

加入指针,理解参数传递的过程,实例如下:

program AllcanshuDemo;

{$APPTYPE CONSOLE}

uses
SysUtils;

type
PIngeger=^Integer; //定义指针类型

procedure P1(var N:Integer); //引用参数传递
begin
{ TODO -oUser -cConsole Main : Insert code here }
N:=N+1;
end;
procedure P2(N:Integer); //普通参数传递
begin
N:=N+2;
end;
procedure P3(PT:PInteger); //传递指针参数
begin
PT^:=PT^+3;
end;

var
i:Integer;
begin
i:=1;
P1(i); //将i的值增加1
writeln('i:',i);
P2(i); //希望将i加2,但没有实现
writeln('i:',i);
P3(@i);//将i的值加3
writeln('i:',i);
readln;
end.

结果如下:

i:2
i:2
i:5

结果分析:

  • i=1,经过P1的处理,N为变量参数,实参和形参都发生改变,故i的值变为2;
  • 过程P2中,N为数值参数,实参和形参占用不同内存,实参的值传给形参后,所得结果并没有返回,故实参的不改变,即i仍为2;
  • 过程P3中,指针指向i所在内存地址,所以操作是针对i进行的,故显示结果为4;

-----------------------------------------------------------------------------------------------------

补充一个概念:

有符号数和无符号数:针对二进制讲的。

有符号数用最高位作为符号位,“0”代表“+”,“1”代表“-”;其余数位用作数值位,代表数值。
比如:
0011 表示 +3;
1011 表示 -3。
无符号数全部二进制均代表数值,没有符号位。即第一个"0"或"1"不表示正负。
比如:
0011 表示 3;
1011 表示 11。


今天所学内容基本就这些,望共勉。

看到一本书出现的一句话:那些未能将我置之死地的事,会使我变得更有力。

机会往往伪装成困难,只有迎难而上,才能更接近成功。Fighting,next day ,go on .