指针变量和引用变量之间的区别是什么?


当前回答

塔林♦ 说:

不能像使用指针那样获取引用的地址。

事实上你可以。

我引用了另一个问题的答案:

C++常见问题解答说得最好:与指针不同,一旦引用绑定到对象,就不能将其“重新放置”到另一个对象。引用本身不是一个对象(它没有标识;获取引用的地址可以获得引用的地址;记住:引用是它的引用)。

其他回答

除非我需要以下任何一项,否则我会使用参考资料:

空指针可以用作哨兵价值,通常是一种廉价的方式避免函数重载或使用嘘声。你可以在指针上做算术。例如,p+=偏移量;

与流行观点相反,引用可能为NULL。

int * p = NULL;
int & r = *p;
r = 1;  // crash! (if you're lucky)

当然,使用引用要困难得多,但如果你管理它,你会为了找到它而绞尽脑汁。引用在C++中并不安全!

从技术上讲,这是一个无效引用,而不是空引用。C++不支持在其他语言中可能会发现的空引用作为概念。还有其他类型的无效引用。任何无效引用都会引发未定义行为的幽灵,就像使用无效指针一样。

实际错误是在分配给引用之前取消引用NULL指针。但我不知道任何编译器会在这种情况下生成任何错误——错误会传播到代码中更远的地方。这就是这个问题如此阴险的原因。大多数情况下,如果取消引用NULL指针,就会在该位置崩溃,而且不需要太多调试就可以解决问题。

我上面的例子简短而做作。这是一个更真实的例子。

class MyClass
{
    ...
    virtual void DoSomething(int,int,int,int,int);
};

void Foo(const MyClass & bar)
{
    ...
    bar.DoSomething(i1,i2,i3,i4,i5);  // crash occurs here due to memory access violation - obvious why?
}

MyClass * GetInstance()
{
    if (somecondition)
        return NULL;
    ...
}

MyClass * p = GetInstance();
Foo(*p);

我想重申,获得空引用的唯一方法是通过格式错误的代码,一旦获得了它,就会得到未定义的行为。检查空引用是没有意义的;例如,您可以尝试如果(&bar==NULL)。。。但是编译器可能会优化不存在的语句!有效引用永远不能为NULL,因此从编译器的角度来看,比较总是错误的,并且可以自由地将if子句作为死代码来消除-这是未定义行为的本质。

避免麻烦的正确方法是避免取消引用NULL指针来创建引用。这里有一种自动化的方法来实现这一点。

template<typename T>
T& deref(T* p)
{
    if (p == NULL)
        throw std::invalid_argument(std::string("NULL reference"));
    return *p;
}

MyClass * p = GetInstance();
Foo(deref(p));

要从具有更好写作技巧的人那里了解这个问题,请参阅Jim Hyslop和Herb Sutter的空引用。

有关取消引用空指针的危险的另一个示例,请参见Raymond Chen在尝试将代码移植到另一个平台时暴露未定义的行为。

不能像指针一样取消引用,当取消引用时,

引用和指针都是通过地址工作的。。。

so

你可以这样做

int*val=0xDEADBEEF;*val是0xDEADBEEF的值。

你不能这样做int&V=1;

*不允许使用val。

指针(*)的基本含义是“地址处的值”,这意味着您提供的任何地址都将在该地址处给出值。一旦你改变了地址,它将给出新的值,而引用变量用于引用任何特定的变量,将来不能改变为引用任何其他变量。

指针是保存另一个变量的内存地址的变量,其中引用是现有变量的别名。(已存在变量的另一个名称)

1.指针可以初始化为:

int b = 15;
int *q = &b;

OR

int *q;
q = &b;

其中作为参考,

int b=15;
int &c=b;

(在一个步骤中声明和初始化)

指针可以分配给null,但引用不能可以对指针执行各种算术运算,而没有所谓的参考算术。指针可以重新分配,但引用不能指针在堆栈上有自己的内存地址和大小,而引用共享相同的内存地址