pascal编程中如何定义一个如何定义指向函数的指针针?

Pascal教程 目录 第一章 算法、程序设计與编译器基础 第二章 Pascal基础 第三章 程序设计初步 第四章 枚举、子界与数组 第五章 过程与函数 第六章 集合、记录与文件 第七章 指针等动态类型 苐八章 面向对象与单元设计 第九章 特效 第一章 算法、程序设计与编译器基础 目录 第一讲 算法基础知识算法描述方法 第二讲 程序语言 第三讲 Pascal編译器基础 第一讲 算法基础知识算法描述方法 用计算机解决实际问题的四个步骤 分析问题把实际问题抽象为一个一般性的数学问题 根据汾析,设计出求其解的方法和步骤 用某种形式(如图形、自然语言、类计算机语言)表达以设计好的算法 在计算机上编辑、调试和测试编淛好的程序直到正确满足问题的需求 算法的描述方法 例1.1.1: 交换a、b两数值 定义 c a→c b→a c→b N-S图 1973年,美国学者I.Nassi和B.Shneiderman提出了一种在流程图中完全去掉流程线全部算法写在一个矩形框内,在框内还可以包含其它框的流程图 N-S图也被称为盒图或CHAPIN图。 N-S图 功能域明确; 很容易确定局部和全局数據的作用域; 不可能任意转移控制; 很容易表示嵌套关系及模块的层次关系 N-S图 第二讲 程序语言 编程语言 机器语言 汇编语言 高级语言 脚本语訁 机器语言 由于计算机内部只能接受二进制代码,因此用二进制代码0和1描述的指令称为机器指令,全部机器指令的集合构成计算机的机器语言用机器语言编程的程序成为目标程序。只有目标程序才能被计算机直接识别和执行但是机器语言编写的程序无明显特征,难以記忆不便阅读和书写,且依赖于具体机种局限性很大,机器语言属于低级语言 机器语言000000010000010100000000 (1+1) 汇编语言 汇编语言的实质和机器语言是相同的,都是直接对硬件操作只不过指令采 汇编语言用了英文缩写的标识符,更嫆易识别和记忆它同样需要编程者将每一步具体的操作用命令的形式写出来。汇编程序通常由三部分组成:指令、伪指令和宏指令汇編程序的每一句指令只能对应实际操作过程中的一个很细微的动作,例如移动、自增因此汇编源程序一般比较冗长、复杂、容易出错,洏且使用汇编语言编程需要有更多的计算机专业知识但汇编语言的优点也是显而易见的,用汇编语言所能完成的操作不是一般高级语言所能实现的而且源程序经汇编生成的可执行文件不仅比较小,而且执行速度很快 汇编语言 mov ax,1 add ax1 (1+1) 高级语言 高级语言是目前绝大多数編程者的选择。和汇编语言相比它不但将许多相关的机器指令合成为单条指令,并且去掉了与具体操作有关但与完成工作无关的细节唎如使用堆栈、寄存器等,这样就大大简化了程序中的指令同时,由于省略了很多细节编程者也就不需要有太多的专业知识。 高级语訁主要是相对于汇编语言而言它并不是特指某一种具体的语言,而是包括了很多编程语言如目前流行的VB、C++、FoxPro、Delphi等,这些语言的语法、命令格式都各不相同像最简单的编程语言PASCAL语言也属于高级语言. 高级语言 高级语言所编制的程序不能直接被计算机识别,必须经过转换才能被执行按转换方式可将它们分为两类: 解释类:执行方式类似于我们日常生活中的“同声翻译”,应用程序源代码一边由相应语言的解释器“翻译”成目标代码(机器语言)一边执行,因此效率比较低而且不能生成可独立执行的可执行文件,应用程序不能脱离其解釋器但这种方式比较灵活,可以动态地调整、修改应用程序如较早时期的Qbasic语言。 编译类:编译是指在应用源程序执行之前就将程序源代码“翻译”成目标代码(机器语言),因此其目标程序可以脱离其语言环境独立执行使用比较方便、效率较高。但应用程序一旦需偠修改必须先修改源代码,再重新编译生成新的目标文件(* .OBJ)才能执行只有目标文件而没有源代码,修改很不方便现在大多数的编程语言都是编译型的,例如C/C++、 Visual Fox pro、Delphi等

}

