我目前正在尝试编写一个实现庸医(队列/堆栈)的程序。在每个庸医实例中,我都有一个指向字符数组"items"的指针我已经编写了pushBack
和pushFront
函数,但我在编写popFront
和popBack
函数时意识到,在这种情况下,我不知道如何从数组中取消引用元素。
我的老师给我提供了一个文本文件,说明程序的输出应该是什么样子,它需要看起来和他的完全一样。在他的输出文件中,当字符从数组的前面或后面弹出时,它会保留在内存中的那个位置,只是数组不再使用它。因此,当我将索引位置从数组的前面或后面弹出时,我不能将其设置回最初初始化的位置。这个字符需要保持在那里,所以当我运行代码时,即使它从数组中弹出,它仍然会显示出来,直到有东西被推到数组上覆盖它(数组的容量是静态的)。
注意:我的程序正在创建并写入一个单独的文本文件,该文件从数组的当前前面到后面显示数组元素,而不是从items[0]到items[ccapacity-1],并且该文件在字符从数组中弹出后不会打印字符。
我有一个名为front的int变量,它包含数组的当前前索引位置,还有一个名为主back,它具有数组后面的索引位置。当我试图编写popFront
函数时,我尝试做一些类似的事情
delete[] &items[front];
但这并没有奏效,也没有
delete[front] items;
让你知道我要做什么。我不知道我需要使用什么语法才能完成这项工作。我会在这里为您提供更多我的代码,这样您就可以亲眼看到:
Quack构造函数:(是的,我必须将数组中的元素初始化为"-",因为当他们还没有在输出文件中分配一个字母时,这就是他们需要的样子)。此外,还提供了growBy
的实现,它可以放大数组,如果我想做这个赋值的更困难的版本并使数组动态,但我没有时间做那个,所以你可以忽略growBy
。
Quack::Quack(int capacity, int growBy) :
capacity(capacity),
growBy(growBy),
nItems(0),
items(new char[capacity]),
front(NULL),
back(NULL)
{
for (int i = 0; i < capacity; i++)
{
items[i] = '-';
}
}
这是我的Quack类:(我在类Quack中省略了printArray
函数,因为它很长而且不相关)
class Quack
{
public:
Quack(int capacity, int growBy = 0);
// capacity: # of slots in array
// growBy: # of slots to add to array when it grows, 0 means "don't grow"
~Quack(void);
bool pushFront(const char ch); // push an item onto the front
bool pushBack(const char ch); // push an item onto the back
bool popFront(char& ch); // pop an item off the front
bool popBack(char& ch); // pop an item off the back
void rotate(int r); // "rotate" the stored items (see note below)
void reverse(void); // reverse the order of the stored items
int itemCount(void); // return the current number of stored items
private:
char *items; // pointer to storage for circular array,
// each item in the array is a char
// items is an array with
int nItems; // # of items currently stored in array
int capacity;
int growBy; // # of slots in array
int front;
int back;
public:
friend std::ostream& operator<<(std::ostream& out, Quack *q);
};
最后,这是我对popFront
所做的操作(你可以看到元素取消引用需要去哪里;剩下的就是我在弹出项目后将front更改为正确的地方)。itemCount()
是一个只返回nItems的函数,这是列表中的项目数,我也在跟踪它。
bool Quack::popFront(char& ch)
{
// if list is empty, can't pop
if (itemCount() == 0)
{
return false;
}
// pop front item
/* here is where I don't know what to do, stackoverflow */
// increment front and nItems
if (front < (capacity - 2))
{
front++;
nItems--;
return false;
}
else if (front == (capacity - 1))
{
front = 0;
nItems--;
return false;
}
return false;
}
以下是VS中程序的正确输出,因此您可以看到它应该做什么:
(popFront从列表前面弹出项目,popBack从列表后面弹出项目,pushFront将项目添加到列表的前面,pushBack将项目添加至列表的后面)
pushFront(a) [ a - - - - - - ]
pushFront(b) [ a - - - - - b ]
pushFront(c) [ a - - - - c b ]
pushFront(d) [ a - - - d c b ]
pushBack(z) [ a z - - d c b ]
pushFront(e) [ a z - e d c b ]
popFront -> e [ a z - e d c b ]
popFront -> d [ a z - e d c b ]
pushBack(f) [ a z f e d c b ]
pushBack(g) [ a z f g d c b ]
rotate(2) [ a z f g c b b ]
rotate(-3) [ a z f g g c b ]
reverse [ b c g g f z a ]
pushFront(y) [ b c g y f z a ]
rotate(3) [ b c g y f z a ]
rotate(-4) [ b c g y f z a ]
popBack -> c [ b c g y f z a ]
popBack -> b [ b c g y f z a ]
popBack -> a [ b c g y f z a ]
popBack -> z [ b c g y f z a ]
popBack -> f [ b c g y f z a ]
popBack -> y [ b c g y f z a ]
popBack -> g [ b c g y f z a ]
还有一点需要注意:我之所以不抛出任何异常,是因为我没有在其中包含任何队列实现。我仅有的库是fstream、iostream、ostream和iomanip(据我所知,根据任务的要求,我不能包括任何其他库)。
似乎没有像庸医或庸医异常这样的保留术语,所以在我抛出queueException的情况下,我只返回false(我想这就是为什么函数是bool类型的,我想不出任何其他原因:我们得到了函数原型,只是没有函数定义)。
非常感谢你抽出时间,哦,聪明的人!
您的变量items
是一个数组。您可以delete
整个阵列:
delete [] items;
或者不是delete
,你不能分段删除一个元素。
ch
由引用&
传递,这意味着如果您为其赋值,则该值将被分配给传递到函数中的变量。如果没有&
,作为参数传递的值将被复制到ch
中,如果更改ch
,则不会对原始参数产生任何影响。
指定给引用类似于指定给法线变量。引用指向与内存中另一个变量相同的数据,但它不是指针。引用只能"指向"另一个变量一次,但指针可以指向多次。
这里有一个例子:
// A silly example, which doubles the variable passed in
void doubleValue( int& i ) {
i = i * 2;
}
// Sample use:
int j = 2;
doubleValue( j ); // j is now 4
doubleValue( j ); // j is now 8
因此,如果需要返回ch
中弹出的值,可以使用数组访问,就像通常从数组中获取值一样。
char sample = items[front];