<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh">
	<id>https://wiki.chinulture.com/index.php?action=history&amp;feed=atom&amp;title=%E6%8C%87%E9%92%88</id>
	<title>指针 - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.chinulture.com/index.php?action=history&amp;feed=atom&amp;title=%E6%8C%87%E9%92%88"/>
	<link rel="alternate" type="text/html" href="https://wiki.chinulture.com/index.php?title=%E6%8C%87%E9%92%88&amp;action=history"/>
	<updated>2026-10-21T05:15:33Z</updated>
	<subtitle>本wiki的该页面的版本历史</subtitle>
	<generator>MediaWiki 1.31.0</generator>
	<entry>
		<id>https://wiki.chinulture.com/index.php?title=%E6%8C%87%E9%92%88&amp;diff=263754&amp;oldid=prev</id>
		<title>Test 32：1個修訂：HDwiki 数据迁移 - 批次 864</title>
		<link rel="alternate" type="text/html" href="https://wiki.chinulture.com/index.php?title=%E6%8C%87%E9%92%88&amp;diff=263754&amp;oldid=prev"/>
		<updated>2014-08-15T22:48:28Z</updated>

		<summary type="html">&lt;p&gt;1個修訂：HDwiki 数据迁移 - 批次 864&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;2014年8月15日 (五) 22:48的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;zh&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;（没有差异）&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Test 32</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.chinulture.com/index.php?title=%E6%8C%87%E9%92%88&amp;diff=263753&amp;oldid=prev</id>
		<title>2014年8月15日 (五) 22:48 Test 32</title>
		<link rel="alternate" type="text/html" href="https://wiki.chinulture.com/index.php?title=%E6%8C%87%E9%92%88&amp;diff=263753&amp;oldid=prev"/>
		<updated>2014-08-15T22:48:28Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
