我应该制作一个程序,我使用stucts和一系列结构。
安全委员会< >安理会成员
我的任务是使用" UML聚合"创建一个程序,我使用结构和结构数组。 (我希望你能理解我想说的话)
由于安全委员会的成员是安全委员会的一部分,而不是相反,安全委员会的结构必须有一系列成员。(忍受我)
//example
struct Member_sc{
char * name;
int age;
};
struct Security_council{
Member_sc members[10];
};
现在,我已经创建了这个程序,一切都很完美(据我的老师说),但现在她告诉我创建一个完整的副本,而不是"成员"数组我必须使用指向Member_sc结构的指针数组。由于我还没有完全弄清楚指针是如何工作的,所以我遇到了一些问题。
如果需要,我可以将代码发布到原始程序,但它包含4个文件(主文件,标题和一些函数文件),尝试在此处发布它会很痛苦。
这是原型(目前所有文件都在一个文件中)
#include <iostream>
using namespace std;
struct member_sc{
string name;
};
struct security_council{
member_sc *point;
security_council **search; // ignore this for now
int n;
security_council():n(0){}
};
void in_mem( member_sc &x){
getline(cin,x.name);
}
void out_mem(member_sc &x){
cout<<x.name<<endl;
}
void in_SC(security_council &q, member_sc &x){
int num; //number of members
cin>>num;
for(int i=0; i<num; ++i){
in_mem(x);
q.point[q.n]=x;
q.n++;
}
}
void out_SC(security_council &q,member_sc &x){
for(int i=0; i<q.n; ++i){
out_mem(q.point[i]);
}
}
int main(){
member_sc y;
security_council x;
in_mem(y); // works
out_mem(y); // works
in_SC(x,y); // crashes after i input the number of members i want
out_SC(x,y); //
system("pause");
return 0;
}
在安全委员会中输入所需的成员数后,程序崩溃。 我的思维方式是对的吗?或者我应该使用动态内存分配?
除此之外(我的老师给了我一个额外的任务)使用指针创建一个搜索功能。我认为指针指针可能对此有好处,但我不确定。
非常感谢任何帮助或建议。 (一旦我弄清楚结构的指针是如何工作的,我认为不好找出搜索的东西)
答案 0 :(得分:1)
问题的第一部分是:
cin >> num;
这只读取已输入的数字并在换行符处停止。然后,在in_mem
中,对getline
的调用会立即读取换行符。你需要这样做:
cin >> num;
cin.ignore();
这将消耗任何剩余输入的输入流,或者可以说是赶上来。
然而,你的核心问题是你没有为&#34; point
&#34;分配任何内存。指向。
指针只是一个变量,它保存的值恰好是内存中事物的地址(偏离0)。如果你要去机场并写下#23; 23号门&#34;在便利贴上,便条贴是指针和#34;门23&#34;是值。
在你的代码中,该变量是未初始化的,如果你幸运的话,它将是0,或者如果你没有那么幸运,你的内存中会有一些随机地址。
到机场打个比方:你到达机场,发现你的便利贴上有#14;披萨&#34;写在上面。没用。
你的老师实际上已经指定了一个&#34;指针数组&#34;。打破下来:指向什么? member_sc
,member_sc*
。现在把它变成一个数组
member_sc* pointers[10];
注意:这不是好的,现代的C ++ - 在现代C ++中,你可能会使用一种叫做智能指针(std :: unique_ptr)的东西。
std::unique_ptr<member_sc[]> pointers(new member_sc[10]);
现在你有10个指针而不是只有一个指针,所有指针都需要一些指向指向。最简单的方法是使用new
关键字和复制构造函数:
for (int i = 0; i < num; i++) {
in_mem(x);
pointers[q.n] = new member_sc(x); // make a clone of x
q.n++;
}
或现代C ++
for (int i = 0; i < num; i++) {
in_mem(x); // x is temporary for reading in
pointers[q.n] = std::make_unique<member_sc>(x);
q.n++;
}
但是这种方法存在限制:您最多只能拥有10个安全委员会成员。你是如何解决这个问题的?那么,现代C ++的答案就是使用std::vector
std::vector<member_sc> members;
// ditch n - vector tracks it for you.
// ...
for (int i = 0; i < num; ++i) {
in_mem(x);
q.members.push_back(x);
// q.n is replaced with q.members.size()
// which is tracked automatically for you
}
但我猜你的老师希望你在用现代奢侈品忘记它们之前真正理解指针。
我们需要重复使用上面刚刚使用的指针内容并更改&#34;指针&#34;到一个指针数组。
这意味着我们想要一个指向成员指针的指针。
member_sc** pointers;
我们需要为此指定一些内存以指向:
cin >> num;
cin.ignore();
if (num == 0) {
// do something
return;
}
pointers = new member_sc[num];
幸运的是,使用指向数组的指针就像使用数组一样简单,唯一的主要区别是你丢失了数组大小的信息 - 你所拥有的只是地址,而不是维度。
for (int i = 0; i < num; i++) {
in_mem(x);
q.pointers[i] = new member_sc(x);
q.n++;
}
我故意不向你提供一个完整的工作示例,因为这显然属于一个班级。
答案 1 :(得分:1)
您永远不会初始化点成员引用的内存,然后在语句q.point[q.n]=x;
中尝试使用它。
基本上,在读入成员数量之后,以及在单个成员中读取的for循环之前,您需要分配一个包含适当数量的member_sc
个对象的数组并将其存储在{{ 1}}。使用它时不要忘记释放这些记忆。
完成此操作后,您还可以从q.point
和member_sc &x
中删除in_SC
参数,因为这样做是不必要的。
最后,您的输入的一些验证似乎已经到位。考虑如果用户输入负数会发生什么,并且您尝试直接使用它来确定要分配的内存大小。
这是一个简单的例子,展示了如何使用动态分配的结构数组:
out_SC
当然,这种代码风格还存在许多其他问题,但我认为这与问题无关。例如:
答案 2 :(得分:0)
由于要求您使用指针数组,请执行以下操作:replace
Member_sc members[10];
带
Member_sc* members[10];
然后使用动态内存分配填充该数组。作为一个好的形式,在程序结束时记得释放你使用过的动态内存。