delphi程序结构是怎样的

delphi程序结构是怎样的,第1张

dpr

为工程文件

dfm

为窗体文件

pas

为单元文件

cfg

配置文件

dof

为项目选项文件(一般没用)

dcu

compiled

units文件

,编译后的单元文件

res

资源文件

ddp

文件就是Delphi

Diagram

Portfolio简写,是用来保存Code

Editor中的Diagram信息的

一般一个项目要考个别人,只需要

dpr,dfm,pas文件即可,如果有cfg,res也一块考(后两个文件很少用到)

Delphi单元文件

1库单元文件头:其中声明了库单元的名字

2Interface部分:

由保留字interface开始,结束于保留字implementation,它用来声明引用的单元,常量,数据类型,变量,过程和函数在Interface部分声明的变量,常量,数据类型,过程,函数都可以供外部引用,对整个程序而言是共有的也就是说,对于所有引用该单元的单元来说,这些声明都是可见和可访问的

在Interface部分,只需写出过程和函数的首部,具体的定义是在下面的implementation部分给出的

Interface部分又可分为多个可选部分,分别为单元引入部分(uses),常量说明部分,类型说明部分,变量说明部分,过程和函数声明部分

3Implementation部分:

Implementation部分分为两部分一部分是声明部分,包括单元引用,常量,类型,变量,过程和函数的声明,这一点和Interface部分相似

区别有两点:

(1):在Implementation部分声明的只对本单元是公共的,可见的,其他单元即使引用了该单元,也不能访问它们

(2):在Implementation部分声明的过程和函数,不需要遵循先声明后定义的规则,而可以直接写出过程和函数的定义另一部分是在Interface部分声明的过程和函数的定义

4Initialization部分:

用于初始化该库单元,此处的代码最先执行如果多个库单元中包含Initialization部分,那么它们的执行顺序就和Program的uses部分引用单元的出现顺序是一致的

5Finalization部分:

通常用于释放Initialization部分分配的资源如果多个库单元中包含Finalization部分,其执行顺序和Initialization部分正好相反

首先给你说明使用extern一次只能包含一个变量或者函数,如果你的另一个文件中有N多个变量或函数的话,你要依次使用extern逐个包含进来,如果这样的话你会不会觉得太麻烦,而且这样程序的可读性也降低了。因此你要把整个文件的内容引入到当前文件中,最好使用#include把头文件包含进来。下面就给你介绍一个extern关键字和把程序写在多个文件中的内容吧。

链接性:链接性为外部的名称可在文件之间共享,链接性为内部的名称只能由一个文件中的函数共享。局部变量不存在共享,也就是说局部变量不存在链接性问题。也就是说链接性为外部的变量可以使用extern关见字把他包含进来由其他文件使用,即和其他文件共享同一个变量;而链接性为内部的变量则不能在其他文件之中使用,如果每个文件中都有一个相同的这个变量,则彼此之间是相互独立的,不存在共享性。比如文件1有一个链接性为外部的变量int e=3;则文件2可以使用extern int e;把e包含进来,两个文件使用的是同一个变量e,文件2对e的修改将影响到文件1中的e的变量。而如果文件1和文件2中的两个变量e的链接性是内部的话,则两个变量将是各自独立的变量,对各自变量的修改不影响另一个文件中的同名变量。

1、对于大型程序一般将一个程序写在多个文件中:一般把程序分成三部分,头文件和两个源文件,其中头文件包含类的声明或函数的声明。其中一个源文件就包含这些类和函数的定义,而另一个源文件则是主程序。

2、将程序放在多个文件中的好处是比如有多个这样的程序需要在头文件中声明的这些函数,则只需在该程序中把这些头文件包含进来。头文件和包含头文件定义的文件就组成了一个软件包,可用于各种程序中。

3、通常不应将函数声明和变量声明放在头文件中。因为如果头文件包含一个函数定义,然后在同一程序的其他两个文件中包含了这个头文件,则同一程序中将包含同一函数的两个定义,除非是内联函数,否则就将出错。

