100165350.htm
来自「C#高级编程(第三版),顶死你们。。 。up」· HTM 代码 · 共 242 行 · 第 1/3 页
HTM
242 行
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> Console.WriteLine("Address of amount1 is 0x{0:X}", (uint)&amount1);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> Console.WriteLine("Address of amount2 is 0x{0:X}", (uint)&amount2);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> Console.WriteLine("Address of pAmount is 0x{0:X}", (uint)&pAmount);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> Console.WriteLine("Address of pDollars is 0x{0:X}", (uint)&pDollars);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> Console.WriteLine("Address of pCents is 0x{0:X}", (uint)&pCents);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> pAmount</span><span style="FONT-FAMILY: 宋体">–</span><span lang="EN-US">>Dollars = 20;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> *pCents = 50;</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US"> Console.WriteLine("amount1 contains " + amount1);</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">现在根据堆栈的工作方式,执行一些指针操作。由于变量是按顺序声明的,所以</span><span lang="EN-US">amount2</span><span style="FONT-FAMILY: 宋体">存储在</span><span lang="EN-US">amount1</span><span style="FONT-FAMILY: 宋体">后面紧邻的地址上,</span><span lang="EN-US">sizeof(CurrencyStruct)</span><span style="FONT-FAMILY: 宋体">返回</span><span lang="EN-US">16(</span><span style="FONT-FAMILY: 宋体">见后面的的屏幕输出</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">,所以</span><span lang="EN-US">CurrencyStruct</span><span style="FONT-FAMILY: 宋体">占用的字节数是</span><span lang="EN-US">4</span><span style="FONT-FAMILY: 宋体">的倍数。在递减了</span><span lang="EN-US">Currency</span><span style="FONT-FAMILY: 宋体">指针后,它就指向</span><span lang="EN-US">amount2</span><span style="FONT-FAMILY: 宋体">:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US"> </span><sub><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -2pt">––</span><span style="LETTER-SPACING: -2pt"> </span></sub><span lang="EN-US" style="LETTER-SPACING: -2pt"> </span><span lang="EN-US">pAmount; // this should get it to point to amount2</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> Console.WriteLine("amount2 has address 0x{0:X} and contains {1}", </span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US"> (uint)pAmount, *pAmount);</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.1pt">在调用</span><span lang="EN-US" style="LETTER-SPACING: -0.1pt">Console.WriteLine()</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.1pt">语句时,它显示了</span><span lang="EN-US" style="LETTER-SPACING: -0.1pt">amount2</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.1pt">的内容,但还没有对它进行初始化。显示出来的东西就是随机的垃圾</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -1pt">——</span><span style="LETTER-SPACING: -0.1pt"> </span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.1pt">在执行该示例前存储在内存中该单元的内容。但这有一个要点:一般情况下,</span><span lang="EN-US" style="LETTER-SPACING: -0.1pt">C#</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.1pt">编译器会禁止使用未初始化的值,但在开始使用指针时,就很容易绕过所有通常的编译检查。此时我们这么做,是因为编译器无法知道我们实际上要显示的是</span><span lang="EN-US" style="LETTER-SPACING: -0.1pt">amount2</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.1pt">的内容。因为知道了堆栈的工作方式,所以可以说出递减</span><span lang="EN-US" style="LETTER-SPACING: -0.1pt">pAmount</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.1pt">的结果是什么。使用指针算法后,可以访问各种编译器通常禁止访问的变量和存储单元,因此指针算法是不安全的。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.1pt">在示例中,接下来在</span><span lang="EN-US">pCents</span><span style="FONT-FAMILY: 宋体">指针上进行指针运算。</span><span lang="EN-US">pCents</span><span style="FONT-FAMILY: 宋体">目前指向</span><span lang="EN-US">amount1.Cents</span><span style="FONT-FAMILY: 宋体">,但此处的目的是使用指针算法让它指向</span><span lang="EN-US">amount2.Cents</span><span style="FONT-FAMILY: 宋体">,而不是直接告诉编译器我们要做什么。为此,需要从</span><span lang="EN-US">pCents</span><span style="FONT-FAMILY: 宋体">指针所包含的地址中减去</span><span lang="EN-US">sizeof(Currency)</span><span style="FONT-FAMILY: 宋体">:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US"> // do some clever casting to get pCents to point to cents</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> // inside amount2</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> CurrencyStruct* pTempCurrency = (CurrencyStruct*)pCents;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> pCents = (byte*) (</span><sub><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -2pt">––</span></sub> <span lang="EN-US">pTempCurrency );</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US"> Console.WriteLine("Address of pCents is now 0x{0:X}", (uint)&pCents);</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">最后,使用</span><span lang="EN-US">fixed</span><span style="FONT-FAMILY: 宋体">关键字创建一些指向类实例中字段的指针,使用这些指针设置这个实例的值。注意,这也是我们第一次能够查看存储在堆中</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">而不是堆栈</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">的项目地址:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US"> Console.WriteLine("\nNow with classes");</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> // now try it out with classes</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> CurrencyClass amount3 = new CurrencyClass();</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> fixed(long* pDollars2 = &(amount3.Dollars))</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> fixed(byte* pCents2 = &(amount3.Cents))</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> {</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> Console.WriteLine(</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> "amount3.Dollars has address 0x{0:X}", (uint)pDollars2);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> Console.WriteLine(</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> "amount3.Cents has address 0x{0:X}", (uint) pCents2);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> *pDollars2 = -100;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> Console.WriteLine("amount3 contains " + amount3);</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US"> }</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">编译并运行这段代码,得到如下所示的结果:</span></p>
<p class="a6" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><strong><span lang="EN-US">csc /unsafe PointerPlayaround2.cs</span></strong></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">Microsoft (R) Visual C# .NET Compiler version 7.10.3052.4</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">for Microsoft (R) .NET Framework version 1.1.4322</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">Copyright (C) Microsoft Corporation 2001</span><span style="FONT-FAMILY: 宋体">–</span><span lang="EN-US">2002. All rights reserved.</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> </span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><strong><span lang="EN-US">PointerPlayaround2</span></strong></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">Size of Currency struct is 16</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">Address of amount1 is 0x12F698</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">Address of amount2 is 0x12F688</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">Address of pAmount is 0x12F684</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">Address of pDollars is 0x12F680</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">Address of pCents is 0x12F67C</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">amount1 contains $20.50</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">amount2 has address 0x12F688 and contains $0.236</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">Address of pCents is now 0x12F67C</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> </span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">Now with classes</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">amount3.Dollars has address 0xB8850C</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">amount3.Cents has address 0x4B88514</span></p>
<p class="a6" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">amount3 contains $</span><span style="FONT-FAMILY: 宋体">–</span><span lang="EN-US">100.0</span></p>
<p class="a3" style="MARGIN-TOP: 8.15pt; FTEL: 21.45pt"><span style="FONT-FAMILY: 黑体">注意:</span></p>
<p class="a1" style="FTEL: 21.45pt"><span style="FONT-FAMILY: 楷体_GB2312">这些结果是使用</span><span lang="EN-US">.NET Framework 1.1</span><span style="FONT-FAMILY: 楷体_GB2312">版本得到的。如果在</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 楷体_GB2312">的另一个版本上运行该例子,实际显示的地址会有所不同。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">注意在这个结果中,显示了未初始化的</span><span lang="EN-US">amount2</span><span style="FONT-FAMILY: 宋体">值,</span><span lang="EN-US">CurrencyStruct</span><span style="FONT-FAMILY: 宋体">结构的字节数是</span><span lang="EN-US">16</span><span style="FONT-FAMILY: 宋体">,大于其字段的字节数</span><span lang="EN-US">(1 long(=8) + 1 byte(=1))</span><span style="FONT-FAMILY: 宋体">。这是前面讨论的对齐单词的结果。</span></p></div>
<!-- page -->
<div class="page" style="text-align: center">
<a href="100165349.htm">上一页</a> <a href="index.html">首页</a> <a href="100165351.htm">下一页</a>
</div>
<div style="margin: 0px auto; width: 700px; border: solid 1px #0b5f98;">
<div style="float: left; width: 16px; background-color: #0b5f98; color: White; padding: 1px;">
图书导读
</div>
<div style="float: right; width: 670px; text-align: left; line-height: 16pt; padding-left: 2px">
<!--导读-->
<h1 id="divCurrentNode2" style="color: #b83507; width: 100%; text-align: left; font-size: 12px; padding-left: 2px">当前章节:<a href='100165350.htm'><font color='red'>7.3.1 指针(3)</font></a></h1>
<div id="divRealteNod2" style="padding-left: 2px">
<div style='float:left;width:49%'>·<a href='100165347.htm'>7.3 不安全的代码</a></div><div style='float:right;width:49%'>·<a href='100165348.htm'>7.3.1 指针(1)</a></div><div style='float:left;width:49%'>·<a href='100165349.htm'>7.3.1 指针(2)</a></div><div style='float:right;width:49%'>·<a href='100165351.htm'>7.3.2 使用指针优化性能</a></div><div style='float:left;width:49%'>·<a href='100165352.htm'>7.4 小结</a></div><div style='float:right;width:49%'>·<a href='100165353.htm'>8.1 System.String类</a></div></div>
</div>
</div>
</div></div>
</body>
</html>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?