首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ABAP中的字段符号和数据引用概念

问ABAP中的字段符号和数据引用概念
EN

Stack Overflow用户
提问于 2012-09-13 16:44:06
回答 4查看 30.1K关注 0票数 9

如果我们将ABAP字段符号和数据引用与C中的指针进行比较,我们会观察到:

在C中,假设我们声明一个变量"var“类型为"integer”,默认值为"5“。

变量"var“将存储在内存中的某个位置,并假设保存此变量的内存地址为"1000”。

现在我们定义了一个指针"ptr“,这个指针被赋值给我们的变量。

因此,"ptr“将是"1000”,“*ptr”将是5。

让我们比较一下ABAP中的上述情况。

这里我们声明一个字段符号"FS“,并将其赋值给变量"var”。

现在我的问题是"FS“包含什么?我在互联网上进行了严格的搜索,但发现许多ABAP顾问认为FS持有变量的地址,即1000。但这是错误的。调试时我发现fs只有5,所以fs (在ABAP中)等同于*ptr (在C中)。如果我的理解有误,请纠正我。

现在,让我们声明一个数据引用"dref“和另一个字段符号"fsym”,在创建数据引用之后,我们将其赋给字段符号。现在我们可以对这个字段符号进行操作了。因此,数据引用和字段符号之间的区别是:

在字段符号的情况下,首先我们将声明一个变量并将其赋给一个字段符号。

在数据引用的情况下,我们首先抓取一个数据引用,然后将其赋值给字段符号。

那么数据引用有什么用呢?同样的功能,我们也可以通过字段符号实现。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-09-13 20:34:57

字段符号非常类似于指针,但您只能以取消引用的形式访问它。换句话说,它将在内部保存分配给它的变量的内存地址,但它不允许您查看内存地址,只允许您查看存储在它所指向的变量中的数据。这是可以证明的,因为如果您更改指向内部表行的字段符号的内容,您将看到更改将直接在该行中进行。

数据引用的作用类似于简单的指针,除了不能像C中那样递增或递减内存地址(ptr++、ptr等)。它不同于字段符号,因为您可以比较两个数据引用,以检查它们是否指向内存中完全相同的点。比较两个字段符号将是一个简单的值比较。另一个不同之处在于,您可以使用CREATE data命令通过创建数据引用来动态分配内存。字段符号只能分配给已分配的变量。

票数 18
EN

Stack Overflow用户

发布于 2012-09-14 00:28:26

尽管数据引用和字段符号看起来非常相似,并且经常以相似的方式使用(请参阅其他答案),但它们从根本上是不同的。

数据引用是存储值的变量,就像字符串或整数一样。它们在内存和内容中都有一个固定的大小。唯一的区别是,这些引用是指向其他数据对象的指针,即内容具有特殊的含义。它们不能指向任何地方,它们可以被解除引用,你可以将它们传递给其他例程,你可以操作指针(GET REFERENCE)或它所指向的值。它没有什么特别的,真的-只是你从你最喜欢的编程语言中知道的指针。

字段符号不是“实数”变量。documentation声明

它们不会为字段物理预留空间

字段符号实际上只是对ABAP的本地symbol table的巧妙操作。我将尝试说明这一点-请注意,这是一个高度简化的模型。假设您声明了三个变量:

代码语言:javascript
复制
DATA: my_char TYPE c,
      my_int  TYPE i,
      my_ref  TYPE REF TO i.

则符号表将包含可能如下所示的条目:

代码语言:javascript
复制
name       type  size addr
------------------------------
MY_CHAR    c        1 0x123456
MY_INT     i        4 0x123457
MY_REF     r        ? 0x123461

(我不确定引用变量的实际大小。)

这些条目仅指向包含这些值的地址。根据这些变量的作用域,它们可能位于完全不同的内存区域,但这不是我们目前关心的问题。重要的是:

必须为变量保留

  • 内存(这是自动完成的,即使对于references).
  • References工作也是如此,就像所有其他变量一样。

让我们在其中添加一个字段符号:

代码语言:javascript
复制
FIELD-SYMBOLS: <my_fs> TYPE any.

则符号可能如下所示:

代码语言:javascript
复制
name       type  size addr     target
--------------------------------------
MY_CHAR    c        1 0x123456
MY_INT     i        4 0x123457
MY_REF     r        ? 0x123461
<MY_FS>    *        

字段符号在其初始状态(未指定)下创建。它不会指向任何地方,在这种状态下使用它将导致短转储。重要的一点是:它不像其他变量那样受到“堆”内存的支持。

代码语言:javascript
复制
ASSIGN my_char TO <my_fs>.

同样,该符号可能如下所示:

代码语言:javascript
复制
name       type  size addr     target
--------------------------------------
MY_CHAR    c        1 0x123456
MY_INT     i        4 0x123457
MY_REF     r        ? 0x123461
<MY_FS>    *                   MY_CHAR

现在,当访问<my_fs>时,运行时系统会将其识别为字段符号,在符号表中查找当前目标,并将所有操作重定向到my_char的实际位置。另一方面,如果您发出以下命令

代码语言:javascript
复制
GET REFERENCE OF my_int INTO my_ref.

符号表不会改变,但是在"heap address“0x123461处,你会发现"address”0x123457。只是一个像my_char = 'X'或my_int = 42 * 2这样的赋值。

在一个非常简单的版本中,这就是为什么you cannot pass field symbols as changing parameters and allow them to be reassigned inside the subroutine。它们的存在方式与其他变量不同,并且它们在添加到的符号表范围之外没有任何意义。

票数 4
EN

Stack Overflow用户

发布于 2012-09-13 18:01:40

字段符号在ABAP中存在的时间要长得多,它允许您在运行时操作和传递字段的值,而无需事先知道字段的名称。考虑以下用例:您有一个包含20个字段的结构,您可以通过名称引用每个字段并将其分配给一个字段符号,然后更改特定字段的值,等等。

数据引用(TYPE REF TO DATA)是ABAP的一个相对较新的补充,它允许您在运行时实例化数据,而无需事先使用“CREATE data”语句知道类型。

有关使用CREATE DATA的示例,请参阅下面的帮助页面。例如,它向您展示了如何使用CREATE DATA获取对引用对象(即ABAP对象引用)的引用,这是使用字段符号无法完成的操作:http://help.sap.com/abapdocu_70/en/ABAPCREATE_DATA_REFERENCE.htm

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12402564

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档