<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>引用类型</title>
	<atom:link href="https://www.aitaocui.cn/tag/213575/feed" rel="self" type="application/rss+xml" />
	<link>https://www.aitaocui.cn</link>
	<description>翡翠玉石爱好者聚集地</description>
	<lastBuildDate>Thu, 24 Nov 2022 21:41:16 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.1.1</generator>

<image>
	<url>https://www.aitaocui.cn/wp-content/uploads/2022/11/taocui.png</url>
	<title>引用类型</title>
	<link>https://www.aitaocui.cn</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>引用类型(c++变量类型)</title>
		<link>https://www.aitaocui.cn/article/325151.html</link>
					<comments>https://www.aitaocui.cn/article/325151.html#respond</comments>
		
		<dc:creator><![CDATA[猩猩影视]]></dc:creator>
		<pubDate>Thu, 24 Nov 2022 21:41:16 +0000</pubDate>
				<category><![CDATA[百科]]></category>
		<category><![CDATA[引用类型]]></category>
		<guid isPermaLink="false">https://www.aitaocui.cn/?p=325151</guid>

					<description><![CDATA[由类型的实际值引用（类似于指针）表示的数据类型。如果为某个变量分配一个引用类型，则该变量将引用（或“指向”）原始值。不创建任何副本。引用类型包括类、接口、委托和装箱值类型。 基本内...]]></description>
										<content:encoded><![CDATA[</p>
<article>
<p>由类型的实际值引用（类似于指针）表示的数据类型。如果为某个变量分配一个引用类型，则该变量将引用（或“指向”）原始值。不创建任何副本。引用类型包括类、接口、委托和装箱值类型。</p>
</article>
<article>
<h1>基本内容</h1>
<p>由类型的实际值引用（类似于指针）表示的数据类型。如果为某个变量分配一个引用类型，则该变量将引用（或“指向”）原始值。不创建任何副本。引用类型包括类、接口、委托和装箱值类型。</p>
<p>一些计算机高级语言有引用类型这种变量类型。</p>
<p>一、C语言中没有引用类型。</p>
<p>二、C++中的引用类型：</p>
<p>“引用”（reference）是c++的一种新的变量类型，是对C的一个重要补充。它的作用是为变量起一个别名。假如有一个变量a，想给它起一个别名，可以这样写：</p>
<p>int a;int&amp;b=a;</p>
<p>这就表明了b是a的“引用”，即a的别名。经过这样的声明，使用a或b的作用相同，都代表同一变量。在上述引用中，&amp;是“引用声明符”，并不代表地址。</p>
<p>不要理解为“吧a的值赋给b的地址”。声明引用并不开辟内存单元，b和a都代表同一变量单元。</p>
<p>注意：在声明引用变量类型时，必须同时使之初始化，及声明它代表哪一变量。在声明一个变量的引用之后，在本函数执行期间，该引用一直与其代表的变量相联系，不能再作为其他变量的别名。下面的用法不对：</p>
<p>int a1,a2;</p>
<p>int&amp;b=a1;</p>
<p>b=a2;//企图使b变成a2的别名（引用）是不行的。</p>
<p>例1：</p>
<p>#include</p>
<p>#include</p>
<p>void main()</p>
<p>{</p>
<p>int a=10;</p>
<p>int&amp;b=a;//声明b是a的引用,这样a的值变以后，b的值也变；b的值变以后，a的值也跟着变。</p>
<p>a=a*a;</p>
<p>cout&lt;</p>
<p>b=b/5;</p>
<p>cout&lt;</p>
<p>}</p>
<p>有了变量名，为什么还需要一个别名呢？C++之所以增加“引用”，主要是把它作为函数参数，以扩充函数传递数据的功能。</p>
<p>我们知道，在C语言中，函数参数传递是单向的，所以例4不能实现两个变量值的交换。C语言中，数组作为函数参数传递的是数组的首地址。</p>
<p>C语言中，还可以利用指针变量做形参来实现两个变量值的换，但这种方式需要定义指针变量，需要额外开辟存储空间，来存放地址，见例3。而引用变量不是独立的变量，不单独占内存单元这种方法，实参向形参传送的是实参的地址(但与指针不同的是掉用函数时不需要&amp;)，而不是实参的值，见例2。</p>
<p>看到&amp;a这种形式时，怎样区分是指针还是引用呢？一般而言，见到前面有类型说明符（如int&amp;a），是引用，而前面没有类型说明符时（如&amp;a）认为是指针。</p>
<p>例2：</p>
<p>//函数参数传递之引用调用</p>
<p>#include</p>
<p>void swap(int&amp;a,int&amp;b)</p>
<p>{</p>
<p>int temp;</p>
<p>temp=a;</p>
<p>a=b;</p>
<p>b=temp;</p>
<p>}</p>
<p>void main()</p>
<p>{</p>
<p>int i=3,j=5;</p>
<p>swap(i,j);</p>
<p>cout&lt;&lt;&quot;i=&quot;&lt;</p>
<p>cout&lt;&lt;&quot;j=&quot;&lt;</p>
<p>}</p>
<p>例3：</p>
<p>//函数参数传递之传地址调用（通过指针）</p>
<p>#include</p>
<p>void swap(int*a,int*b)</p>
<p>{</p>
<p>int temp;</p>
<p>temp=*a;</p>
<p>*a=*b;</p>
<p>*b=temp;</p>
<p>}</p>
<p>void main()</p>
<p>{</p>
<p>int i=3,j=5;</p>
<p>swap(&amp;i,&amp;j);</p>
<p>cout&lt;&lt;&quot;i=&quot;&lt;</p>
<p>cout&lt;&lt;&quot;j=&quot;&lt;</p>
<p>}</p>
<p>例4：</p>
<p>//错误程序例：这个程序不能实现i和j值的交换。</p>
<p>#include</p>
<p>void swap(int a,int b)</p>
<p>{</p>
<p>int temp;</p>
<p>temp=a;</p>
<p>a=b;</p>
<p>b=temp;</p>
<p>}</p>
<p>void main()</p>
<p>{</p>
<p>int i=3,j=5;</p>
<p>swap(i,j);</p>
<p>cout&lt;&lt;&quot;i=&quot;&lt;</p>
<p>cout&lt;&lt;&quot;j=&quot;&lt;</p>
<p>}</p>
<p>备注：注意C++中引用类型与类的区别。</p>
<p>参考文献：东北大学出版社-李一波编着《新概念C语言》218页</p>
<p>清华大学出版社陈天华编着《面向对象程序设计与VisualC++教程》73页</p>
<p>三、C#中也有引用类型。</p>
<h1>区别</h1>
<p>看实例吧：</p>
<p>引用是C++中的概念，初学者容易把引用和指针混淆一起。</p>
<p>下面的程序中，n是m的一个引用（reference），m是被引用物（referent）。</p>
<p>int m;</p>
<p>int&amp;n=m;</p>
<p>n相当于m的别名（绰号），对n的任何操作就是对m的操作。</p>
<p>所以n既不是m的拷贝，也不是指向m的指针，其实n就是m它自己。</p>
<h1>引用的规则</h1>
<p>（1）引用被创建的同时必须被初始化（指针则可以在任何时候被初始化）。</p>
<p>（2）不能有NULL引用，引用必须与合法的存储单元关联（指针则可以是NULL）。</p>
<p>（3）一旦引用被初始化，就不能改变引用的关系（指针则可以随时改变所指的对象）。</p>
<p>以下示例程序中，k被初始化为i的引用。</p>
<p>语句k=j并不能将k修改成为j的引用，只是把k的值改变成为6。</p>
<p>由于k是i的引用，所以i的值也变成了6。</p>
<p>int i=5;</p>
<p>int j=6;</p>
<p>int&amp;k=i;</p>
<p>k=j;//k和i的值都变成了6；</p>
<h1>主要功能</h1>
<p>在C++中可以定义“引用”。定义方式如下：类型名&amp;引用名=同类型的某变量名;</p>
<p>引用的主要功能：传递函数的参数和返回值。</p>
<p>C++语言中，函数的参数和返回值的传递方式有三种：值传递、指针传递和引用传递。</p>
<p>以下是&quot;值传递&quot;的示例程序。</p>
<p>由于Func1函数体内的x是外部变量n的一份拷贝，改变x的值不会影响n,所以n的值仍然是0。</p>
<p>void Func1(int x)</p>
<p>{</p>
<p>x=x+10;</p>
<p>}</p>
<p>&#8230;</p>
<p>int n=0;</p>
<p>Func1(n);</p>
<p>cout&lt;&lt;&quot;n=&quot;&lt;&lt;n=&quot;0&quot;n=&quot;0;&quot;n=&quot;&lt;&lt;n&lt;&lt;endl;//n=10以下是&quot;size=&quot;14&quot;&gt;</p>
<p>void Func3(int&amp;x){x=x+10;}&#8230;int n=0;Func3(n);cout&lt;&lt;&quot;n=&quot;&lt;&lt;n=&quot;10&quot;&gt;</p>
<p>（1）在实际的程序中，引用主要被用做函数的形式参数&#8211;通常将类对象传递给一个函数.引用必须初始化.但是用对象的地址初始化引用是错误的，我们可以定义一个指针引用。</p>
<p>1int ival=1092;</p>
<p>2int&amp;re=ival;//ok</p>
<p>3int&amp;re2=&amp;ival;//错误</p>
<p>4int*pi=&amp;ival;</p>
<p>5int*&amp;pi2=pi;//ok</p>
<p>（2）一旦引用已经定义，它就不能再指向其他的对象.这就是为什么它要被初始化的原因。</p>
<p>（3）const引用可以用不同类型的对象初始化(只要能从一种类型转换到另一种类型即可)，也可以是不可寻址的值，如文字常量。例如：</p>
<p>double dval=3.14159;</p>
<p>//下3行仅对const引用才是合法的</p>
<p>const int&amp;ir=1024;</p>
<p>const int&amp;ir2=dval;</p>
<p>const double&amp;dr=dval+1.0;</p>
<p>上面，同样的初始化对于非const引用是不合法的，将导致编译错误。原因有些微妙，需要适当做些解释。</p>
<p>引用在内部存放的是一个对象的地址，它是该对象的别名。对于不可寻址的值，如文字常量，以及不同类型的对象，编译器为了实现引用，必须生成一个临时对象，引用实际上指向该对象，但用户不能访问它。</p>
<p>例如:</p>
<p>double dval=23;</p>
<p>const int&amp;ri=dval;</p>
<p>编译器将其转换为:</p>
<p>int tmp=dval;//double-&gt;int</p>
<p>const int&amp;ri=tmp;</p>
<p>同理：上面代码</p>
<p>double dval=3.14159;</p>
<p>//下3行仅对const引用才是合法的</p>
<p>const int&amp;ir=1024;</p>
<p>const int&amp;ir2=dval;</p>
<p>const double&amp;dr=dval+1.0;</p>
<p>内部转化为：</p>
<p>double dval=3.14159;</p>
<p>//不可寻址，文字常量</p>
<p>int tmp1=1024;</p>
<p>const int&amp;ir=tmp1;</p>
<p>//不同类型</p>
<p>int tmp2=dval;//double-&gt;int</p>
<p>const int&amp;ir2=tmp2;</p>
<p>//另一种情况，不可寻址</p>
<p>double tmp3=dval+1.0;</p>
<p>const double&amp;dr=tmp3;</p>
<p>（4）不允许非const引用指向需要临时对象的对象或值，即，编译器产生临时变量的时候引用必须为const!!!!切记！！</p>
<p>int iv=100;</p>
<p>int*&amp;pir=&amp;iv;//错误，非const引用对需要临时对象的引用</p>
<p>int*const&amp;pir=&amp;iv;//ok</p>
<p>const int ival=1024;</p>
<p>int*&amp;pi_ref=&amp;ival;//错误，非const引用是非法的</p>
<p>const int*&amp;pi_ref=&amp;ival;//错误，需要临时变量，且引用的是指针，而pi_ref是一个非常量指针</p>
<p>const int*const&amp;pi_ref=&amp;ival;//正确</p>
<p>//补充</p>
<p>const int*p=&amp;ival;</p>
<p>const int*&amp;pi_ref=p;//正确</p>
<p>（5）********对于const int*const&amp;pi_ref=&amp;iva;具体的分析如下：*********</p>
<p>1.不允许非const引用指向需要临时对象的对象或值。</p>
<p>int a=2;</p>
<p>int&amp;ref1=a;//OK.有过渡变量。</p>
<p>const int&amp;ref2=2;//OK.编译器产生临时变量，需要const引用</p>
<p>2.地址值是不可寻址的值。</p>
<p>int*const&amp;ref3=&amp;a;//OK;</p>
<p>3.于是，用const对象的地址来初始化一个指向指针的引用。</p>
<p>const int b=23;</p>
<p>const int*p=&amp;b;</p>
<p>const int*&amp;ref4=p;</p>
<p>const int*const&amp;ref5=&amp;b;//OK</p>
<p>const引用的语义到底是什么？</p>
<p>最后，我们可能仍然不明白const引用的这个const的语义是什么。const引用表示，试图通过此引用去(间接)改变其引用的对象的值时，编译器会报错！这并意味着，此引用所引用的对象也因此变成const类型了。我们仍然可以改变其指向对象的值，只是不通过引用。下面是一个简单的例子：</p>
<p>1#include</p>
<p>2using namespace std;</p>
<p>3</p>
<p>4int main()</p>
<p>5{</p>
<p>6int val=1024;</p>
<p>7const int&amp;ir=val;</p>
<p>8</p>
<p>9val++;</p>
<p>10//ir++;</p>
<p>11</p>
<p>12cout&lt;&lt;&quot;val=&quot;&lt;</p>
<p>13cout&lt;&lt;&quot;ir=&quot;&lt;</p>
<p>14return0;</p>
<p>15}</p>
<p>其中第10行，如果我们通过ir来改变val的值，编译时会出错。但是我们仍然可以通过val直接改变其值(第9行)</p>
<p>总结：const引用只是表明，保证不会通过此引用间接的改变被引用的对象！</p>
<p>另外，const既可以放到类型前又可以放到类型后面，放类型后比较容易理解：</p>
<p>string const*t1;</p>
<p>const string*t1;</p>
<p>typedef string*pstring;string s;</p>
<p>const pstring cstr1=&amp;s;就出错了</p>
<p>但是放在类型后面不会出错:</p>
<p>pstring const cstr2=&amp;s;</p>
</article>
<div class="mt-3 mb-3" style="max-width: 770px;height: auto;">
                                    </div>
<div class="mt-3 mb-3" style="max-width: 770px;height: auto;">
                                    </div>
<div class="mt-3 mb-3" style="max-width: 770px;height: auto;">
                                    </div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.aitaocui.cn/article/325151.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
