📄 pointer.html
字号:
</div>
<br>
<br>
这个程式片段并未初始指标就指定值给*ptr,所以会造成不可预知的结果(通常是记忆体区段错误),最好为指标设定初值,如果指标一开始不指向任何的物
件,则可设定初值为0,表示不指向任何物件,例如:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">int *iptr = 0;</span><br>
</div>
<br>
在这边必须注意一个指标宣告常犯的错误,在指标宣告时,可以靠在名称旁边,也可以靠在关键字旁边,例如: <br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">int *ptr1; </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">int* ptr2;</span><br>
</div>
<br>
这两个宣告方式都是可允许的,一般比较倾向用第一个,因为可以避免以下的错误:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">int* prt1, ptr2;</span><br>
</div>
<br>
这样的宣告方式,初学者可能以为ptr2也是指标,但事实上并不是,以下的宣告ptr1与ptr2才都是指标:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">int *ptr1, *ptr2;</span><br>
</div>
<br>
有时候,您只希望储存记忆体的位址,然后将之与另一个记忆体位址作比较,这时并不需要关心型态的问题,您可以使用void*来宣告指标,例如: <br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">void* ptr;</span><br>
</div>
<br>
由于void型态的指标没有任何的型态资讯,所以只用来持有位址资讯,您不可以使用*运算子对void型态指标提取值,而必须使用
reinterpret_cast作转型动作至对应的型态,例
如:<br>
<br>
<pre>#include <iostream> <br>using namespace std; <br><br>int main() { <br> int var = 10; <br> void *vptr = &var ; <br> <br> // 下面这句不可行,void型态指标不可取值 <br> //cout << *vptr << endl;<br> <br> // 转型为int型态指标并指定给iptr <br> int *iptr = reinterpret_cast<int*>(vptr);<br> cout << *iptr << endl; <br> <br> return 0; <br>}<br></pre>
<br>
执行结果: <br>
<small> </small><small> </small><small> </small><small> </small><small>
</small>
<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="background-color: rgb(0, 0, 0);"><small><span style="color: rgb(255, 255, 255);">10</span><span style="color: rgb(255, 255, 255);"></span></small></td>
</tr>
</tbody>
</table>
<br>
您也可以使用旧风格的转型语法,如下所示:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">int var = 10; </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">void *vptr =
&var ; </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">//
转型为int型态指标并指定给iptr </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">int *iptr =
(int*)(vptr);</span><br>
</div>
<br>
顺便来看一下const宣告的变数,被const宣告的变数一但被指定值,就不能再改变变数的值,您也无法对该变数如下取值:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">const int var = 10;</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">var = 20; //
error, assignment of read-only variable `var' </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">int *ptr =
&var; // error, invalid conversion from `const int*' to
`int*' </span><br>
</div>
<br>
用const宣告的变数,必须使用对应的const型态指标才可以:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">const int var = 10;</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">const int *vptr =
&var;</span><br>
</div>
<br>
同样的vptr所指向的记忆体中的值一但指定,就不能再改变记忆体中的值,您不能如下试图改变所指向记忆体中的资料:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">*vptr = 20; // error,
assignment of read-only location </span><br>
</div>
<br>
另外还有指标常数,也就是您一旦指定给指标值,就不能指定新的记忆体位址值给它,例如:<br>
<div style="margin-left: 40px;"><span style="font-family: Courier New,Courier,monospace; font-weight: bold;">int x = 10;</span><br style="font-family: Courier New,Courier,monospace; font-weight: bold;">
<span style="font-family: Courier New,Courier,monospace; font-weight: bold;">
int y = 20;</span><br style="font-family: Courier New,Courier,monospace; font-weight: bold;">
<span style="font-family: Courier New,Courier,monospace; font-weight: bold;">
int* const vptr = &x;</span><br style="font-family: Courier New,Courier,monospace; font-weight: bold;">
<span style="font-family: Courier New,Courier,monospace; font-weight: bold;">
vptr = &x; // error, assignment of read-only variable `vptr' </span><br>
</div>
<span style="font-style: italic;"><span style="font-weight: bold;"><br>
</span></span>
在某些情况下,您会想要改变唯读区域的值,这时您可以使用const_cast改变指标的型态,例如:<br>
<br>
<pre>#include <iostream> <br>using namespace std; <br><br>void foo(const int*); <br> <br>int main() { <br> int var = 10; <br> <br> cout << "var = " << var << endl; <br> <br> foo(&var); <br> <br> cout << "var = " << var << endl; <br> <br> return 0; <br>}<br><br>void foo(const int* p) {<br> int* v = const_cast<int*> (p); <br> *v = 20; <br>}<br></pre>
<br>
由于函式(Function)定义中传入的指标使用const加上唯读性,所以您不能对传入的指标进行以下的动作:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">*p = 20; // error, assignment
of read-only location</span><span style="font-weight: bold; font-style: italic;"> </span></div>
<br>
但在某种原因下,您真的必须改变指标指向的位址处之资料,则您可以使用const_cast改变指标的唯读性,<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">int* v =
const_cast<int*> (p); </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">*v = 20; </span><br>
</div>
<br>
执行结果: <br>
<small> </small><small> </small><small> </small><small> </small><small>
</small>
<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="background-color: rgb(0, 0, 0);"><small><span style="color: rgb(255, 255, 255);">var = 10<br>
var = 20</span></small></td>
</tr>
</tbody>
</table>
<br>
您也可以使用旧风格的转型语法,例如:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">void foo(const
int* p) {</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">
int* v = (int*) (p); </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">
*v = 20; </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">}</span><br>
</div>
<br>
关于函式的定义与使用,在之后还会介绍。<br>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -