我试图理解指针,所以我做了这段代码:
#include<iostream>
using namespace std;
struct teste{
int a;
bool b;
};
void say (struct teste* a) {
cout << (*a).a << (*a).b << "\n";
}
int main() {
teste* e;
(*e).a=2;
(*e).b=0;
say(e);
}
给了我分段错误
但以下内容:
#include<iostream>
using namespace std;
struct teste{
int a;
bool b;
};
void say (struct teste* a) {
cout << (*a).a << (*a).b << "\n";
}
int main() {
teste e;
e.a=2;
e.b=0;
say(&e);
}
我知道第二个是首选,但为什么第一个不起作用?我想我做的一切都很好。
答案 0 :(得分:2)
teste* e;
(*e).a=2;
(*e).b=0;
这会导致分段错误,因为指针e
未初始化 - 它不指向有效内存。
当您使用某个地址y
初始化指针 - 然后应用解除引用运算符时,您可以告诉它从您分配给它的内存地址y
中检索值。在您的情况下,没有为其分配地址,因此您无法取消引用它。
指向teste
对象,然后您可以取消引用它。
答案 1 :(得分:0)
您实际上从未为e
分配任何内存。您可以在堆栈上声明它,然后使用运算符&
int main() {
teste e;
e.a=2;
e.b=0;
say(&e);
}
或使用new
在堆上声明它,然后在您完成后将其delete
声明。
int main() {
teste* e = new teste;
e->a=2;
e->b=0;
say(e);
delete e;
}
答案 2 :(得分:0)
在第一个示例中,您声明了一个指针,但该指针指向任何内容。所以你得到了seg。故障。你应该为该指针赋值,作为teste实例的地址,使用new()或malloc()
在内存中声明或创建答案 3 :(得分:0)
想象一下,你问我&#34;机场在哪里?#34;?我提议为你写一个便利贴的地址。
在我写的笔记上:
airport
这不是很有帮助,是吗?
teste* e;
这表示&#34;声明一个变量e,使其在内存中保存teste
实例的地址&#34;。
但是你还没有提供teste
的实际实例来指出它;你没有真正为它分配东西的地址。
int main() {
teste instance;
teste* e = &instance;
e->a = 2;
(*e).b = 0; // equivalent to e->a
say(e);
}
该行
teste* e = &instance;
表示&#34;声明一个变量e,这样它将地址保存在teste
结构的内存中,并让该地址为instance
的地址(&amp; instance) &#34;
我们也可以写
teste* e;
e = &instance;
但是,如果可以的话,尝试在声明时始终初始化变量是一种更好的做法。
->
运算符对于(*e).
或多或少的语法糖 - 它通过(取消引用)指针进行访问。
e->a
// is equivalent to
(*e).a
.
成员->
的成员是成员通过。
请注意,.
和->
是不同的运算符,在您对语言的理解之后将会变得非常重要。
在此示例中,instance
是一个局部变量,因此在堆栈上创建。这意味着当范围结束时,它将被销毁/消失。
如果你需要instance
更长时间,或者它非常大,你可以从&#34;堆&#34;中分配它。
int main() {
teste* e = new teste;
e->a = 2;
e->b = 0;
say(e);
delete e;
}
解释新的和删除可能超出了回答这个问题的范围,我留给你了解它们及其用途。