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”,在创建数据引用后,我们将其分配给字段符号。现在我们可以对这个字段符号进行操作了。所以数据引用和字段符号之间的区别是:-

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

在数据引用的情况下,我们首先创建一个数据引用,然后将其分配给字段符号。

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

4

4 回答 4

18

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

数据引用就像一个简单的指针,除了你不能像 C 中那样增加或减少内存地址(ptr++、ptr-- 等等)。它与字段符号不同,因为您可以比较两个数据引用以检查它们是否指向内存中完全相同的位置。比较两个字段符号将是一个简单的值比较。另一个区别是您可以使用 CREATE DATA 命令通过创建数据引用来动态分配内存。字段符号只能分配给已分配的变量。

于 2012-09-13T12:34:57.427 回答
4

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

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

字段符号不是“真正的”变量。该文件指出

他们没有为一个字段物理保留空间

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

DATA: my_char TYPE c,
      my_int  TYPE i,
      my_ref  TYPE REF TO i.

然后符号表将包含 - 除其他外 - 可能如下所示的条目:

name       type  size addr
------------------------------
MY_CHAR    c        1 0x123456
MY_INT     i        4 0x123457
MY_REF     r        ? 0x123461

(我不确定参考变量的实际大小。)

这些条目仅指向包含这些值的地址。根据这些变量的范围,它们可能驻留在完全不同的内存区域中,但这不是我们目前关心的问题。重点是:

  • 必须为变量保留内存(这是自动完成的,即使是引用)。
  • 引用就像所有其他变量一样工作。

让我们为此添加一个字段符号:

FIELD-SYMBOLS: <my_fs> TYPE any.

那么符号可能如下所示:

name       type  size addr     target
--------------------------------------
MY_CHAR    c        1 0x123456
MY_INT     i        4 0x123457
MY_REF     r        ? 0x123461
<MY_FS>    *        

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

ASSIGN my_char TO <my_fs>.

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

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。另一方面,如果您发出命令

GET REFERENCE OF my_int INTO my_ref.

符号表不会改变,但在“堆地址”0x123461,你会找到“地址”0x123457。my_char = 'X'只是一个像or的赋值my_int = 42 * 2

这就是在一个非常简化的版本中,您不能将字段符号作为更改参数传递并允许它们在子例程中重新分配的原因。它们的存在方式与其他变量不同,并且它们在被添加到的符号表范围之外没有任何意义。

于 2012-09-13T16:28:25.793 回答
1

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

数据引用(TYPE REF TO DATA_

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

于 2012-09-13T10:01:39.693 回答
0

字段符号是 - nomen est omen - 字段的符号。您将它分配给一个变量,它就成为该变量的别名。

引用和字段符号之间的主要区别在于,引用可以指向由 CREATE DATA 或 CREATE OBJECT 创建的匿名数据。必须始终将字段符号分配给现有变量。

于 2012-09-13T10:03:47.763 回答