有关(int&)和(int)的区别

本文通过一段C++代码示例,详细解释了(int)a、(int&)a及(int*)&a的区别,并探讨了浮点数在内存中的存储方式及其对类型转换的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先看一段程序

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include "stdafx.h"
#include <iostream>
 
using  namespace  std;
 
int  _tmain( int  argc, _TCHAR* argv[])
{
     float  a = 1.0f;
     cout<<( int )a<<endl;
     cout<<&a<<endl;
     cout<<( int &)a<<endl;
     cout<<boolalpha<<(( int )a == ( int &)a)<<endl;
     cout<< "~~~~~~~~~~~~~~~~~~~" <<endl;
     
     float  b=0.0f;
     cout<<( int )b<<endl;
     cout<<&b<<endl;
     cout<<( int &)b<<endl;
     cout<<boolalpha<<(( int )b == ( int &)b)<<endl;
     cout<< "~~~~~~~~~~~~~~~~~~~" <<endl;
 
     int  c=22;
     cout<<&c<<endl;
     cout<<( int &)c<<endl;
 
     return  0;
}

这段程序的输出会是什么呢?

显然(int)a是将a的值转换成int型

&a则是a的内存地址的二进制表示

那么(int&)a是什么呢?是否等于(int)&a呢?

【注意:(int)&a实际是将二进制的地址转化成int型】

我们看一下程序运行的结果:

image

(int&)a的值很古怪,1065353216

不妨尝试输出(int)&a,就会发现(int&)a≠(int)&a

实际上,(int&a)是与*((int*)&a)等价的,意思都是将&a这个地址上的32位看成int型,即使存储在这里的可能不是int型数据

(int&)a为什么会是1065353216呢?

这和浮点数在内存中的存储格式有关,float 1.0在内存中存储为(按IEEE754规定):


符号位           阶(8位)                          尾数(23位)
   0            01111111       000 0000000000 0000000000

于是将其看做int型数值的话

00111111100000000000000000000000(2)   =   1065353216(10)

这正是程序输出的结果

小结:

(int)a实际上是以浮点数a为参数构造了一个整型数,该整数的值是1。

(int&)a则是告诉编译器将a当作整数看(并没有做任何实质上的转换)。

因为1以整数形式存放和以浮点形式存放其内存数据是不一样的,因此两者不等。

对b的两种转换意义同上,但是0的整数形式和浮点形式其内存数据是一样的,因此在这种特殊情形下,两者相等(仅仅在数值意义上)。

 

~The end~

ps:
int&是引用,可以说是一个变量的别名,在定义时必须绑定到一个变量
比如int i = 0;
int& n = i;
n++;
这时i = 1
一般用在函数参数中
比如交换两个数
void Swap(int& a, int& b)
{
    int temp = a;
    a = b;
    b = temp;
}
这样调用这个函数
int x = 2, y = 3;
Swap(a, b);
这是x = 3, y = 2;
而如果用void Swap(int a, int b) 则是复制x和y到函数里
不会改变x, y的值

display(ostream & out)
比如这里调用display(cout);则在函数里修改out,等同于修改cout
比如函数中out << 10 << endl;
等同于cout << 10 << endl; 
而如果是display(ostream out);则out为cout的复制,并非本身
比如函数中out << 10 << endl;
但cout没有改变
&lt;think&gt;在C++中,`int &amp;r``int&amp; r`在语法上是完全等价的。它们都声明了一个名为`r`的引用,该引用绑定到一个`int`类型的对象上。C++编译器将空格在类型引用符号(`&amp;`)之间的位置视为无关紧要。 ### 两种写法的含义 - `int &amp;r`:将`&amp;`放在类型`int`变量名`r`之间。 - `int&amp; r`:将`&amp;`紧跟在类型`int`后面,然后空格,然后是变量名`r`。 ### 代码示例 ```cpp #include &lt;iostream&gt; using namespace std; int main() { int x = 10; // 两种声明引用的方式 int &amp;r1 = x; // 写法1: int &amp;r1 int&amp; r2 = x; // 写法2: int&amp; r2 r1 = 20; cout &lt;&lt; &quot;x = &quot; &lt;&lt; x &lt;&lt; endl; // 输出20 r2 = 30; cout &lt;&lt; &quot;x = &quot; &lt;&lt; x &lt;&lt; endl; // 输出30 // 验证r1r2都是x的引用 cout &lt;&lt; &quot;&amp;x = &quot; &lt;&lt; &amp;x &lt;&lt; endl; cout &lt;&lt; &quot;&amp;r1 = &quot; &lt;&lt; &amp;r1 &lt;&lt; endl; cout &lt;&lt; &quot;&amp;r2 = &quot; &lt;&lt; &amp;r2 &lt;&lt; endl; // 三个地址相同 return 0; } ``` ### 解释 - 上述代码中,`r1``r2`都是变量`x`的引用。 - 修改`r1`或`r2`都会改变`x`的值,因为引用就是变量的别名。 - 打印地址会显示`x`、`r1``r2`的地址相同。 ### 风格选择 尽管两种写法在功能上相同,但在编程风格上,开发者有不同的偏好: 1. **`int&amp; r`风格**:强调引用类型。这种写法将`int&amp;`视为一个整体(即引用类型)。当同时声明多个变量时,这种风格可能更清晰,但需要注意,如果在一行中声明多个变量,则只有第一个变量是指针或引用,后面的都是基本类型(容易出错)。 2. **`int &amp;r`风格**:强调引用是变量名的一部分。这种写法源于C语言中指针的写法(`int *p`),将`*`视为变量名的一部分。这种风格的支持者认为,每个变量的声明都应该单独写,以避免混淆。 ### 注意:多个变量声明 当一行声明多个变量时,引用符号(或指针符号)只作用于紧邻的变量。例如: ```cpp int a = 10; int&amp; ref1 = a, ref2 = a; // 错误:ref2是int类型,不是引用 ``` 这里,`ref1`是一个引用,但`ref2`是一个普通的`int`(初始化为`a`的值)。因此,为了避免混淆,通常建议每行只声明一个变量。 ### 结论 在C++中,`int &amp;r``int&amp; r`没有区别,选择哪种写法取决于个人或团队的编码风格。重要的是要保持一致。 &sect;&sect;相关问题&sect;&sect;: 1. C++中引用指针的主要区别是什么? 2. 为什么引用必须被初始化,而指针可以稍后赋值? 3. 在函数参数传递中,使用引用指针的优缺点分别是什么? 4. 如何理解C++中的&ldquo;右值引用&rdquo;?&lt;/think&gt;在 C++ 中,`int &amp;r` `int&amp; r` **没有任何区别**,它们是**完全等价**的语法形式。空格在 C++ 类型声明中会被编译器忽略,因此这两种写法声明的是完全相同的东西:一个名为 `r` 的 `int` 类型的引用。 ### 代码示例与验证 ```cpp #include &lt;iostream&gt; using namespace std; int main() { int value = 42; // 两种写法声明引用 int &amp;r1 = value; // 写法1: 空格在类型&amp;之间 int&amp; r2 = value; // 写法2: &amp;紧贴类型 cout &lt;&lt; &quot;初始值: &quot; &lt;&lt; value &lt;&lt; endl; r1 = 100; // 通过引用修改值 cout &lt;&lt; &quot;通过 r1 修改后: &quot; &lt;&lt; value &lt;&lt; endl; r2 = 200; // 通过另一个引用修改值 cout &lt;&lt; &quot;通过 r2 修改后: &quot; &lt;&lt; value &lt;&lt; endl; // 验证它们是同一个变量的引用 cout &lt;&lt; &quot;\n地址验证:&quot; &lt;&lt; endl; cout &lt;&lt; &quot;value 地址: &quot; &lt;&lt; &amp;value &lt;&lt; endl; cout &lt;&lt; &quot;r1 地址: &quot; &lt;&lt; &amp;r1 &lt;&lt; endl; cout &lt;&lt; &quot;r2 地址: &quot; &lt;&lt; &amp;r2 &lt;&lt; endl; // 验证引用本身的大小(通常与指针相同) cout &lt;&lt; &quot;\n引用大小:&quot; &lt;&lt; endl; cout &lt;&lt; &quot;sizeof(r1): &quot; &lt;&lt; sizeof(r1) &lt;&lt; endl; cout &lt;&lt; &quot;sizeof(r2): &quot; &lt;&lt; sizeof(r2) &lt;&lt; endl; return 0; } ``` ### 输出结果: ``` 初始值: 42 通过 r1 修改后: 100 通过 r2 修改后: 200 地址验证: value 地址: 0x7ffeedb0a78c r1 地址: 0x7ffeedb0a78c r2 地址: 0x7ffeedb0a78c 引用大小: sizeof(r1): 8 sizeof(r2): 8 ``` ### 关键解释: 1. **语法等价性**: - `int &amp;r` `int&amp; r` 在 C++ 标准中是**完全相同的声明** - 编译器将 `&amp;` 视为类型修饰符的一部分,而非变量名的一部分 - 空格位置不影响语义(类似于 `int* p` `int *p` 的关系) 2. **实际使用中的选择**: ```cpp // 风格1: &amp;靠近类型 (强调引用是类型的一部分) int&amp; func1(int&amp; param) { return param; } // 风格2: &amp;靠近变量名 (强调引用是变量的属性) int &amp;func2(int &amp;param) { return param; } // 两者完全等效 ``` 3. **多个变量声明时的注意事项**: ```cpp int a = 1, b = 2; // 正确:两个都是引用 int&amp; ref1 = a, &amp; ref2 = b; // 错误:只有 ref3 是引用,ref4 是普通 int int&amp; ref3 = a, ref4 = b; ``` 在声明多个变量时,必须为每个引用变量重复 `&amp;` 符号,否则未加 `&amp;` 的变量会成为普通变量。 ### 编程风格建议: 1. **一致性原则**: - 在项目中保持统一的风格(要么全部用 `Type&amp; var`,要么全部用 `Type &amp;var`) - Google C++ 风格指南推荐 `Type&amp; var` - Linux 内核风格推荐 `Type &amp;var` 2. **可读性考虑**: ```cpp // 推荐:清晰区分类型变量名 std::vector&lt;std::string&gt;&amp; names = get_names(); // 不推荐:&amp;位置可能引起混淆 std::vector&lt;std::string&gt; &amp; names = get_names(); ``` 3. **模板编程中的一致性**: ```cpp template&lt;typename T&gt; void process(T&amp; item) { // 推荐:统一使用 Type&amp; 风格 // ... } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值