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

C++ c+中引用和指针的声明+;,c++,pointers,reference,declaration,C++,Pointers,Reference,Declaration,例如,如果F是对整数的引用,则一旦该引用最初指向一个新对象,就不允许该引用指向该对象 我可以写声明如:const int&F吗 我对引用和指针感到困惑,因为它们都表示某物的地址,但我们总是将参数use reference写成:const&F,我理解这是为了减少副本,不允许其他人更改它,但还有其他含义吗?为什么在函数声明之后需要“const”,比如:intf(intz)const;这个常量使返回类型为const或函数const中的所有内容 再举一个例子, void F(int* p) { p+=3

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

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


我对引用和指针感到困惑,因为它们都表示某物的地址,但我们总是将参数use reference写成:const&F,我理解这是为了减少副本,不允许其他人更改它,但还有其他含义吗?为什么在函数声明之后需要“const”,比如:intf(intz)const;这个常量使返回类型为const或函数const中的所有内容

再举一个例子,

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

int z=8;
F(&z);
std::cout<<z<<std::endl;
void F(int*p)
{
p+=3;
}
int z=8;
F&z;

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

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

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


希望有帮助

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

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

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


希望有帮助

只是一些答案的第一步-如果有什么不清楚的地方,请评论,我将尝试详细说明

int a = 3;
声明一个初始值为3的整数,
a
,但您可以更改它。例如,以后您可以这样做

a = 5;   // (*)
a
的值为5。如果要防止这种情况,可以改为编写

const int a = 3;
这将使赋值
(*)
非法-编译器将发出错误

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

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

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

关于指针的问题:代码片段

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

int z = 8;
F(&z);
没有达到你的期望。您将
z
的地址传递到函数
F
,因此在
F
中,指针
p
将指向
z
。但是,您现在要做的是将
3
添加到
p
的值中,即添加到
p
指向的地址中。所以您将更改为指向某个(半)随机内存地址的指针。幸运的是,它只是一个副本,将被丢弃。您可能想做的是增加
p
所指向的整数的值,即
*p+=3
。您可以通过将参数设置为a
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;
}
当然,如果函数返回某些内容,例如,该值可以有自己的类型

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;

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

int a = 3;
声明一个初始值为3的整数,
a
,但您可以更改它。例如,以后您可以这样做

a = 5;   // (*)
a
的值为5。如果要防止这种情况,可以改为编写

const int a = 3;
这将使赋值
(*)
非法-编译器将发出错误

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

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

const int& b = a;
表示
b
仍然是
a的别名