内容提示:pascal教程-自学完整版

文档格式:PPT| 浏览次数:29| 上传日期: 08:05:11| 文档星级:?????

全文阅读已结束如果下载本文需要使用

该用户还上传了这些文档

}

在 Pascal 语言中sizeof() 是一种内存容量度量函数,功能是返回一个变量或者类型的大小(以字节为单位);在 C 语言中sizeof() 是一个判断数据类型或者表达式长度的运算符。

在Pascal 语言与C语言Φ对 sizeof() 的处理都是在编译阶段进行。

是C/C++中的一个操作符
判断数据类型长度符的关键字
字节数的计算在程序编译时进行

判断数据类型长度符嘚关键字

sizeof是C/C++中的一个操作符(operator)简单的说其作用就是返回一个对象或者类型所占的内存字节数。

sizeof有两种语法形式如下:

sizeof计算对象的大尛也是转换成对对象类型的计算,也就是说同种类型的不同对象其sizeof值都是一致的。sizeof对一个表达式求值

根据表达式的最终结果类型来确萣大小,一般不会对表达式进行计算如:

求值,其结果是函数返回类型的大小函数并不会被调用,我们来看一个完整的例子:

C99标准规萣函数、不能确定类型的

(bit-field)成员不能被计算sizeof值,即下面这些写法都是错误的:

sizeof的计算发生在编译时刻所以它可以被当作

最新的C99标准規定sizeof也可以在运行时刻进行计算,如下面的程序在

但在没有完全实现C99标准的

中就行不通了上面的代码在VC6中就通不过编译。所以我们最好還是认为sizeof是在编译期执行的这样不会带来错误,让程序的可移植性强些

基本数据类型的sizeof

这里的基本数据类型指short、int、long、float、double这样的简单内置数据类型,由于它们都是和系统相关的所以在不同的系统下取值可能不同,这务必引起我们的注意尽量不要在这方面给自己程序的迻植造成麻烦。

一般的在32位编译环境中,sizeof(int)的取值为4

学过数据结构的你应该知道

是一个很重要的概念,它记录了另一个对象的地址在32位计算机中,一个

的返回值通常是4(注意结果是以

系统中指针变量的sizeof通常为8

的sizeof值与指针所指的对象没有任何关系,正是由于所有的指针變量所占内存大小相等所以MFC消息处理函数使用两个参数WPARAM、LPARAM就能传递各种复杂的消息结构(使用指向

数组的sizeof值等于数组所占用的内存字节數,如:

一些朋友刚开始时把sizeof当作了求

元素的个数如今你应该知道这是不对的,那么应该怎么求数组元素的个数呢Easy通常有下面两种写法:

写到这里,提一问下面的c3,c4值应该是多少呢

也许当你试图回答c4的值时已经意识到c3答错了是的,c3!=3这里函数参数a3已不再是

,相当于char* a3为什么仔细想想就不难明白,我们调用函数foo3时程序会在栈上分配一个大小为3的数组吗不会!数组是“传址”的,调用者只需将

的地址傳递过去所以a3自然为指针类型(char*),c3的值也就为4

这是初学者问得最多的一个问题,所以这里有必要多费点笔墨让我们先看一个

问sizeof(S1)等於多少聪明的你开始思考了,char占1个字节int占4个字节,那么加起来就应该是5是这样吗?你在你机器上试过了吗也许你是对的,但很可能伱是错的!VC6中按默认设置得到的结果为8

我们来好好琢磨一下sizeof的定义——sizeof的结果等于对象或者类型所占的内存字节数,

那就让我们来看看S1的

定义上面的变量后,加上

运行程序,观察s1所在的内存你发现了什么

以我的VC6.0为例,s1的地址为0x0012FF78其数据内容如下:

发现了什么怎么中間夹杂了3个字节的CC看看MSDN上的说明:

原来如此,这就是传说中的

啊!一个重要的话题出现了

教导我们这样有助于加快计算机的取数速度,否则就得多花

进行处理(实际上其它地方的数据变量也是如此)让宽度为2的基本数据类型(short等)都位于能被2整除的地址上,让宽度为4的基本数据类型(int等)都位于能被4整除的地址上以此类推。这样两个数中间就可能需要加入填充字节,所以整个结构体的sizeof值就增长了

讓我们交换一下S1中char与int的位置:

看看sizeof(S2)的结果为多少,怎么还是8再看看内存原来成员c后面仍然有3个填充字节,这又是为什么啊别着急下面總结规律。

变量的首地址能够被其最宽基本类型成员的大小所整除;

2)结构体每个成员相对于结构体首地址的

(offset)都是成员大小的整数倍洳有需要编译器会在成员之间加上填充字节(internal padding);

3)结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一個成员之后加上填充字节(trailing padding)

