好吧,所以这一切都始于我对哈希码的兴趣.在Jon Skeet的一篇文章中做了一些阅读后,我问了这个问题.这让我对指针算法非常感兴趣,这是我几乎没有经验的.所以,在阅读完这个页面后,我开始尝试,因为我从那里得到了一个基本的理解,我的其他很棒的同行在这里!
现在我正在做更多的实验,我相信我已经准确地复制了string
下面实现中的哈希码循环(我保留了错误的权利):
Console.WriteLine("Iterating STRING (2) as INT ({0})", sizeof(int)); Console.WriteLine(); var val = "Hello World!"; unsafe { fixed (char* src = val) { var ptr = (int*)src; var len = val.Length; while (len > 2) { Console.WriteLine((char)*ptr); Console.WriteLine((char)ptr[1]); ptr += 2; len -= sizeof(int); } if (len > 0) { Console.WriteLine((char)*ptr); } } }
但是,结果对我来说有点困惑; 的种类.结果如下:
Iterating STRING (2) as INT (4) H l o W r d
我原来认为,值ptr[1]
是第二个与第一个字母一起读取(或挤压在一起)的字母.但是,显然不是这样.那是因为ptr[1]
技术上第一次迭代是字节4而第二次迭代是字节12吗?
你的问题是你正在将指针转换为一个int*
指针..这是32位..而不是16 char*
.
因此,每个增量是32位.这是一张照片(如果你必须赞美我的作品):
抱歉躲闪箭头......我想我的老鼠电池正在奄奄一息
当你通过char
指针阅读时......你正在逐字符地读取16位.
当你把它转换为int
指针时......你正在以32位的增量读取.这意味着,ptr[0]
是H
和e
(并指向基础H
).ptr[1]
两个都是l
......
这就是为什么你实际上是在输出中跳过一个字符.
当你把它投回到char
这里:
Console.WriteLine((char)*ptr);
..只有前16位才会产生转换,这是每对中的第一个字符.