Python中的C指针运算

4 投票
3 回答
2869 浏览
提问于 2025-04-16 15:14

我正在尝试把一个简单的C程序转换成Python,但因为我对C一无所知,对Python也只懂一点,所以这对我来说很困难。

我卡在了C语言的指针上。

有一个函数,它接受一个无符号长整型的指针,并在一个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中实现这个功能。

3 个回答

0

假设 z 是以列表的形式传入的(在对应的 Python 代码中)。z += 3 可以理解为 del z[:3],这意味着把列表中的前三个元素移到开头。不过在 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

需要注意的是,Python 也有一个 += 操作符用于列表,但这个操作符是用来在列表末尾添加另一个列表的。

1

这里的 z += 3 的意思就是把指针向下移动3个元素。假设你在C语言中有一个指向数组的指针,叫做 lst,这个数组的内容是 [1, 2, 3, 4]。指针 lst 指向第一个元素,所以 *lst 就相当于 lst[0]。而 *(lst+1) 就相当于 lst[1]

10

在Python中,类似的代码片段可能是:

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

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

(....)里面的内容也需要修改。我就不多说了,留给你自己去练习,因为问题中没有具体说明。

撰写回答