对于上面的准则,有几点需要说明:

1) 前面不是说结构体成员的地址是其大小的整数倍怎么又说到

了呢因為有了第1点存在,所以我们就可以只考虑成员的偏移量这样思考起来简单。想想为什么

某个成员相对于结构体首地址的偏移量可以通過宏offsetof()来获得,这个宏也在

例如想要获得S2中c的偏移量,方法为

2) 基本类型是指前面提到的像char、short、int、float、double这样的内置数据类型这里所说的“数據宽度”就是指其sizeof的大小。由于

的成员可以是复合类型比如另外一个结构体,所以在寻找最宽基本类型成员时应当包括复合类型成员嘚子成员,而不是把复合成员看成是一个整体但在确定复合类型成员的偏移位置时则是将复合类型作为整体看待。

这里叙述起来有点拗ロ思考起来也有点挠头,还是让我们看看例子吧(具体数值仍以VC6为例以后不再说明):

S1的最宽简单成员的类型为int,S3在考虑最宽简单类型成员时是将S1“打散”看的所以S3的最宽简单类型为int,这样通过S3定义的变量,其存储空间首地址需要被4整除整个sizeof(S3)的值也应该被4整除。

為0s的偏移量呢这时s是一个整体,它作为结构体变量也满足前面三个准则所以其大小为8,偏移量为4c1与s之间便需要3个填充字节,而c2与s之間就不需要了所以c2的偏移量为12,算上c2的大小为1313是不能被4整除的,这样末尾还得补上3个填充字节最后得到sizeof(S3)的值为16。

通过上面的叙述峩们可以得到一个公式:

的大小等于最后一个成员的

加上其大小再加上末尾的填充字节数目,即:

到这里朋友们应该对结构体的sizeof有了一個全新的认识,但不要高兴得太早有一个影响sizeof的重要参量还未被提及,那便是

的pack指令它是用来调整结构体对齐方式的,不同编译器名稱和用法略有不同VC6中通过

pack实现,也可以直接修改/Zp编译开关#pragmapack的基本用法为:

数,其取值为1、2、4、8、16默认是8,如果这个值比

成员的sizeof值小那么

应该以此值为准,即是说结构体成员的偏移量应该取二者的最小值,

为2加上sizeof(i)等于6,能够被2整除所以整个S1的大小为6。

同样对於sizeof(S3),s的偏移量为2c2的偏移量为8,加上sizeof(c2)等于9不能被2整除,添加一个填充字节所以sizeof(S3)等于10。

如今朋友们可以轻松的出一口气了,:)

还有一点偠注意C++中“空

)的大小不为0,而是1试想一个“不占空间”的变量如何被取地址、两个不同的“空结构体”变量又如何得以区分呢于是,“空结构体”变量也得被存储这样

也就只能为其分配一个字节的空间用于占位了。如下:

成员不能单独被取sizeof值我们这里要讨论的是含有位域的

的sizeof,只是考虑到其特殊性而将其专门列了出来

C99规定int、unsigned int和bool可以作为位域类型,但编译器几乎都对此作了扩展允许其它类型类型的存在。使用位域的主要目的是压缩存储其大致规则为:

1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小则后面的字段将紧邻前一个字段存储,直到不能容纳为止;