4、头文件一般包含:函数原型,使用#define或const定义的符号常量,结构声明,类声明,模板声明,内联函数。

5、包含头文件时使用#include关见字,在#include后面文件名最好使用双引号不要使用尖括号,比如#include “eeeh”使用双引号和尖括号的区别是使用尖括号时编译器将首先在标准头文件中查找,而使用双引号则首先在当前工作目录或源代码目录查找。

6、不能在同一个文件中包含头文件两次。一般不会犯这种错误,但是当使用包含了一个头文件的文件时有可能在不知情的情况下犯这个错误。

7、使用预处理器指令#ifndef来解决上面的问题。语名#ifndef hyong…#endi表示仅当以前没有使用预处理器编译指令#define定义的名称hyong时才处理#ifndef…#endif之间的语句。#define通常创建符号常量,比如#define H 3;把常量3定义为名字H,但只使用#define就能创建名称,比如#define H;就创建了一个名称H。完整的#ifndef…#endif语句的例子如下:#ifndef HY #define HY void g(); #endif;该语句的执行顺序为:编译器首先遇到该头文件时,名称HY没有被定义,这时编译器就将查看#ifndef…#endif之间的内容,并读取到#define HY这一行。如果在同一文件中遇到包含该头文件的代码时,编译器就知道HY这个名字已经被#define定义了,从而跳过#ifndef…#endif之间的内容。注意这种方法并不能防止头文件被包含两次,而只是让他忽略除第一次包含之外的所有内容。

//将程序放在多个文件中的示例:

//头文件hyongh的内容如下

#ifndef HY //一般在头文件都都使用这种格式以防止头文件在同一文件中被包含两次。语名#ifndef hyong…#endi表示仅当以前没有使用预处理器编译指令#define定义的名称hyong时才处理#ifndef…#endif之间的语句。

#define HY //在这里用define定义一个名字HY,以便在下次访问到该头文件时,使该名字已经被定义,从而让程序跳过#ifndef…#endif间的语句。

void g(); //在头文件中声明一个函数g();

#endif

//在头文件hyh中定义函数,一般不允许这样做

#include <iostream>

using namespace std;

void f(){cout<<"f()"<<endl;}

//定义头文件中声明的函数的源文件hyongcpp的内容如下

#include "stdafxh" //注意:在VC++中所有的源文件中都要包含这条语句。

#include "hyongh" //将头文件hyongh包含进来,这里使用双引号,而不是引号,以便能更快地检查到该头文件中定义的名字

#include “hyh” //

#include <iostream>

using namespace std;

void g(){cout<<"g()"<<endl;} //定义头文件hyongh中声明的函数g()

//主程序源文件ffcpp的内容如下

#include "stdafxh"

#include<iostream>

#include "hyongh" //注意,主程序和hyongcpp的文件中都包含了这个头文件。

//#include “hyh” //错误,在同一程序中的另一个文件hyongcpp中已包含过该头文件,因为f函数是在hyh这个头文件中定义的,在这里再包含头文件hyh就会出现在同一程序中定义了两个f()函数的错误。

using namespace std;

int main() {g(); cout<<"p"<<endl; } //f();//对f函数的调用错误,因为f函数在头文件hyh中定义,并且不能在主程序文件中再包含头文件hyh,在这里就会出现f是未标识的标识符的错误。

lib文件是静态链接库文件,一般只对外部提供接口函数,是事先已经生成好的。甚至有的lib文件只是一个引导文件,比如C语言中一些标准库函数,真正的接口实现会放在动态库dll文件中,因此说lib文件是不能调用外部函数结构体的。

呵呵,只是我个人的经验总结。自己学着做个函数库就大概清楚了。

写个头文件 ch 声明 一个结构体类型

struct STU

{

int x;

int y;

};

