100165349.htm
来自「C#高级编程(第三版),顶死你们。。 。up」· HTM 代码 · 共 260 行 · 第 1/3 页
HTM
260 行
<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" style="FTEL: 0cm"><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">MyStruct* pStruct;</span></p>
<p class="MsoNormal" style="FTEL: 0cm"><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">MyStruct Struct = new MyStruct();</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">pStruct = &Struct;</span></p>
<p class="MsoNormal" style="FTEL: 0cm"><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">(*pStruct).X = 4;</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">(*pStruct).F = 3.4f;</span></p>
<p class="MsoNormal" style="FTEL: 0cm"><span style="FONT-FAMILY: 宋体">但是,这个语法有点复杂。因此,</span><span lang="EN-US">C#</span><span style="FONT-FAMILY: 宋体">定义了另一个运算符,用一种比较简单的语法,通过指针访问结构的成员,该语法称为指针成员访问运算符,其符号是一个短划线,后跟一个大于号:–</span><span lang="EN-US">></span><span style="FONT-FAMILY: 宋体">。</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 lang="EN-US">C++</span><span style="FONT-FAMILY: 楷体_GB2312">开发人员会认出指针成员访问操作符。因为</span><span lang="EN-US">C++</span><span style="FONT-FAMILY: 楷体_GB2312">使用这些符号完成相同的任务。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">使用这个指针成员访问运算符,上述代码可以重写为:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><a ftel="arrow"><span lang="EN-US">pStruct</span></a><span style="FONT-FAMILY: 宋体">–</span><span lang="EN-US">>X = 4;</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">pStruct</span><span style="FONT-FAMILY: 宋体">–</span><span lang="EN-US">>F = 3.4f;</span></p>
<p class="MsoNormal" style="FTEL: 0cm"><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">long* pL = &(Struct.X);</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">float* pF = &(Struct.F);</span></p>
<p class="MsoNormal" style="FTEL: 0cm"><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">long* pL = &(pStruct</span><span style="FONT-FAMILY: 宋体">–</span><span lang="EN-US">>X);</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">float* pF = &(pStruct</span><span style="FONT-FAMILY: 宋体">–</span><span lang="EN-US">>F);</span></p>
<h4 style="FTEL: 21.45pt"><span lang="EN-US">9. </span><span style="FONT-FAMILY: 黑体">类成员指针</span></h4>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">前面说过,不能创建指向类的指针,这是因为垃圾收集器不包含指针的任何信息,只包含引用的信息,因此创建指向类的指针会使垃圾收集器不能正常工作。</span></p>
<p class="MsoNormal"><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">class MyClass</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"> public long X;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> public float F;</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" style="FTEL: 0cm"><span style="FONT-FAMILY: 宋体; LETTER-SPACING: 0.1pt">然后就可以为它的字段</span><span lang="EN-US" style="LETTER-SPACING: 0.1pt">X</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: 0.1pt">和</span><span lang="EN-US" style="LETTER-SPACING: 0.1pt">F</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: 0.1pt">创建指针了,方法与前面一样。但这么做会抛出一个编译</span><span lang="EN-US" style="LETTER-SPACING: 0.1pt"> </span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: 0.1pt">错误:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><a ftel="pointersfields"><span lang="EN-US">MyClass myObject = new MyClass();</span></a></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">long* pL = &( myObject.X); // wrong– –compilation error</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">float* pF = &( myObject.F); // wrong– –compilation error</span></p>
<p class="MsoNormal"><span lang="EN-US">X</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US">F</span><span style="FONT-FAMILY: 宋体">本身都是非托管类型,它们嵌入在一个对象中,存储在堆上。在垃圾收集的过程中,垃圾收集器会把</span><span lang="EN-US">MyClass</span><span style="FONT-FAMILY: 宋体">移动到内存的一个新单元上,这样,</span><span lang="EN-US"> pL</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US">pF</span><span style="FONT-FAMILY: 宋体">就会指向错误的存储单元。由于存在这个问题,所以编译器不允许以这种方式把托管类型的成员地址分配给指针。</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">fixed</span><span style="FONT-FAMILY: 宋体">的语法如下所示:</span></p>
<p class="a6" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><a ftel="fixed"><span lang="EN-US">MyClass myObject = new MyClass();</span></a></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">fixed (long* pObject = &( myObject.X))</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"> // do something</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" style="FTEL: 0cm"><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">pObject)</span><span style="FONT-FAMILY: 宋体">现在就在</span><span lang="EN-US">fixed</span><span style="FONT-FAMILY: 宋体">块的作用域内,这样,垃圾收集器知道,在执行</span><span lang="EN-US">fixed</span><span style="FONT-FAMILY: 宋体">块中的代码时,不能移动</span><span lang="EN-US">MyObject</span><span style="FONT-FAMILY: 宋体">对象。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">如果要声明多个这样的指针,可以在同一个代码块前放置多个</span><span lang="EN-US">fixed</span><span style="FONT-FAMILY: 宋体">语句:</span></p>
<p class="a6" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">MyClass myObject = new MyClass();</span></p>
<p class="2" style="MARGIN-TOP: 6pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">fixed (long* pX = &( myObject.X))</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">fixed (float* pF = &( myObject.F))</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"> // do something</span></p>
<p class="a6" 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><span lang="EN-US">fixed</span><span style="FONT-FAMILY: 宋体">块:</span></p>
<p class="a6" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">MyClass myObject = new MyClass();</span></p>
<p class="2" style="MARGIN-TOP: 6pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">fixed (long* pX = &( myObject.X))</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"> // do something with pX</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> fixed (float* pF = &( myObject.F))</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"> // do something else with pF</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> }</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><span lang="EN-US">fixed</span><span style="FONT-FAMILY: 宋体">语句中初始化多个变量,但这些变量的类型必须相同:</span></p>
<p class="a6" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><a ftel="OLE_LINK9"><span lang="EN-US">MyClass myObject = new MyClass();</span></a></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">MyClass myObject2 = new MyClass();</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">fixed (long* pX = &( myObject.X), pX2 = &( myObject2.X))</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">{</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US"> // etc.</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">在上述情况中,是否声明不同的指针,让它们指向相同或不同对象中的字段,或者指向不与类实例相关的静态字段,这一点是不重要的。</span></p></div>
<!-- page -->
<div class="page" style="text-align: center">
<a href="100165348.htm">上一页</a> <a href="index.html">首页</a> <a href="100165350.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='100165349.htm'><font color='red'>7.3.1 指针(2)</font></a></h1>
<div id="divRealteNod2" style="padding-left: 2px">
<div style='float:left;width:49%'>·<a href='100165346.htm'>7.2 释放未托管的资源</a></div><div style='float:right;width:49%'>·<a href='100165347.htm'>7.3 不安全的代码</a></div><div style='float:left;width:49%'>·<a href='100165348.htm'>7.3.1 指针(1)</a></div><div style='float:right;width:49%'>·<a href='100165350.htm'>7.3.1 指针(3)</a></div><div style='float:left;width:49%'>·<a href='100165351.htm'>7.3.2 使用指针优化性能</a></div><div style='float:right;width:49%'>·<a href='100165352.htm'>7.4 小结</a></div></div>
</div>
</div>
</div></div>
</body>
</html>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?