codecamp

Ada数据类型属性、类型限制和类型转换

数据类型属性,表示某个数据类型的具体特征---取值范围,最小值,最大值,某数在该类型中的位置 …… 应该说是相当有用的-----起码不像 C 语言,还要翻翻系统手册才能知道某个数据类型的具体定义。这些属性的用法和调用函数一样,也可以认为它们就是预定义的函数----虽然不怎么准确,有些返回值为通用类型(universal type)和字符串型。

数据类型的属性既可以使用预先定义的操作,也可以自己定义数据类型的属性,如S'First 是返回 S 类型的下限,如果用户不满意默认的属性,也可自己指定S'First(虽然没必要),如:

for S'First use My_Version_First;

My_Version_First 是用户自己的函数,以后当使用 S'First 时,实际上调用 My_Version_First;有些数据属性也可以直接用数字标示,如:

for S'First use 0;

这样,S'First 的值就成了0。在很多地方,如内存管理中,这种用法还是比较普遍的。下面简单地列出标量类型的属性,S 表示某个标量类型:

通用标量类型属性

S'First 返回 S 类型的下限,返回值为 S 型。

S'Last 返回 S 类型的上限,返回值为 S 型。

S'Range 返回 S 类型的取值范围,即 S'First .. S'Last。

S'Base 表示 S 类型的一个子类型,但没有范围限制(单纯从取值范围角度讲,“儿子”反而比“父母”大),称之为基类型(base type)。

S'Min 函数定义为: function (Left,Right:S'Base) return S'Base 。比较 Left和 Right 的大小,返回较小值。如:Integer'Min (1 , 2) = 1 。

S'Max 函数定义为: function (Left,Right:S'Base) return S'Base 。比较 Left和 Right 的大小,返回较大值。如:Integer'Max (1 , 2) =2 。

S'Succ 函数定义为:function S'Succ (Arg :S'Base) return S'Base 。返回 Arg 的后趋。

S'Pred 函数定义为: function S'Pred (Arg :S'Base) return S'Base 。返回 Arg的前趋。

S'Wide_Image 函数定义为:function S'Wide_Image (Arg : S'Base) return Wide_String 。返回 Arg 的“像”,即可显示的字符串,这里返回宽字符串型 Wide_String。如:Float'Wide_Image (9.00) = “9.00" 。详见 第三章 数组。

S'Image 与 S'Wide_Image 一样,但返回字符串型 String 。

S'Wide_Width 表示 S'Wide_Image 返回的字符串的最大长度,返回值为 universal_integer。

S'Width 表示 S'Image 返回的字符串的最大长度,返回值为 universal_integer。

S'Wide_Value 函数定义为: function S'Wide_Value ( Arg : Wide_String) return S'Base。是 S'Wide_Image 的逆过程,返回与“像”Arg 相对应的 S 类型的值。如: Float'Wide_Value ("9.00") = 9.00 。

S'Value 与 S'Value 一样,但参数 Arg 是 String 类型。

通用离散类型属性

离散类型包括整型和枚举型,除了上述的属性外,还有:

S'Pos 函数定义为: function S'Pos (Arg : S'Base) return universal_integer。返回 Arg 在 S 类型中的位置。

S'Val 函数定义为: function S'Pos (Arg : S'Base) return S'Base。返回 在 S 类型中位置为 Arg 的值。

例如:

type Color is (red, white, blue);
Color'Pos (White) = 2
Color'Val (1) = red

浮点类型属性

S'Digits  返回 S 类型的精度,为 universal_integer 类型。

定点类型属性

S'Small 返回 S 类型的 small 值,返回值为实型。

S'Delta 返回 S 类型的 delata,返回值为实型。

S'Fore  返回 S 类型所表示数的小数点前面的最小字符数量,返回值类型 universal_integer。

S'Alt 返回 S 类型所表示数的小数点后面的最小字符数量,返回值类型 universal_integer。

十进制定点型属性

十进制定点型属性

S'Digits 返回 S 类型的精度。

S'Scale 返回 S 类型的标度 N,使 S'Delta=10.0**(-N)。

S'Round 函数定义为 function S'Round(X:universal_real) return S'Base;返回 X 的舍入值。

2.6 类型限制和类型转换(Type Qualification and Type Conversion)

先让我们看一下下面的例子:

type primary is (red, green, blue);
type rainbow is (red, yellow, green, blue, violet);
...
for i in red..blue loop
...

这里明显有歧义,编译器也就无法自动判定 red,blue 到底是 primary 还是 rainbow 中的元素。因此我们就需要使用类型限制,精确指明元素:

for i in rainbow'(red)..rainbow'(blue) loop

for i in rainbow'(red)..blue loop -- 只需要一个限制

for i in primary'(red)..blue loop

类型限制并不改变一个值的类型,只是告诉编译器程序员所期望的数据类型。由于 Ada 中提供了重载等特性,变量、子程序等重名的现象相当普遍,以后我们会碰到,解决方法和现在所讲的类型限制差不多,都是指明资源的准确位置。

类型转换我们也常常在使用,比方说 modular 类型的数的输入输出需要特定的程序包,初学者便可以将 modular 数转换成 Integer 数来处理(虽然不怎么好)。下面是一个 Integer 和 Float 类型数互相转换的例子:

X : Integer:= 4;
Y : Float;
Y := float(X);
. . .
X := Integer(Y);

这导致编译器插入合适的代码来做类型转换,实际效果就取决于编译器,而且一些类型之间的转换是禁止的;像上述的强行转换一般也不推荐,除非意义很明确,建议是使用上节所讲的数据类型属性、以及以后会碰到的相关子程序等来进行类型转换。

还有一种不进行检查的类型转换,我们会在以后遇到。

类型限制和类型转换

先让我们看一下下面的例子:

type primary is (red, green, blue);
type rainbow is (red, yellow, green, blue, violet);
...
for i in red..blue loop
...

这里明显有歧义,编译器也就无法自动判定 red,blue 到底是 primary 还是 rainbow 中的元素。因此我们就需要使用类型限制,精确指明元素:

for i in rainbow'(red)..rainbow'(blue) loop
for i in rainbow'(red)..blue loop -- 只需要一个限制
for i in primary'(red)..blue loop

类型限制并不改变一个值的类型,只是告诉编译器程序员所期望的数据类型。由于 Ada 中提供了重载等特性,变量、子程序等重名的现象相当普遍,以后我们会碰到,解决方法和现在所讲的类型限制差不多,都是指明资源的准确位置。

类型转换我们也常常在使用,比方说 modular 类型的数的输入输出需要特定的程序包,初学者便可以将 modular 数转换成 Integer 数来处理(虽然不怎么好)。下面是一个 Integer 和 Float 类型数互相转换的例子:

X : Integer:= 4;
Y : Float;
Y := float(X);
. . .
X := Integer(Y);

这导致编译器插入合适的代码来做类型转换,实际效果就取决于编译器,而且一些类型之间的转换是禁止的;像上述的强行转换一般也不推荐,除非意义很明确,建议是使用上节所讲的数据类型属性、以及以后会碰到的相关子程序等来进行类型转换。

还有一种不进行检查的类型转换,我们会在以后遇到。


Ada标量类型
Ada数组的类型
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }