- Published on
Pointer(指针)与引用的区别
- Authors
- Name
- Yanbin
- @ybtaimu
概念
引用:引用是某个变量的别名
,一旦引用被初始化,它就不能再指向其他对象
。引用必须在声明时初始化
。
int a = 10;
int& ref = a; // ref 是 a 的引用,ref 就是 a 的别名
指针:指针是存储某个变量地址的变量。指针可以在任何时候指向不同的对象,并且可以为空(即指向 nullptr)。
int a = 10;
int* ptr = &a; // ptr 是指向 a 的指针,存储 a 的地址
底层实现
尽管 C++ 语法上将引用和指针区分开来,但在底层,引用通常是通过 指针 或 内存地址 来实现的。编译器在生成代码时,会将引用转换为指针或内存地址的操作。
2.1 引用作为指针处理
编译器通常会将引用视为指针的别名。这意味着引用在底层实际上是一个指向对象的指针,但编译器对引用进行了语法上的简化,使得程序员不需要显式地解引用。
例如,下面的代码:
int a = 10;
int& ref = a;
ref = 20;
可能会被编译器转换为类似以下的代码:
int a = 10;
int* const ref = &a; // 引用被实现为指针
*ref = 20; // 对引用的赋值被转换为对指针解引用的赋值
在这种情况下,ref 在底层被处理为一个指向 a 的指针,ref = 20 实际上是通过 *ref 来修改 a 的值。
引用的内存模型
引用本身并不占用额外的内存空间,它只是在编译时为某个对象创建了一个别名。因此,引用的内存地址与它所引用的对象的内存地址是相同的
。
例如,下面的代码:
int a = 10;
int& ref = a;
std::cout << &a << std::endl; // 输出 a 的地址
std::cout << &ref << std::endl; // 输出 ref 的地址,和 a 一样
输出结果会显示 &a 和 &ref 是相同的地址,因为 ref 实际上是 a 的别名,它们指向同一个内存位置。
可通过该例题更深刻的理解
http://oj.lgwenda.com/problem/15 使用C++的引用,注意提交时把代码选为C++; 在主函数定义字符指针 char *p, 然后在子函数内malloc申请空间(大小为100个字节), 通过fgets读取字符串,然后在主函数中进行输出;要求子函数使用C++的引用, 注意在C++中从标准输入读取字符串,需要使用fgets(p,100,stdin)
#include <stdio.h>
#include <stdlib.h>
void get(char* &i) {
i = (char*)malloc(100);
fgets(i,100,stdin);
}
int main() {
char* p = nullptr;
get(p);
printf("%s\n",p);
}