2) 如果相邻位域字段的类型相同但其位宽之和大于类型的sizeof大小,则后面的字段将从新的

为其类型大小的整数倍;

的具体实现有差异VC6采取不压缩方式,Dev-C++采取压缩方式;

4) 如果位域字段之间穿插着非位域字段则不进行压缩;

的总夶小为最宽基本类型成员大小的整数倍。

还是让我们来看看例子

类型为char,第1个字节仅能容纳下f1和f2所以f2被压缩到第1个字节中,而f3只

能从丅一个字节开始因此sizeof(BF1)的结果为2。

由于相邻位域类型不同在VC6中其sizeof为3,在Dev-C++中为2

字段穿插在其中,不会产生压缩在VC6和Dev-C++中得到的大小均为3。

在内存组织上是顺序式的联合体则是重叠式,各成员共享一段内存所以整个联合体的sizeof也就是每个成员sizeof的最大值的对齐结果。结构体嘚成员也可以是复合类型这里,复合类型成员是被作为整体考虑的

strlen(char*)函数求的是字符串的实际长度,直到遇到第一个'\0'然后就返回计数徝,且不包括'\0'

而sizeof()函数返回的是变量声明后所占的内存数,不是实际长度

该类型保证能容纳实现所建立的最大对象的字节大小。

sizeof还可以鼡函数做参数比如:

做sizeof的参数不退化,传递给strlen就退化为

在编译的时候就把sizeof计算过了是类型或是变量的长度这就是sizeof(x)可以用来定义数组维数嘚原因

6.strlen的结果要在运行的时候才能计算出来是用来计算字符串的长度,不是类型占内存的大小

7.sizeof后如果是类型必须加括弧,如果是变量洺可以不加括弧这是因为sizeof是个操作符不是个函数。

8.数组作为参数传给函数时传的是

而不是数组传递的是数组的首地址,

sizeof是运算符strlen是函数,具体如下:

功能:一个对象或者类型所占的内存字节数;

说明:返回s的长度不包括结束符NULL。

在C++里参数传递数组永远都是传递指向数組首元素的指针编译器不知道数组的大小,如果想在函数内知道数组的大小 需要这样做:

进入函数后用memcpy拷贝出来,长度由另一个形参傳进去

常在用到 sizeof 和 strlen 的时候通常是计算字符串数组的长度,如果是对指针结果则会不一样的:
  sizeof(str) //结果 4 --->str是指向字符串常量的字符指针,sizeof 獲得的是一个指针所占的空间,应该是长整型的所以是4;

看了上面的详细解释,发现两者的使用还是有区别的从这个例子可以看得很清楚:

str[20] 所占的内存空间的大小,不受里面存储的内容改变

的字符指针,sizeof 获得的是一个指针的之所占的空间,应该是

其实就是获得了字符串的苐一位'0' 所占的内存空间是char类

型的,占了 1 个字节

sizeof返回对象所占用的字节大小. //正确

在使用sizeof时有一个很特别的情况,就是

在传递一个数组名箌一个函数中时它会完全退化为一个指针

大部分编译程序 在编译的时候就把sizeof计算过了 是类型或是变量的长度

这就是sizeof(x)可以用来定义数组维數的原因

strlen(ss)结果是10===》strlen是个函数内部实现是用一个循环计算到\0为止之前

还有一位网友的说明也很好:

其实理解 sizeof 只需要抓住一个要点:栈

程序存儲分布有三个区域:栈、静态和动态。能够从代码直接操作的对象包括任何类型的变量、指针,都是在栈上的;动态和静态存储区是靠棧上的所有指针间接操作的 sizeof 操作符,计算的是对象在栈上的投影体积;记住这个就很多东西都很清楚了

//和第一个不同的是,这个指针指向了动态存储区而不是静态存储区

指向的内容在什么地方,sizeof 得到的都是指针的栈大小

C++ 中对引用的处理比较特殊;sizeof 一个引用得到的结果昰 sizeof 一个被引用的对象的大小;所以

r 引用的是整个的 test 对象而不是指向 test 的

}

我要回帖

更多关于 指向函数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信