定义结构体变量s的文件bc

#include "ch"

struct STU s; / 不加extern ,默认认为extern /

ac 调用bc里定义的全局变量s

#include <stdioh>

#include "ch" / struct STU这个类型的定义(或者说声明)在这个头文件里 /

extern struct STU s;/ 声明它是外部的类型是struct STU /

int main()

{

printf("sx+sy = %d+%d = %d\n",sx,sy,sx+sy);/调用了/

}

结构体成员在引用时,

如果结构体是变量,

可以使用来引用(点引用符号),

如果是指针,必须使用->来引用。

当然如果不是C而是C++的话可能不这么严格了。

适用于应用程序使用的软件设计和构架总结软件架构一般定义为应用程序的结构。在定义这些结构的时候,软件架构师的目标就是使用不同级别的抽象,通过根据关注点把功能进行分割来最小化复杂度。我们会从最高层的抽象以及不同的关注点开始研究。因为设计的过程中需要不断深入这些层次、扩展关注点直到定义了结构为止。内容目标概览概要步骤第一步——选择我们的分层策略第二步——定义层之间的接口第三步——选择我们的部署策略第四步——选择通讯协议其它资源目标找出并选择分层策略定义层之间的接口找出并选择部署策略选择合适的通讯协议概览在开始应用程序设计的时候,我们第一个任务就是关注最高层次的抽象并且开始把功能分组到不同的层中。然后,我们需要根据我们所设计的应用程序的类型为每一层定义公共的接口。在定义了层和接口之后我们就需要决定应用程序是如何部署的。最后,最后一个步骤包含选择会用于在应用程序不同逻辑层和物理层之间通讯的协议。概要步骤第一步——选择我们的分层策略第二步——定义层之间的接口第三步——选择我们的部署策略第四步——选择通讯协议第一步——选择我们的分层策略层表示组件按照不同关注点的逻辑分组。例如,业务逻辑表示应该分组到某层的一个关注点。这可能是应用程序最初设计中最重要的一个抉择。然而,有很多种方式可以把功能进行分层。在完成了本步骤之后你应该能理解如何来组织应用程序的分层结构。下图演示了用于大多数业务应用程序设计的主要层。在这个示例中,功能按照表现逻辑、服务逻辑、业务逻辑和数据访问逻辑进行分组。如果服务没有公开的话,就不需要服务层,那么我们应该只有表现、业务和数据访问层。 这只是一个示例,不是对应用程序进行分层的唯一方式。然而,一般来说分层在软件设计中很常见。底层的 *** 作系统设计使用了RING的方式,RING0(内核)表示最低的层,它可以直接访问诸如CPU和内存等硬件资源。设备驱动作为外层RING通过RING0提供的接口和硬件进行交互。应用程序代码包含在最外部的RING中,它们通过设备驱动来和硬件交互。除了层,我们还有一些功能会跨越层,它们通常称作横切。此类功能包含诸如日志以及异常管理等。有不同的方式来处理这种功能,比如公共类库、使用元数据直接在编译输出中插入横切代码的面向方面编程(AOP)等。在为应用程序选择分层策略的时候,如下事项是我们需要考虑的关键点:决定我们是否需要层选择我们需要的层决定我们是否需要合并层决定层之间交互的规则决定我们是否需要层在大多数情况下总是需要把功能进行分层。然而,在有些特例下不需要。例如,如果我们构建一个非常小的应用程序,可能就会考虑在用户界面事件处理程序中实现表现、业务逻辑以及数据访问功能。此外,一些软件工程师会认为跨层边界或增加层带来的开销会对性能有负面影响。 是否使用分层的决定说白了就是性能对可维护性。虽然不使用分层可以提升性能,因为所有的东西都紧密耦合在了一起。但是,这种耦合会严重影响应用程序的扩展和维护能力。说实话,对可扩展性和可维护性的影响远比获得的那一点性能的提升重大。不管怎么始终应该考虑分层,我们的目标其实是决定应用程序需要怎么样合适的分层。选择我们需要的层有几种不同的方式来把功能进行分层。例如一种分层的方式就是表现、服务和数据访问。许多关注业务领域的面向对象设计使用又一种不同的分层策略,最底层用于基础结构代码,提供类似数据访问的支持。上面一层就是领域层,用于包含业务领域对象,最顶层包含应用程序代码。对于使用微软NET Framework开发的大多数业务应用程序来说,按照表现、服务、业务以及数据访问对功能进行分组是不错的选择。下面描述了每一层中的一些组件,以及什么时候不需要这层。表现-这层包含用于处理用户接口请求以及呈现用户接口输出的组件。如果我们的应用程序没有用户接口的话就不需要表现层。服务-这层包含用于处理服务请求的组件。例如,对于使用Windows Communication Foundation (WCF)的应用程序,我们就会找到定义契约的组件、用于实现接口以及提供在实现类和外部契约类之间提供转换支持的组件。如果我们的应用程序不提供服务,则不需要在设计中包含服务层。Business业务-这层包含用于处理表现或服务层请求的组件。在这层中的组件包括业务处理、业务实体以及业务工作流。在一些情况下,我们不需要有任何的业务层并且只需要从数据源获取数据,也就是说这种情况下不需要业务层。数据访问-这层包含用于管理和数据源交互的组件。例如,使用ADONET的话在数据访问层中就会有连接和命令组件。如果我们的应用程序不使用外部数据的话那么我们就不需要实现数据访问层。决定我们是否需要合并层例如,应用程序具有很有限的业务规则并且主要关注验证的话可以在一层中实现业务和表现逻辑。在以下情况考虑合并层: 如果我们的业务规则很有限,在一层中实现业务和表现逻辑是合理的。如果我们的应用程序从服务获取数据并且显示数据,可以直接为表现层添加服务引用并且直接使用服务数据。这样的话就可以合并数据访问和表现。 如果数据访问服务直接访问数据库中的表或视图的话可以考虑在服务层中实现数据访问功能。还有一些适用于合并分层的示例。然而,基本准则是我们总是应该把功能分层。在一些情况下,层只不过是一层调用并且没有提供什么功能。然而,如果把功能进行分离的话我们就可以在影响很小或没有影响的情况下扩展其功能。决定层之间的交互规则分层策略带来的一个问题是我们需要定义层之间如何交互的规则。指定这样的一种交互规则的主要原因是最小化依赖以及消除循环引用。例如,如果两个层依赖另外那个层的组件就很可能带来循环依赖。最常见的准则是只允许层之间的单向交互。从上到下的交互–比较高的层可以和其下层进行交互,但是低层不可以和其上的层进行交互。在设计中总是应该强制这样的准则来避免层之间的循环依赖。紧密交互 –每一层只能直接和其下的层进行交互。这个准则可以强制严格的关注分离,应该每一层只知道其直接下属层。这个准则的好处是对某一层的修改只会影响其直接上层。松散交互–高层可以跳过一些层直接和底层进行交互。这可以增加性能,但是也会增加依赖。换句话说,对底层的修改可能会影响其上的多个层。考虑使用紧密交互规则:如果我们设计的应用程序会不断修改来增加新的功能,并且我们希望最小化改变的影响。如果我们设计的应用程序可能会跨物理层进行分布。考虑使用松散交互规则:如果我们设计的应用程序肯定不会跨物理层进行分布。例如是安装在客户机上的独立富客户端应用程序。如果我们设计一个很小的应用程序,影响多层的改动工作量不大。检查点在结束本步骤之前,你应该可以回答如下问题:你是否找到了应用程序需要的功能并且把功能分层?你是否定义了层之间如何交互的规则?第二步——定义层之间的接口对于为层定义接口,最主要的原则是在层之间使用松散耦合。意思就是层不应该公开内部组件让其它层来依赖。而是,层的接口应该设计为最小的依赖性,提供公共接口并且隐藏层中组件的细节。隐藏细节叫做抽象,有很多种方式实现抽象。如下设计方式用来为层定义接口:抽象接口 –可以通过定义抽象基类或类型定义来实现。基类或类型定义了所有层消费者用于和层进行交互的公共接口。通过使用实现抽象接口的测试对象,有的时候又叫做mock对象,可以增进可测试性。公共设计类型 –许多设计模式定义表示不同层中接口的对象类型。这些对象类型提供了一个抽象,它隐藏了层中的细节。例如,表数据入口模式定义了表示数据库中表的对象类型。这些对象负责实现和数据库交互的必要SQL代码。对象的消费者不需要知道使用的SQL甚至不需要知道连接数据库和执行命令的细节。依赖倒置 –这是一种编程模式,抽象接口定义在任何层的外部或不依赖于任何层。层不依赖于公共接口,而不是一个层依赖于另一个层。依赖注入模式是依赖导致的常见实现方式。通过依赖注入组件,一层可以通过使用公共抽象接口来注入到其它层的组件中。基于消息 –基于消息的接口可以用于提供层之间的交互,而不是直接和组件进行交互。有多种消息解决方案,比如web服务和支持跨机器和进程边界的微软消息队列。然而,你也可以组合抽象接口和用于定义要交互的数据结构的公共消息类型。 基于消息最主要的区别是层之间的交互使用公共结构,它封装了交互的细节。这个结构可以定义 *** 作、数据架构、错误契约、安全信息以及其它和层之间通讯相关的细节。考虑使用抽象接口:如果你希望使用接口具体实例来实现不同行为的能力。如果你希望使用mock对象来增加应用程序的可测试性。考虑使用公共设计类型:如果你在为层中的接口实现设计模式。许多设计模式基于抽象接口,然而,一些基于具体类。如果你希望一种快捷而简单的方式实现层接口。比如表数据入口模式。考虑使用依赖导致:如果你希望提供最大的可测试性,这个方式允许你诸如具体的测试类到设计中的不用层中。考虑使用基于消息的:如果你要实现一个web应用程序并且在表现层和业务层中定义接口。如果你有一个应用程序层需要支持多个客户端类型。如果你希望提供跨物理和进程边界交互。如果你希望以公共接口进行交互。如果你要和一个无状态的接口进行交互,状态信息使用消息进行携带。 对于web应用程序表现层和业务逻辑层之间的交互推荐使用基于消息的接口。一般通过使用Windows Communication Foundation (WCF)或提供公共消息类型的抽象接口来实现。在表现层和业务层之间使用基于消息的接口的原因是因为web应用程序的业务层不维护调用间的状态。换句话说,每一次表现层和业务层中的调用都代表一个新的上下文。通过使用基于消息的接口我们可以随请求传递上下文信息并且为表现层中的异常和错误处理提供一种公共的模型。检查点在结束本步骤之前,你应该可以回答如下问题:你是否需要使用抽象接口提供测试性?你的接口是否需要提供跨进程和机器边界交互?你的业务层是否需要支持多个客户端类型?你是否会使用基于消息的接口在web应用程序的表现层和业务层之间进行交互?第三步——选择部署策略对于大多数解决方案中都可以找到几种常见的模式,它们表示了应用程序的部署结构。如果要为我们的应用程序决定最佳部署解决方案,首先需要了解常见的模式。在理解了不同的模式之后,然后你就可以考虑场景、需求以及安全约束来选择某一种或多种模式。客户端-服务器这个模式表示具有两个主要组件:客户端和服务器的基本结构。对于这种情况,客户端和服务器可以在相同机器上也可以跨越两个机器。如下示例演示了常见的web应用程序场景,客户端和web服务器进行交互。N层这个模式表示应用程序组件跨域一个或多个服务器的结构。下图表示了2层部署,所有应用程序代码位于客户端而数据库位于分离的服务器中。3层在3层设计中,客户端和部署在独立服务器的应用程序软件进行交互,和数据库进行交互的应用程序服务器也是单独的服务器。这是许多web应用程序和web服务常见的模式。 4层对于这种情况,web服务器从物理上和应用服务器分离。这么做通常处于安全的目的,web服务器部署在隔离区域(DMZ)中而应用程序服务器位于不同的子网。我们一般会在客户端和web层以及web层和应用层或业务逻辑层之间假设2道防火墙。考虑客户端服务器或2层: 如果我们在开发一个需要访问应用服务器的客户端。 如果我们在开发一个访问外部数据库的独立客户端。考虑3层: 如果我们在开发基于局域网的应用程序,所有服务器都在一个私有网络中。 如果我们在开发基于Internet的应用程序,并且安全需求不约束在公共的web/应用服务器中实现业务逻辑。考虑4层: 如果安全需求规定业务逻辑不能在DMZ中部署业务逻辑。 如果我们的应用程序使用服务器上的资源很厉害并且我们希望把功能分离到另一个服务器。在大多数情况下推荐让所有的应用程序代码放在相同服务器。任何需要跨物理边界的需求都会影响性能因为数据需要在这些边界进行序列化。然而,有一些情况下我们需要跨服务器分离功能。此外,根据服务器的位置我们可以选择性能最优化的通讯协议。检查点在结束本步骤之前,你应该可以回答如下问题: 安全需求是否规定业务逻辑不能部署在公开的DMZ中? 我们是否在开发独立的只需要访问数据库的客户端? 我们是否在开发web应用程序或web服务? 我们是否在开发有多个客户端的应用程序? 第四步——选择通讯协议说到设计中用于跨逻辑层或物理层进行通讯的物理协议,通讯协议的选择对我们应用程序的性能起巨大作用。选择通讯协议的一个主要的地方就是使用服务和数据库进行交互。 Windows Communication Foundation (WCF) –直接支持四种协议: >

