7

我有以下代码

 char ptr=new char();


 int counter = 1;
 string s = new System.String(ptr, counter);

 // does not show something
 MessageBox.Show(s+"Something");

 //shows something
 MessageBox.Show("Something" + s);

第一个消息框什么都不显示在此处输入图像描述

第二个消息框显示了一些东西在此处输入图像描述

如果计数器值为 0,则两个消息框显示相同的结果,但如果计数器大于 0,则出现问题。

我认为问题在于new string(ptr, counter)初始化

. 但我想知道为什么会发生这种情况的内部机制。

4

2 回答 2

12

ptr 内部为空。因此,当您连接时,它将打印到空字符。因此,在运行时,MessageBox.Show(s + "Something");评估为,MessageBox.Show("\0Something");而您的另一个评估为MessageBox.Show("Something\0");.

这就是为什么Something没有印在第一个上。它超过了空字符。在Wikipedia上阅读更多关于 Null-Terminated Strings (ASCIIZ) 的信息。

在内部,.NET 中的字符串只是一个struct包含长度的integer 和一个char[]数组。但是,在将其传递给 时MessageBox.Show,它会传递给 Win32 API 函数MessageBox,该函数基于 C,使用以空字符结尾的字符串。

最有可能的是,至少对于处于optimize( Release) 模式的现代编译器,编译器会看到您在字符串中添加了一个空字符,然后删除它之后的所有内容。在这种情况下,它只是\0为字符串分配。

于 2012-05-27T03:09:01.810 回答
3

new char()返回一个空字符(包含两个零字节)ptr'\0'.

当您使用s = new System.String(ptr, 0);时,构造函数将'\0'字符连接次,从而产生一个空字符串 ( "")。将空字符串添加到另一个字符串没有效果,因此s+"Something"等于"Something"+swhich is "Something"

以另一种方式, usings = new System.String(ptr, 1);创建一个包含单个'\0'字符的字符串。然后在结果之前添加此字符串,在"Something"结果"\0Something"之后添加"Something\0"

在 C# 中,字符串不会作为以 NULL 结尾的字符串进行操作,因此当您创建 时"\0Something",您确实拥有它(您可以通过取Length字符串的 10 来确定),但是MessageBox.Show会转换为MessageBoxwindows user32 库的 Win32 函数。并且该函数需要一个以 null 结尾的字符串(当遇到 unicode 字符串的零字节或两个零字节时它会停止)。

于 2012-05-27T03:45:13.817 回答