c ++中的引用和指针声明

时间:2013-12-09 16:45:09

标签: c++ pointers reference declaration

例如,如果F是对整数的引用,则一旦初始指向一个对象,就不允许将引用指向新对象。

我可以写声明如下:const int& F'

我对引用和指针感到困惑,因为它们都代表了某些东西的地址,但是我们总是把参数使用引用写成:const& F,我明白这是为了减少副本而不允许其他人改变副本,但还有其他含义吗?为什么在函数声明之后需要“const”,如:int F(int z)const;这个const使得返回类型为const或函数const中的所有内容?

还有一个例子,

void F(int* p)
{
p+=3;
}

int z=8;
F(&z);
std::cout<<z<<std::endl;

z的输出是什么,因为z是一个引用,我把它作为一个指向一个整数的指针传递。将p增加3只会使地址不同而不会改变它的值?

3 个答案:

答案 0 :(得分:2)

只是第一次传递一些答案 - 如果有什么不清楚请发表评论,我会尽力详细说明。

int a = 3;

声明一个整数a,初始值为3,但您可以更改它。例如,稍后你可以做

a = 5;   // (*)

a的值为5.如果要阻止这种情况,可以改写

const int a = 3;

将使赋值(*)非法 - 编译器将发出错误。

如果创建对整数的引用,则基本上是在创建别名:

int& b = a;

,尽管出现,但不会创建新的整数b。相反,它将b声明为a的别名。如果a之前的值为3,那么b也是如此,如果您编写b = 6并打印a的值,您也会获得6。与a一样,您可以通过将赋值b = 6声明为const来使其成为非法的:

const int& b = a;

表示b仍然是a的别名,但不会用于为a分配不同的值。它仅用于读取a的值。请注意,a本身仍然可能是或可能不是常量 - 如果您将其声明为非const,您仍然可以写a = 6b也会6 }。

关于指针的问题:片段

void F(int* p) {
  p += 3;
}

int z = 8;
F(&z);

不符合您的预期。您将z的地址传递给函数F,因此在F内,指针p将指向z。但是,您正在执行的操作是将3添加到p的值,即p指向的地址。因此,您将更改为指向某个(半)随机存储器地址的指针。幸运的是,它只是一个副本,它将被丢弃。您可能希望做的事情是将p指向的整数值增加到,这将是*p += 3。您可以通过将参数设为int* const来防止此错误,这意味着:p(即指向的地址)的值不能更改,但它指向的值(即{{{1}的值1}},在这种情况下)可以。这会使z合法,但不会是“错误的”(非预期的)*p += 3。其他版本将是p += 3,这将使const int* p合法但不是p += 3,而const int * const`则不允许。

实际上,您编写*p += 3的方式是危险:假设您展开该函数,然后您(正确地)F编写。您认为您正在更新传入其地址的*p += 3的值,而实际上您正在更新或多或少的随机存储器的值地址。事实上,当我尝试编译以下内容时:

z

我遇到了分段错误,因为我正在写一个我没有分配变量的地址(据我所知,我可能只是搞砸了我的启动扇区)。

最后,关于函数声明后的// WARNING WARNING WARNING // DANGEROUS CODE - This will probably produce a segfault - don't run it! void F(int* p) { p += 3; // I thought I wrote *p += 3 // ... Lots of other code in between, I forgot I accidentally changed p *p += 3; // NOOOOOOOOOOO! } int main() { int z=8; F(&z); std::cout << z; return 0; } :它使const指针成为this指针 - 基本上编译器发出const代替仅const A* this。从概念上讲,它表明你的意图是函数不会改变类的状态,这通常意味着它不会改变任何(内部)变量。例如,它会使以下代码非法:

A* this

当然,如果函数返回某些内容,则此值可以有自己的类型,例如

class A {
  int a;

  void f() const {
    a = 3;  // f is const, so it cannot change a!
  }
};

A a;
a.f();

是不返回任何内容的函数,整数的(副本),整数的(引用),整数的常量(副本)以及整数的常量引用。如果另外void f(); int f(); int& f(); const int f(); const int& f(); 保证不更改任何类字段,您还可以在括号后添加f

const

答案 1 :(得分:1)

我记得引用和指针之间的区别在于必须存在引用并且引用不能更改。

指针可以更改,通常需要针对NULL进行检查或测试以验证指向有效对象。

此外,通过引用传递的对象可以在语法上处理,就像在函数中声明的那样。指针必须使用引用语法。

希望有所帮助。

答案 2 :(得分:1)

你很困惑。

首先int z=8; F(&z);这里z不是参考。

让我先从基础知识开始:

当在类型声明中找到时,符号&表示引用,但在任何其他上下文中,符号&表示地址。 类似地,在类型声明中*具有声明指针的含义,在其它任何地方它都是解引用运算符,表示你使用地址处的值。

例如:
int *p:p是int类型的指针
x = *p:x被指定为在地址 p。

中找到的值

int &r = a:r是int类型的引用,r是变量a。
p = &a:p被指定为变量的地址 a。

你有另一个问题:函数末尾的const,如int f(int x) const。这可以在非静态类方法上使用 only ,并指定该函数不会修改该对象。它与返回值无关。