理解C函数进行C#翻译
我正在检查一些从C翻译成C的代码。我对原文C有一个问题:理解C函数进行C#翻译,c#,c,code-translation,C#,C,Code Translation,我正在检查一些从C翻译成C的代码。我对原文C有一个问题: ... #define getblock(p, i) (p[i]) ... void MurmurHash3_x86_32 ( const void * key, int len, uint32_t seed, void * out ) { const uint8_t * data = (const uint8_t*)key; const int nblocks = len /
...
#define getblock(p, i) (p[i])
...
void MurmurHash3_x86_32 ( const void * key, int len,
uint32_t seed, void * out )
{
const uint8_t * data = (const uint8_t*)key;
const int nblocks = len / 4;
int i;
uint32_t h1 = seed;
uint32_t c1 = 0xcc9e2d51;
uint32_t c2 = 0x1b873593;
const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
for(i = -nblocks; i; i++)
{
uint32_t k1 = getblock(blocks,i);
...
(i=-nblocks;i;i++)的
部分是向后循环数据吗?我从未见过使用负索引引用的数据。事实上,这是一种使用哈希()的算法,您的源代码可能就是该算法;) 通过nblocks
(假设sizeof(uint32\u t)==4)在数据之前初始化块
变量。然后
的循环从数据的开头开始
到块所指向的结尾
,因此使用负索引。因此,它不是向后循环数据,而是向前循环。不,它不是向后循环数据。它从数据的开头开始,并向上索引
如您所见,这里的指针“blocks”已经超过了“data”。它将“nblocks”指向数据的开头
const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
因此,需要一个负索引才能到达数据的开头(-n块)。数据的起始位置正是“blocks[-nblocks]”。“for”循环就从这里开始,然后开始计数
for(i = -nblocks; i; i++)
为什么不调试它或者在每个循环开始时打印出i
,看看会发生什么?这应该会让行为变得非常清楚。我正在Visual Studio下用C#编写。我相信源代码是GNUC。所以你根本没有办法执行原始代码?如果你在重写,我会想办法解决的;您应该能够运行正在翻译的代码片段,以帮助您更好地理解它在做什么。根本不能执行任何C代码更糟糕,而且不应该太难补救。你是对的。我只是想知道这个函数是否有一个简单的解释。是的,但我的观点是,你应该能够通过执行它自己弄清楚这一点,即使你仅仅通过阅读它不理解它做什么,或者至少你应该能够通过运行它来确认你的猜测。如果你在这里做不到这一点,它只会使翻译中不太复杂的方面变得更难解决。我有一个不同的来源,但我相信这个算法是相当标准的。wiki文章暗示它正在向前(我之前看到过),但您确认它正在向后,剩余部分在输入的开头,对吗?#define
到底是为了什么?为什么他们不直接说p[i]
?有趣的是,128位哈希向后运行,而32位哈希向前运行。我同意它向前运行。但你为什么要这样做?通过显式地指向数据的末尾,然后使用负索引进行遍历,您获得了什么?他正在处理一些遗留代码。一些程序员决定这样做。嗯,是的。但是为什么呢?为什么会有人这么做?这项技术有什么好处吗?或者这纯粹是因为他们认为自己很聪明?想不出这样做有什么好处。@ElchononEdelson:这是一个愚蠢的微观优化。有人认为在一个紧密的循环中,与零比较比比较两个变量要快。