#include

struct person

{

char name[10];

int num;

};

void main()

{

struct person per[5];

void sort(struct person , int );

int i;

printf("print letter:\n");

for(i=0;i<5;i++)

{

printf("name: ");

scanf("%s", &per[i]name);

printf("num: ");

scanf("%d", &per[i]num);

}

sort(per, 5);

for(i=0;i<5;i++)

printf("print: %s%d\n", per[i]name, per[i]num);

getch();

}

void sort(struct person a, int n)

{

int i,j,t;

for(i=0;i<n;i++)

for(j=0;j<n;j++)

if(a[i]num>a[j]num)

{

t=a[i]num; /你代码中i写成j,这是细节问题/

a[i]num=a[j]num;

a[j]num=t;

}

}

你代码有点问题,我给你改了改。TC测试通过。

除了注视的地方,还有几点要注意:

你源代码传送的是per[0]num的地址,记:a[0],但是a[1]的地址不等于

per[1]num的地址。

指针加1的意思你没理解好。

举个列子。

int a[10];

那么(a+1)的意思是把a地址向后移动sizeof(int)个位。

所以你那个&a[1]指向的还是结构体中的数据。(恩,这里体现了低级语言的特性。每一个内存的每一位都要考虑到。要是你写个程序:200位的浮点数加法计算机,你更能体会到什么叫做考虑到每一位内存,调试的时候要一个内存一个内存的演算。代码我的baidu空间里有,可以自己去看)

不懂的问

以上就是关于delphi程序结构是怎样的全部的内容,包括:delphi程序结构是怎样的、CMake如何让工程内的文件引入工程外部的头文件,而这个外部的头文件又能引入工程内部的头文件、在标准C语言中,如何让.lib文件调用外部函数的结构体等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/zz/10137817.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-05
下一篇2023-05-05

发表评论

登录后才能评论

评论列表(0条)

    保存