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

declaration of reference and pointer in c++

本文关键字:声明 指针 引用 c++      更新时间:2023-10-16

例如,如果F是对一个整数的引用,则该引用在最初指向一个新对象时不允许指向该对象。

我可以这样写声明吗:const int&F

我对引用和指针感到困惑,因为它们都表示某个东西的地址,但我们总是将参数use-reference写成: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只会使地址不同,并且不会更改其值?

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

int a = 3;

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

a = 5;   // (*)

并且CCD_ 2将具有值5。如果你想防止这种情况,你可以写

const int a = 3;

这将使赋值CCD_ 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 = 6,并且a0也将是6

关于指针的问题:摘录

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

没有达到你的预期。您将z的地址传递给函数F,因此在F内部,指针p将指向z。然而,您要做的是将3添加到p的值,即p指向的地址。因此,您将更改为指向某个(半)随机内存地址的指针。幸运的是,这只是一个副本,它将被丢弃。您可能想要做的是将(*)0指向的整数的值递增到,即*p += 3。您本可以通过将参数设置为int* const来避免这种错误,这意味着:p的值(即指向的地址)不能更改,但它指向的值(在这种情况下,即z的值)可以。这将使*p += 3合法,但不是"错误的"(非故意的)p += 3。其他版本是const int* p,它将使p += 3合法,但不使*p += 3合法,而const int*const`则不允许。

实际上,您编写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

void f() const;
int f() const;
int& f() const;
const int f() const;
const int& f() const;

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

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

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

希望能有所帮助。

您混淆了事情。

首先,这里的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。这只能用于非静态类方法,并指定函数不修改对象。它与返回值无关。