如何在C++;是用指针实现的 我知道C++引用变量是用指针实现的。在我开始使用C++之前,我一直在看一些C代码,因为这样我就有了一些我可以用C语言来处理的东西。有没有人真的有关于如何使用指针实现它的例子
我一直在研究这个问题,这就是我发现的。但是,我不确定它是否合法,因为我以前不能在C++文件中正确运行。任何答案都将不胜感激,谢谢!:)如何在C++;是用指针实现的 我知道C++引用变量是用指针实现的。在我开始使用C++之前,我一直在看一些C代码,因为这样我就有了一些我可以用C语言来处理的东西。有没有人真的有关于如何使用指针实现它的例子,c++,pointers,reference,C++,Pointers,Reference,我一直在研究这个问题,这就是我发现的。但是,我不确定它是否合法,因为我以前不能在C++文件中正确运行。任何答案都将不胜感激,谢谢!:) 在C语言中,当您使用变量作为函数的参数时,它是按值发送的。如果函数应该更改变量,那么参数必须作为指针发送 int x = 5; void addtwo(int* param) { *param += 2; } addtwo(&x); // This will send a pointer to x to the function addtwo
在C语言中,当您使用变量作为函数的参数时,它是按值发送的。如果函数应该更改变量,那么参数必须作为指针发送
int x = 5;
void addtwo(int* param)
{
*param += 2;
}
addtwo(&x); // This will send a pointer to x to the function addtwo
在C++中,可以发送引用:< /p>
void addtwo(int& param)
{
param += 2;
}
addtwo(x); // This will send a reference to x to the function addtwo
在这个简单的示例中,这看起来没有多大区别,但是在第二个示例中,看起来param没有被取消引用。但它实际上是,因为它是作为参考发送的。尽管
param
看起来不像指针(它不是-它是一个引用),函数addtwo
被发送到x的地址,就像它是一个指针一样。差别是细微的,但却是具体的。在C语言中,当您使用变量作为函数的参数时,它是按值发送的。如果函数应该更改变量,那么参数必须作为指针发送
int x = 5;
void addtwo(int* param)
{
*param += 2;
}
addtwo(&x); // This will send a pointer to x to the function addtwo
在C++中,可以发送引用:< /p>
void addtwo(int& param)
{
param += 2;
}
addtwo(x); // This will send a reference to x to the function addtwo
在这个简单的示例中,这看起来没有多大区别,但是在第二个示例中,看起来param没有被取消引用。但它实际上是,因为它是作为参考发送的。尽管param
看起来不像指针(它不是-它是一个引用),函数addtwo
被发送到x的地址,就像它是一个指针一样。差别是微妙的,但却是具体的。这是我能想到的最好的证明:
#include <iostream>
using namespace std;
double value;
struct pointer {
double *value; };
struct reference {
double& value; };
int main() {
pointer ptr { &value };
reference ref { value };
*ptr.value = 3.14;
cout << sizeof(value) << endl;
cout << sizeof(pointer) << endl;
cout << sizeof(reference) << endl;
cout << ref.value;
}
换句话说:引用是具有不同运算符集的常量指针(不能更改)。主要优点是编译器可以更好地优化它们(完全丢弃引用/指针),但这并不能证明它们有任何不同,因为编译器也可以优化/丢弃指针(gcc-O3可以很好地做到这一点,我看到并分解了带有指针的良好循环,gcc可以克服所谓的混叠问题。这是我能想到的最好的证明:
#include <iostream>
using namespace std;
double value;
struct pointer {
double *value; };
struct reference {
double& value; };
int main() {
pointer ptr { &value };
reference ref { value };
*ptr.value = 3.14;
cout << sizeof(value) << endl;
cout << sizeof(pointer) << endl;
cout << sizeof(reference) << endl;
cout << ref.value;
}
换句话说:引用是具有不同运算符集的常量指针(不能更改)。主要优点是编译器可以更好地优化它们(完全丢弃引用/指针),但这并不能证明它们有任何不同,因为编译器也可以优化/丢弃指针(gcc-O3也可以做到这一点,我看到并分解了指针的良好循环,gcc可以克服所谓的混叠问题。引用与常量指针具有相同的含义 引用和指针的代码是相同的,至少MSVC2013是这样 例如:
int u=1,v=3, w;
int& x = u; // initialize reference
w = x; // x is synonym for u;
x++;
int *y = &u; // initalize pointer
w = *y; // y points to u
(*y)++;
在这两种情况下,初始化都会生成:
lea eax, DWORD PTR _u$[ebp]
mov DWORD PTR _x$[ebp], eax ; of course in the case of the pointe _y$ instead of _x$.
在这两种情况下,分配都会生成:
mov eax, DWORD PTR _x$[ebp]
mov ecx, DWORD PTR [eax]
mov DWORD PTR _w$[ebp], ecx
甚至增量也会生成相同的代码
无论是指针、常量指针还是指向常量的指针(在后一种情况下,++不工作),生成的代码都是相同的。编译器的功能是确保常量是常量
现在在语法上有了细微的区别:
int& x = u; // initialize reference
int *y = &u; // initalize pointer
int const *z = &u; // initialize pointer to "const int". Pointer itself is not const !
int * const a = &u; // initialize "const pointer" to "int", which is basically a reference.
根据这些定义:
//(*z)++; // invalid because the it points to a const int.
z = &w; // valid because pointer intself is not const
以及:
所以你可以说int&
相当于int*const
(我在这里不使用“=”,因为它是操作符=保留的,看起来像是语法错误!)
当然,对于引用,您总是使用它的名称,就好像它是一个实变量一样(例如:
x++
),而对于常量指针,您总是必须取消引用(又名:(*x++
)。因此含义相同,但语法不同。引用与常量指针具有相同的含义
引用和指针的代码是相同的,至少MSVC2013是这样
例如:
int u=1,v=3, w;
int& x = u; // initialize reference
w = x; // x is synonym for u;
x++;
int *y = &u; // initalize pointer
w = *y; // y points to u
(*y)++;
在这两种情况下,初始化都会生成:
lea eax, DWORD PTR _u$[ebp]
mov DWORD PTR _x$[ebp], eax ; of course in the case of the pointe _y$ instead of _x$.
在这两种情况下,分配都会生成:
mov eax, DWORD PTR _x$[ebp]
mov ecx, DWORD PTR [eax]
mov DWORD PTR _w$[ebp], ecx
甚至增量也会生成相同的代码
无论是指针、常量指针还是指向常量的指针(在后一种情况下,++不工作),生成的代码都是相同的。编译器的功能是确保常量是常量
现在在语法上有了细微的区别:
int& x = u; // initialize reference
int *y = &u; // initalize pointer
int const *z = &u; // initialize pointer to "const int". Pointer itself is not const !
int * const a = &u; // initialize "const pointer" to "int", which is basically a reference.
根据这些定义:
//(*z)++; // invalid because the it points to a const int.
z = &w; // valid because pointer intself is not const
以及:
所以你可以说int&
相当于int*const
(我在这里不使用“=”,因为它是操作符=保留的,看起来像是语法错误!)
当然,对于引用,您总是使用它的名称,就像它是一个实变量一样(例如:
x++
),而对于常量指针,您总是必须取消引用(又称:(*x)+
).意思相同,但语法不同。编译器可以以任何方式实现引用,包括完全优化某些引用
你可以想到参考资料
T& r = o;
作为
这是对左值引用的大多数属性的一个很好的解释,除了这个概念图不包括临时变量的生存期扩展和临时变量的初始化
它“解释”了
- 引用必须在声明中初始化,除非它是形式参数
- 无法重新分配引用
- 引用不能是有效代码中的“空引用”