ABAP基本数据类型、通用类型
ABAP基本数据类型
更多的类型请参考ABAP数据类型继承图
类型 |
允许最大长度(字符数) |
默认长度(省略时采用) |
说明 |
初始值 |
C |
1~262143个字符 |
1 字符 |
如果未在 DATA 语句中指定参数<length>和<type>,则创建长度为 1 的字符 |
每个位置都是空格 |
N |
1~262143个字符 |
1 字符 |
0到9之间字符组成的数字字符串
如果未在 DATA 语句中指定参数<length>,则创建长度为 1 |
"0"每个位置都是阿拉伯数字0 |
D |
8 个字符 |
|
日期格式必须为 YYYYMMDD 取值范围:YYYY (year): 0001 to 9999, MM(month): 01 to 12, DD (day): 01 to 31 |
"00000000" |
T |
6 个字符 |
|
格式为 24-hour的 HHMMSS HH:00 to 23 MM: 00 to 59 SS: 00 to 59 |
"000000" |
I |
4 bytes |
|
-2.147.483.648 to +2.147.483.647(.点号为千分位分隔符,不是小数点,而,逗号则表示是小数点) 如果运算出现非整型的结果(如小数)则进行四舍五入,而不是截断 |
0 |
F |
8 bytes |
|
小数位最大可以到17位,即可精确到小数点后17位 取值范围:-1,7976931348623157EE+308 to -2,2250738585072014EE-308 for the negative area, the value zero, and +2,2250738585072014EE-308 to +1,7976931348623157EE+308 for the positive area. 如果要求高精度,则不应该使用类型 F 数据。而应代之以类型 P 数据 F赋值时,会转换为标准形式:<±尾数部分>E±<指数部分>,且尾数部分的小数位最多为17位 |
0
如果值是小数,则要将值使用引号引起来 |
P |
1 to 16 bytes |
8 bytes |
有效长度为1到16个字节。 两个数字位压缩后才占一个字节,由于0-9的数字只需要4Bit位,所以一个字节实质上允许存储二位数字,这就是P数据类型为压缩数据类型的由来,因为定义的的数据长度比存储于内存中要长。并借用最后半个字节,即字面上的一位来存储小数点、正号、负号、或者是这三种中间的组合————存储的可能是通过将小数点与正负号经过某种位运算后的结果,因为半个字节不可能存储小数或正负号的所对应的ASCII码(都比15大) P类型最多允许14位小数位,即可以精确到小数点后14,再除开小数点与正负号占半个字节,即字面上1位4Bit,此时最大整数位最长可达16*2 = 32 – 1 = 31 -14 = 17位 Depending on the field length len(len表示定义时P的整个长度) and the number of decimal places dec(dec表示小数位), the following applies for the value area: (-10^(2len -1) +1) / (10^(+dec)) to (+10^(2len -1) -1) /(10^(+dec)) in steps of 10^(-dec). Values in between this range are rounded off. 在计算过程中如果小数部分过长,则进行四舍五入 |
0
若小数部分超过长度,则自动按四舍五入将多余的小数除掉;如果整数部分超过长度,则系统运行出错
如果值是小数,则要将值使用引号引起来 |
X |
1~524,287 bytes |
1 byte |
十六进制字符 0-9, A-F具体的范围为:00~FF 类型X是十六进制类型,可表示内存字节实际内容,使用两个十六制字符表示一个字节中所存储的内容。但直接打印输出时,输出的还是赋值时字面意义上的值,而不是Unicode解码后的字符 如果未在 DATA 语句中指定参数<length>,则创建长度为 1 注:如果值是字母,则一定要大写,否则赋值不进 DATA: x2(2) TYPE x. |
十六进制的00 |
string |
不限定 |
|
在系统内部,长度可变的内置类型(String、XString)是通过引用实际动态的数据对象的固定内存地址来进行操作,因而这两种内置类型和引用类型一样,属于纵深类型。 |
长度为0的空字符串'' |
xstring |
不限定 |
|
由十六进制字符 0-9, A-F组成字符串。直接打印输出时,输出的还是赋值时字面意义上的值,而不是Unicode解码后的字符串 注:如果值是字母,则一定要大写,否则赋值不进 DATA : xs TYPE xstring . |
长度为0的空字符串'' |
b |
1 Byte |
|
0 to 255属于ABAP内部类型,在ABAP程序中不能直接使用 |
0 |
s |
2 bytes |
|
-32.768 to +32.767属于ABAP内部类型,在ABAP程序中不能直接使用 |
0 |
P类型(压缩型)数据
是一种压缩的定点数,其数据对象占据内存字节数和数值范围取定义时指定的整个数据大小和小数点后位数,如果不指定小数位,则将视为I类型。其有效数字位大小可以是从1~31位数字(小数点与正负号占用一个位置,半个字节),小数点后最多允许14个数字。
P类型的数据,可用于精确运算(这里的精确指的是存储中所存储的数据与定义时字面上所看到的大小相同,而不存在精度丢失问题——看到的就是内存中实实在在的大小)。在使用P类型时,要先选择程序属性中的选项 Fixed point arithmetic(即定点算法,一般默认选中),否则系统将P类型看用整型。其效率低于I或F类型。
"16 * 2 = 32表示了整个字面意义上允许的最大字面个数,而14表示的是字面上小数点后面允许的最大小数位,而不是指14个字节,只有这里定义时的16才表示16个字节
DATA: p(16) TYPE p DECIMALS 14 VALUE '12345678901234567.89012345678901'.
"正负符号与小数点固定要占用半个字节,一个字面上位置,并包括在这16个字节里面。
"16 * 2 = 32位包括了小数点与在正负号在内
"在定义时字面上允许最长可以达到32位,除去小数点与符号需占半个字节以后
"有效数字位可允许31位,这31位中包括了整数位与小数位,再除去定义时小
"数位为14位外,整数位最多还可达到17位,所以下面最多只能是17个9
DATA: p1(16) TYPE p DECIMALS 14 VALUE '-99999999999999999'.
"P类型是以字符串来表示一个数的,与字符串不一样的是,P类型中的每个数字位只会占用4Bit位,所以两个数字位才会占用一个字节。另外,如果定义时没有指定小数位,表示是整型,但小数点固定要占用半个字节,所以不带小数位与符号的最大与最小整数如下(最多允许31个9,而不是32个)
DATA: p1(16) TYPE p VALUE '+9999999999999999999999999999999'.
DATA: p2(16) TYPE p VALUE '-9999999999999999999999999999999'.
其实P类型是以字符串形式来表示一个小数,这样才可以作到精确,就像Java中要表示一个精确的小数要使用BigDecimal一样,否则会丢失精度。
DATA: p(9) TYPE p DECIMALS 2 VALUE '-123456789012345.12'.
WRITE: / p."123456789012345.12-
DATA: f1 TYPE f VALUE '2.0',
f2 TYPE f VALUE '1.1',
f3 TYPE f.
f3 = f1 - f2."不能精确计算
"2.0000000000000000E+00 1.1000000000000001E+00 8.9999999999999991E-01
WRITE: / f1 , f2 , f3.
DATA: p1 TYPE p DECIMALS 1 VALUE '2.0',
p2 TYPE p DECIMALS 1 VALUE '1.1',
p3 TYPE p DECIMALS 1.
p3 = p1 - p2."能精确计算
"2.0 1.1 0.9
WRITE: / p1 , p2 , p3.
DATA: P TYPE P.
P = 1 / 3 * 3.
WRITE P.
如果未设置程序属性“定点算法”,则结果为 0,这是因为除法结果被内部取整为 0。
如果设置程序属性“定点算法”,则结果为 1,这是因为除法结果被内部存储 0.333333333333333333333333333333,精度达 31 位数字。
Java中精确计算:
publicstaticvoid main(String[] args) {
System.out.println(2.0 - 1.1);// 0.8999999999999999
System.out.println(sub(2.0, 0.1));// 1.9
}
publicstaticdouble sub(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.subtract(b2).doubleValue();
}
ABAP数据类型继承图
下图中左边展示了ABAP类型的继承关系(黄色表示类型、灰色表示可生成相应的数据),右边为通用数据类型(但只用在formalparameters(形式参数)与field symbols字段符号,Data通用类型只可用于定义data references变量,object通用类型只可用于定义object references变量)。
character-type:text fields (c)、numeric text fields (n)、date fields (d)、and time fields (t)、text string (string),相应的通用类型为clike
numeric-type:Integer (i)、floating point numbers (f)、and packed numbers (p),相应的通用类型为numeric.
byte-type:Byte fields (x)、byte string (xstring),相应的通用类型为xsequence.
Byte-type 与 Character-type
- Byte-type :x or xstring.
- Character-type :c, n, d, t, string或者是由纯的character-type类型字段组成的结构structure
通用类型
除了object,所有的通用类型都能直接用TYPE后面(如 TYPE data,但没有TYPE object,object不能直接跟在TYPE后面,只能跟在 TYPE REF TO后面)
TYPE REF TO 后面可接的通用类型只能是 data(数据引用)或者是 object(对象引用)通用类型,其他通用类型不行:
TYPE REF TO data :表示的是数据引用data references
TYPE REF TO object: 表示的是对象引用object references
ANY代表了除data、 object 任何数据类型
下表为ABAP预置的通用类型。ABAP数据类型继承图
Type |
Description |
Internal table with any table type |
|
Standard table |
|
c |
Text field with a generic length |
n |
Numeric text with generic length |
p |
Packed number with generic length and generic number of decimal places |
x |
Byte field with generic length |
Character-like (c, d, n, t, string, and character-like flat structures) |
|
Text-like (c, string) |
|
Byte-like (x, xstring) |
|
Numeric (i (b, s), p, decfloat16, decfloat34, f) |
|
Any data type |
|
Any data type |
|
基础数据类型,以及只包含character-like扁平组件的数据结构 Elementary data type including structured types with exclusively character-like flat components |
|
Any object type (root class of the inheritance hierarchy继承层次结构) |
|
字符类型C作为接口参数类型使用时,则传递的参数的长度可以是任意的,但如果采用C(XX)形式定义的,则传递进去的长度固定为XX。
如果字符符号定义成一般类型(通用类型)内表,则在使用时,你只能动态的访问各字段的名称:
TYPES: BEGIN OF line,
col1,
col2,
END OF line.
DATA: wa TYPE line,
itab TYPE HASHED TABLE OF line WITH UNIQUE KEY col1,
key(4) VALUE 'col1'.
FIELD-SYMBOLS <fs> TYPE ANY TABLE.
wa-col1 = 'X'.
wa-col2 = 'Y'.
INSERT wa INTO TABLE itab.
ASSIGN itab TO <fs>.
CLEAR: wa.
READ TABLE <fs> WITH TABLE KEY (key) = 'X' INTO wa.
"编译会出错
*READ TABLE <fs> WITH TABLE KEY col1 = 'X' INTO wa.
WRITE:/ sy-subrc, wa-col1, wa-col2.
因为上面的字段符号为ANY TABLE,行的结构类型不明确,所以不能静态的指定行的字段名。如果上面将字段符号定义成ANY或什么都不写是写时,根本就不可以使用READ TABLE这样的语句,原因是在静态编译的情况下,根本不为会它指向的是一个内表。
当使用完全限定类型定义字段符号时,可以静态的使用技术属性。如,某个结构的组件元素、循环某个内表、创建某个对象(引用类型的字段符号):
DATA: BEGIN OF line,
col1,
col2 VALUE 'X',
END OF line.
FIELD-SYMBOLS <fs> LIKE line.
ASSIGN line TO <fs>.
MOVE <fs>-col2 TO <fs>-col1.
WRITE: / <fs>-col1,<fs>-col2.
INDEX/ANY TABLE通用型内表
除三种标准类型外,还有一般性类型,即索引表(INDEX TABLE)和任意表(ANY TABLE),一般性类型可以用于类型定义中,但不能用于声明一个内表对象,因为它并没有指明任何明确的表类型,因而系统无法确定对其操作方式。一般性类型还可以用于指明字段符号和接口参数的类型,其实际类型可能在运行期内才能够确定。
扁平类型和纵深类型
扁平结构就是指变量内存中直接存储的是内容,而不是地址,指针是一种典型的引用类型即纵深类型。
扁平结构指的是所有代表实际操作内容的数据对象,因此固定长度的基本类型(即除开string与Xstring类型外的基本类型)数据均为扁平结构数据。
纵深结构指的是数据对象的内容为其他的内存地址区域,因而引用类型的数据对象是典型的纵深结构,然而内表和字符串为纵深结构(String、Xstring类型对象),因为它们内部机制也是类似的引用寻址方式。对于结构体而言,如果其中一个组件含有上述纵深类型数据,则本身也是纵深结构,如果全部由基本类型数据组成,则该结构体也是扁平结构。因此扁平类型是运行时长度固定的类型,而纵深类型对应的数据对象所占内存长度在运行时内可变,系统是以指针的形式为寻址方式对其定位。
参数的通用类型
一般性类型及其兼容性检查规则(一般性类型/非完全限定):
这种通用的类型指定在参数传递过程中可以带来方便,但也会由于系统检查级别的降低而增加危险性,也可能因为类型的不明确性造成误用,所以在大多数据可能的情况下,还是尽量明确地指定接口参数的类型。