📄 pointer.html
字号:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<link rel="stylesheet" href="css/stdlayout.css" type="text/css">
<link rel="stylesheet" href="css/print.css" type="text/css">
<meta content="text/html; charset=gb2312" http-equiv="content-type">
<title>指标与记忆体位址</title>
</head>
<body>
<h3><a href="http://caterpillar.onlyfun.net/GossipCN/index.html">From
Gossip@caterpillar</a></h3>
<h1><a href="CppGossip.html">C++ Gossip: 指标与记忆体位址</a></h1>
<br>
在 <a href="Variable.html">变
数</a> 中曾经说过,
变数(Variable)提供一个有名称的记忆体储存空间,一个变数关系至一个资料型态、一个变数本身的值与一个变数的位址值。<br>
<br>
变数资料型态决定了变数所分配到的记忆体大小;变数本身的值是指储存于记忆体中的某个数值,而您可以透过变数名称取得这个数值,这个数值又称为
rvalue或
read
value;而变数的位址值则是指变数所分配到的记忆体之位置,变数本身又称为lvalue或
location value。<br>
<br>
如果您想知道变数的记忆体位址为何,您可以使用&运算子,&是“取址运算子”(Address-of
operator),它可以取出变数的记忆体位址,例如: <br>
<br>
<pre>#include <iostream> <br>using namespace std; <br><br>int main() { <br> int var = 10; <br><br> cout << "变数var的值:" << var <br> << endl; <br> cout << "变数var的记忆体位址:" << &var <br> << 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);">变数var的值:10<br>
变数var的记忆体位址:0x22ff74</span><span style="color: rgb(255, 255, 255);"></span></small></td>
</tr>
</tbody>
</table>
<br>
这个程式中,您宣告了一个int整数变数var,var指向的记忆体位址是0xbffff384,这是记忆体位址的16进位表示法,从
0xbffff384后的4个位元组都是var所配置到的记忆体空间,现在这个空间中储存值为10。<br>
<br>
直接存取变数即直接对所分配到的记忆体空间作存取,指标(Pointer)则提供了间接性,指标可指向特定的记忆体位址,而不直接操作变数或物件,要宣告
一个指标,使用以下的语法:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">type *ptr;</span><br>
</div>
<br>
其中type是指标的型态,每一个指标都有一个相对应的型态,用以指出所指向的资料或物件之型态有所不同,编译器根据指标型态来确定特定记忆体位址上的资
料如何解释,以及如何进行指标运算(Pointer arithmetic),以下是几个指标宣告的范例:<br>
<div style="margin-left: 40px;"><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;">float *fptr;</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">char *cptr;</span><br>
</div>
<br>
您可以使用&运算子取出变数的位址值并指定给指标,例如:<br>
<br>
<pre>#include <iostream> <br>using namespace std; <br><br>int main() { <br> int var = 10; <br> int *ptr = &var ; <br><br> cout << "变数var的位址:" << &var <br> << endl; <br> cout << "指标ptr指向的位址:" << ptr <br> << 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);">变数var的位址:0x22ff74<br>
指标ptr指向的位址:0x22ff74</span><span style="color: rgb(255, 255, 255);"></span></small></td>
</tr>
</tbody>
</table>
<br>
如以上的程式结果所示,您使用&来取出变数var所指向的记忆体位址,然后将这个位址指定给指标ptr,因此ptr所储存的值就与&
var所取出的值相同。 <br>
<br>
指标拥有两种操作特性,一是操作指标所储存的位址,一是操作指标所指向位址之资料,或是操作指向的位址上之物件,您可以使用提取
(Dereference)运算子*来提取指标所指向位址的资料,例如:<br>
<br>
<pre>#include <iostream> <br>using namespace std; <br><br>int main() { <br> int var = 10; <br> int *ptr = &var;<br><br> cout << "指标ptr储存的值:" << ptr<br> << endl; <br> cout << "取出ptr指向的记忆体位置之值:" << *ptr <br> << endl;<br> <br> system("pause");<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);">指标ptr储存的值:0x22ff74<br>
取出ptr指向的记忆体位置之值:10</span><span style="color: rgb(255, 255, 255);"></span></small></td>
</tr>
</tbody>
</table>
<br>
如果已经取得了记忆体位置,当将某个值指定给*prt时,该记忆体位置的值也会跟着改变,相当于告诉程式,将值放到ptr所指向的记忆体位址,例如: <br>
<br>
<pre>#include <iostream> <br>using namespace std; <br><br>int main() { <br> int var = 10; <br> int *ptr = &var ; <br><br> cout << "var = " << var <br> << endl; <br> cout << "*ptr = " << *ptr <br> << endl; <br><br> *ptr = 20; <br><br> cout << "var = " << var <br> << endl;<br> cout << "*ptr = " << *ptr <br> << 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);">var = 10<br>
*ptr = 10<br>
var = 20<br>
*ptr = 20</span><span style="color: rgb(255, 255, 255);"></span></small></td>
</tr>
</tbody>
</table>
<br>
如以上所表示的,当指标ptr所储存的值与变数var所指向的记忆体位置相同时,当您对*ptr进行指定的动作时,就会将值直接存入该记忆体位置,因此再
透过变数var所取出的值也就改变了。 <br>
<br>
如果宣告指标但不指定初值,则指标指向的位址是未知的,存取未知位址的记忆体内容是危险的,例如:<br>
<div style="margin-left: 40px;"><span style="font-weight: bold; font-family: Courier New,Courier,monospace;">int *ptr; </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace;">
<span style="font-weight: bold; font-family: Courier New,Courier,monospace;">*ptr = 10;</span><br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -