Python 如何在Cython中创建无循环的空字符数组
嗯,这似乎很容易,但我在网上找不到任何参考资料。在C中,我们可以创建一个包含Python 如何在Cython中创建无循环的空字符数组,python,c,cython,Python,C,Cython,嗯,这似乎很容易,但我在网上找不到任何参考资料。在C中,我们可以创建一个包含n空字符的char数组,如下所示: char arr[n] = ""; 但是当我试着在Cython和 cdef char arr[n] = "" 我发现这个编译错误: Error compiling Cython file: ------------------------------------------------------------ ... cdef char a[n] = ""
n
空字符的char
数组,如下所示:
char arr[n] = "";
但是当我试着在Cython和
cdef char arr[n] = ""
我发现这个编译错误:
Error compiling Cython file:
------------------------------------------------------------
...
cdef char a[n] = ""
^
------------------------------------------------------------
Syntax error in C variable declaration
显然Cython不允许以这种方式声明数组,但是有其他方法吗?我不想手动设置数组中的每个项,也就是说,我不想找这样的东西
cdef char a[10]
for i in range(0, 10, 1):
a[i] = b"\0"
那么:
cdef char *arr = ['\0']*n
在C中,“”用于字符,“”用于字符串。但是任何“空字符”都没有真正意义,可能您想要的是“\0”或仅仅是0
也许:
import cython
from libc.stdlib cimport malloc, free
cdef char * test():
n = 10
cdef char *arr = <char *>malloc(n * sizeof(char))
for n in range(n):
arr[n] = '\0'
return arr
为您做到这一点,您不必将每个元素设置为长度为零的C字符串。仅将第一个元素归零即可:
cdef char arr[n]
arr[0] = 0
接下来,如果要将整个字符数组归零,请使用memset
from libc.string cimport memset
cdef char arr[n]
memset(arr, 0, n)
如果C纯粹主义者抱怨0而不是“\0”,请注意“\0”是Cython中的Python字符串(Python 3中的unicode)\0'在Cython中不是C字符!memset的第二个参数需要一个整数值,而不是Python字符串
如果您确实想知道Cython中C'\0'的int值,则必须在C中编写一个helper函数:
/* zerochar.h */
static int zerochar()
{
return '\0';
}
现在:
cdef extern from "zerochar.h":
int zerochar()
cdef char arr[n]
arr[0] = zerochar()
或
您没有得到
n
空字符。还有,你的在哪里代码>s?我刚刚测试过它,我确实在C代码中得到了n个\0
字符。我相信这会在内存中创建一个临时的Python列表,这个列表速度很慢,一般来说并不好,因为它会损害Cython中纯C代码的nogil
语义。如果没有,我很乐意接受你的答案。我想更重要的是,这个答案a)不会编译(至少在Cython的最新版本中是这样),b)如果它确实编译了,将创建一个指向python对象的指针,而python对象很快就不存在了(这就是它不编译的原因)。我告诉过你,我不是在寻找手动执行此操作的方法(使用循环)。您没有太多选择,如果您使用arr=“”,那么只有arr[0]将是\0,其余的将被内存中以前存在的垃圾填充。另一个答案提供了一个隐式循环的解决方案(python为您提供)['\0']*n但这是一个简洁的方法,而且速度相当快。你的回答让我回忆起calloc
,这一行就完成了。好吧,你的答案最接近我想要的。我完全忘记了memset
。非常感谢你的回答。
cdef extern from "zerochar.h":
int zerochar()
cdef char arr[n]
arr[0] = zerochar()
cdef extern from "zerochar.h":
int zerochar()
from libc.string cimport memset
cdef char arr[n]
memset(arr, zerochar(), n)