【问题标题】:C Pointer arithmetic in PythonPython中的C指针算法
【发布时间】:2011-07-31 06:10:19
【问题描述】:

我正在尝试将一个简单的 C 程序转换为 Python,但由于我对 C 和一点 Python 一无所知,这对我来说很难..

我被 C 指针卡住了。

有一个函数接受一个 unsigned long int 指针并将其值添加到 while 循环内的一些变量中:

uint32_t somename(const uint32_t *z) {
    while(....) {
        a += z[0]
        b += z[1]
        c += z[2]
        z += 3
    }
}

谁能告诉我如何在 python 中完成同样的事情? (完全看不懂的部分是“z += 3”)

我知道 python 中没有指针。 (至少不像 C)但问题是我不知道 C 指针究竟做了什么,因此不能在 python 中实现。

【问题讨论】:

  • .... 也很重要。
  • 客户端通过将地址(指针)传递给 z 的第一个元素来调用该函数。 z+=3 移动到 z[0]、z[1]、z[2] 和 z[3]。
  • 另外,z= z[3:] 可以被认为是远程等效的,除了它需要更多的时间,移动内存并且以后没有与z-= 3 等效的事实(缺少的元素不是没有了)。

标签: python c arrays math pointers


【解决方案1】:

Python 中类似的代码 sn-p 可能是:

def somename(z):
    i = 0
    while (....):
        a += z[i]
        b += z[i+1]
        c += z[i+2]
        i += 3

在 C 中,z 有点像数组索引,除了它从数组的起始地址开始,而不是从 0 开始。Python 中没有类似的概念,所以你需要显式使用列表索引。

(....) 中的任何内容也需要修改。我将把它作为练习留给你,因为它在问题中未指定。

【讨论】:

    【解决方案2】:

    z += 3 的意思基本上是将指针向下推进 3 个元素。假设您有一个指向 C 中名为 lst 的数组的指针,其中包含 [1, 2, 3, 4]。指针lst 指向第一个元素,使得*lst 等价于lst[0]。此外,*(lst+1) 等价于lst[1]

    【讨论】:

      【解决方案3】:

      假设 z 作为列表传递(在相应的 python 代码中)。 z += 3 可以转换为 del z[:3],它将元素 3 移动到 0。 但是在 python 中,你需要先复制数组,因为使用 del 语句,数组会被修改。

      在 C 中,您可以通过负索引访问指向索引之前的元素。这可以通过嵌套在类中的“不可见”偏移来完成。当列表被访问时,这个偏移量总是被添加到索引上。 下面的类演示了这种行为。

      class pointer_like:
          def __init__(self, lst):
              self.lst = lst; self.offset = 0
      
          # self[index]
          def __getitem__(self, index):
              return self.lst[self.offset + index]
      
          # self += offset
          def __iadd__(self, offset):
              self.offset += offset
      
          # other member functions...
      
      # as your example above
      def somename(z):
          z = pointer_like(z)
          while (....):
              a += z[0]
              b += z[1]
              c += z[2]
              z += 3
      
      >>> # other example
      >>> z = pointer_like([0, 1, 2, 3, 4, 5])
      >>> z[0]
      0
      >>> z += 3
      >>> z[0]
      3
      >>>
      >>> # with normal python lists, this would mean third last element
      >>> z[-3]
      0
      >>> z += -5
      >>> z[2]
      0
      >>>
      >>> # this is special, because z.offset is negative (-2),
      >>> # when a list item is accessed through a negative index,
      >>> # it is counted from the end of the array in python.
      >>> # In this case, it is -2, so the second last is accessed
      >>> # In C this would cause undefined behavor, on most
      >>> # platforms this causes an access violation
      >>> z[0]
      4
      

      请注意,pyhon 也有一个+= 运算符用于列表,但这允许在末尾附加另一个列表。

      【讨论】:

        猜你喜欢
        • 2011-04-01
        • 2017-11-24
        • 2016-01-31
        • 2022-11-21
        • 1970-01-01
        • 1970-01-01
        • 2013-08-30
        相关资源
        最近更新 更多