1.在日常生活中指针是[[仪器]]或[[钟表]]上的，可动的，一般狭长的，往往在一段尖的用来指示测量的数据的装置。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2.在信息工程中指针是一个用来指示一个内存地址的[[计算机]][[语言]]的变量或[[中央处理器]]([[CPU]])中[[寄存器]](Register)。指针一般出现在比较近机器语言的语言，如汇编语言或C语言。面向对象的语言如Java一般避免用指针。指针一般指向一个函数或一个变量。在使用一个指针时，一个[[程序]]既可以直接使用这个指针所储存的[[内存]][[地址]]，又可以使用这个地址里储存的变量或[[函数]]的值。大家都认为，c语言之所以强大，以及其自由性，很大部分体现在其灵活的指针运用上。因此，说指针是c语言的灵魂，一点都不为过。同时，这种说法也让很多人产生误解，似乎只有[[c语言]]的指针才能算指针。[[basic]]不支持指针，在此不论。其实，[[pascal]]语言本身也是支持指针的。从最初的pascal发展至今的object pascal，可以说在指针运用上，丝毫不会逊色于c语言的指针。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
指针1、内存分配[[表]] 计算机中的内存都是编址的，就像你家的地址一样。在程序编译或者运行的时候，系统（可以不关心具体是什么，可能是编译器，也可能是操作系统）开辟了一张表。每遇到一次声明语句（包括函数的传入参数的声明）都会开辟一个内存空间，并在表中增加一行纪录。记载着一些对应关系。----------------------------------------------------Declaration | ID Name Address Length----------------------------------------------------Int nP; | 1 nP 2000 2Bchar myChar; | 2 myChar 2002 1Bint *myPointer; | 3 myPointer 2003 2Bchar *myPointer2; | 4 myPointer2 2005 2B----------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2、指针就是一个整数。 指针，是一个无符号整数（unsigned int，下简写为int），它是一个以当前系统寻址范围为取值范围的整数。32 位系统下寻址能力（地址[[空间]]）是4G-bit（0~232-1)二进制表示长度为32bit，也就是4B。 int 类型也正好如此取值。 例证就是程序1 得到的答案和程序2 的答案一致。（不同机器可能需要调整一下pT 取值。）----------------------------------------------------程序1#include main(){ char *pT; char t='h'; pT= putchar(*pT);}----------------------------------------------------程序2#include main(){ char *pT; char t='h'; pT=(char *)1245048; putchar(*pT);}---------------------------------------------------- 加上(char *)是因为毕竟int 和char *不是一回事，需要强制转换，否则会有个警告。因为char *声明过的类型，一次访问1 个sizeof(char)长度，double *声明过的类型，一次访问1个sizeof(double)长度。 在汇编里int 类型和指针就是一回事了。因为不论是整数还是指针，执行自增的时候，都是其值加一。如果上文声明char *pT;，[[汇编语言]]中pT 自增之后值为1245049，可是C语言中pT++之后pT 值为1245049。如果32 位系统中， s 上文声明int *pT;，汇编语言中pT 自增之后值为1245049，可是[[C 语言]]中pT++之后pT 值为1245052。 为什么[[DOS]]下面的Turbo C，和[[Windows ]]下VC 的int 类型不一样长。因为[[DOS]]是16位的，[[Windows]] 是32 位的，可以预见，在64 位Windows 中编译，上文声明int *pT;，pT++之后pT 值为1245056。 那么，复杂的结构怎么分配空间呢？C 语言的结构体（汇编语言对应为Record 类型）按顺序分配空间。----------------------------------------------------int a[20];----------------------------------------------------typedef struct st{ double val; char c; struct st *next;} pst;----------------------------------------------------pst pT[10];---------------------------------------------------- 在32 位系统下，内存里面做如下分配（单位：H，16 进制）；----------------------------------------------------变量 2000 2001 2002 2003 2004 2005 2006 … 204C 204D 204E 204F地址 a[0] a[1] … a[19]----------------------------------------------------变量 2050 2051 … 2057 2058 2059 205A 205B 205C 205D 205E 205F地址 pst.val pst.c pst.next 无效 无效 无效---------------------------------------------------- 这就说明了为什么sizeof(pst)=16 而不是8。编译器把结构体的Size 规定为结构体成员中Size 最大的那个类型的整数倍。 至于pT 的存储，可以依例推得。总长为160，此不赘述。 有个问题，如果执行pT++，答案是什么？是自增16，还是160？别忘了，pT 是常量，不能加减。 所以，我们就可以声明：----------------------------------------------------typedef struct BinTree{ int value; struct BinTree *LeftChild; struct BinTree *RightChild;} BTree;---------------------------------------------------- 用一个整数，代表一棵树的结点。把它赋给某个结点的LeftChild/RightChild 值，就形成了上下级关系。只要无法找到一个路径，使得A-LC/RC-LC/RC...-LC/RC==A，这就构成了一棵[[二叉树]]。反之就成了[[图]]。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3、C 的按值传递 C 中函数调用是按值传递的，传入参数在子函数中只是一个初值相等的副本，无法对传入参数作任何改动。但实际编程中，经常要改动传入参数的值。这一点我们可以用传入参数的地址而不是原参数本身，当对传入参数（地址）取（*）运算时，就可以直接在内存中修改，从而改动原想作为传入参数的参数值。----------------------------------------------------#include void inc(int *val){ (*val)++;}main(){ int a=3; inc(&amp;amp;amp;a); printf(&amp;quot;%d&amp;quot; , a);}---------------------------------------------------- 在执行inc(&amp;amp;amp;a);时，系统在内存分配表里增加了一行“inc 中的val”，其地址为新地址，值为&amp;amp;amp;a。操作*val，即是在操作a 了。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4、*和&amp;amp;amp;运算 为了（*p）操作是这样一种运算，返回p 的值作为地址的那个空间的取值。（&amp;amp;amp;p）则是这样一种运算，返回当时声明p 时开辟的地址。显然可以用赋值语句对内存地址赋值。我们假设有这么两段内存地址空间，他们取值如下：（单位：H，16 进制）----------------------------------------------------地址 0000 ... 2000 2001 2002 2003 2004 ... 3000 3001 3002 3003 ...取值 ???? ... 01 30 00 00 30 00 03 20 9A---------------------------------------------------- 假设有这么一段代码：（假设开辟空间时p 被分配给了3001H、3002H 两个位置）----------------------------------------------------int *p;p=2003;*p=3001H---------------------------------------------------- **p 的值为多少？ **p=*(*(p))=*(*(2003H))=*(3000H)=0300H。 那么&amp;amp;amp;&amp;amp;amp;p、*(&amp;amp;amp;p)和&amp;amp;amp;(*p)又等于多少？ &amp;amp;amp;&amp;amp;amp;p=&amp;amp;amp;(&amp;amp;amp;(p))=&amp;amp;amp;(3001H)，此时出错了，3001H 是个常数怎么可能有地址呢？ *&amp;amp;amp;p=*(&amp;amp;amp;(p))=*(3001H)=2003H，也就是*&amp;amp;amp;p=p。 &amp;amp;amp;*p=&amp;amp;amp;(*(p))=&amp;amp;amp;(3001H)，读者可能以为&amp;amp;amp;*p=p 此时出错了，3001H 是个常数怎么可能有地址呢？&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4'、另类的*和&amp;amp;amp; 两个地方要注意： 在程序声明变量的时候的*，只是表明“它是一个整数，这个整数指向某个内存地址，一次访问sizeof(type)长度”。这点不要和(*)操作符混淆； 在C++程序声明变量的时候的&amp;amp;amp;，只是表明“它是一个引用，这个引用声明时不开辟新空间，它在内存分配表加入新的一行，该行内存地址等于和调用时传入的对应参数内存地址”。 这点不要和(*)声明符，(&amp;amp;amp;)操作符混淆。 清华大学软件学院免试研究生面试就有问过这个问题。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
5、双重指针（指向指针的指针） 双重指针又是怎么一回事儿呢？综合2 的BTree 定义，和3 的说法。对于一棵树，我们通常用它的根节点地址来表示这棵树。这就使“擒贼先擒王”。找到了树的根，其每个节点都可以找到。 但是有时候我们需要对树进行删除节点，增加节点操作，往往考虑到删除根节点，增加的节点取代原来的根节点作为新根节点的情况。为了修改根节点这个“整数”，我们需要退一步，使用这个“整数”的内存地址，也就是指向这个“整数”的指针。在声明时，我们用2 个*号，声明指向指针的指针。它的意思是“它是一个整数，这个整数指向某个内存地址，一次访问sizeof(int)长度，其值是一个整数，那个整数值指向某个内存地址，一次访问sizeof(BTree)长度。”。详见“数据结构.rar”有关“树”（06 文件夹）的程序代码。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
6、指针数组、数组指针和指向函数的指针 指针数组：就是一个整数数组，那个[[数组]]的各个元素都是[[整数]]，指向某个[[内存]]地址。 数组指针：数组名本身就是一个指针，指向数组的首地址。注意这是一个常数。 指向函数的指针：从二进制角度考虑，数组名是该数组数据段首地址，函数名就是该代码段的首地址，可以用“int *fun()”。在二进制层面，代码段和数据段什么区别？没什么区别。----------------------------------------------------#include void inc(int *val){ (*val)++;}main(){ void (*fun)(int *); int a=3; fun=inc; (*fun)(&amp;amp;amp;a); printf(&amp;quot;%d&amp;quot; , a);}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:技術應用]]&lt;/div&gt;</summary>
		<author><name>Test 32</name></author>
		
	</entry>
</feed>