我认为问题出现在main()中,但是编译得很好,但我没有输出。我想也许它不是正确的,因为在调试模式下它说
“myCharQ {item=0x0018fa00 "ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ̺yâpú" front=-858993460 rear=-858993460 ...}
”
你会如何改写它以使它合适?我刚开始上课,所以任何帮助都会有用。
以下是基于数组的队列类
#include <iostream>
#include <cstdlib>
using namespace std;
const int MaxQueueSize = 10; // Queue Struct can hold up to 10 char.
typedef char ItemType; // the queue's data type is char
class CPPQueue
{
public:
CPPQueue();
ItemType item[MaxQueueSize];
void initQueue(CPPQueue q);
bool IsEmpty(CPPQueue q);
bool IsFull(CPPQueue q);
void Enqueue(CPPQueue q, ItemType newItem);
void PrintQ(const CPPQueue q);
void PrintQueueInfo(CPPQueue myQ);
ItemType Dequeue(CPPQueue q);
private:
int front, rear;
int count;
};
CPPQueue::CPPQueue()
{
int front, rear, count = 0;
}
void CPPQueue::initQueue(CPPQueue q)
{
q.front = q.rear = q.count = 0;
}
bool CPPQueue::IsEmpty(CPPQueue q)
{
return (q.count == 0);
}
bool CPPQueue::IsFull(CPPQueue q)
{
return (q.count == MaxQueueSize);
}
void CPPQueue::Enqueue(CPPQueue q, ItemType newItem)
{
if(q.count == MaxQueueSize)
{
cerr << "Error! Queue is full, cannot enqueue item.\n" << endl;
exit(1);
}
q.item[q.rear] = newItem;
q.rear++;
if (q.rear == MaxQueueSize)
{
q.rear = 0; // adjustment for circular queue
}
q.count++;
}
ItemType CPPQueue::Dequeue(CPPQueue q)
{
ItemType theItem;
if(q.count == 0)
{
cerr << "Error! Queue is empty, cannot dequeue item.\n" << endl;
exit(1);
}
theItem = q.item[ q.front ];
q.front++;
if (q.front == MaxQueueSize)
{
q.front = 0; // adjustment for circular queue
}
q.count--;
return theItem;
}
// Function PrintQ() prints the contents of the queue without changing
// the queue. Printing starts at the "front" index and stops before we
// get to the "rear" index. A decrementing counter controls the loop.
//
void CPPQueue::PrintQ(const CPPQueue q)
{
int i;
int qindex = q.front;
for(i = q.count; i > 0; i--)
{
cout << q.item[qindex] ;
qindex = (++qindex) % MaxQueueSize; // adjustment for circular queue
if(i > 1)
cout << ", ";
}
}
// Helper function for the main program below.
void CPPQueue::PrintQueueInfo(CPPQueue myQ)
{
cout << "The queue contains: ";
PrintQ(myQ);
cout << endl;
}
int main()
{
CPPQueue myCharQ;// queue holds characters
char ch; // char dequeued
myCharQ.initQueue(myCharQ);
myCharQ.Enqueue(myCharQ, 'a'); myCharQ.PrintQueueInfo(myCharQ);
myCharQ.Enqueue(myCharQ, 'b'); myCharQ.PrintQueueInfo(myCharQ);
myCharQ.Enqueue(myCharQ, 'c'); myCharQ.PrintQueueInfo(myCharQ);
ch = myCharQ.Dequeue(myCharQ); myCharQ.PrintQueueInfo(myCharQ);
ch = myCharQ.Dequeue(myCharQ); myCharQ.PrintQueueInfo(myCharQ);
myCharQ.Enqueue(myCharQ, 'e');
myCharQ.Enqueue(myCharQ, 'f'); myCharQ.PrintQueueInfo(myCharQ);
myCharQ.Enqueue(myCharQ, 'g'); myCharQ.PrintQueueInfo(myCharQ);
cout << endl;
// print the dequeued characters
while(!myCharQ.IsEmpty(myCharQ))
{
ch = myCharQ.Dequeue(myCharQ);
cout << ch << " ";
}
cout << endl << endl;
return 0;
}
答案 0 :(得分:6)
您永远不会初始化成员变量front
,rear
和count
。您可以通过再次声明具有相同名称的变量来在构造函数中隐藏它们。删除int
并仅分配它们(尽管这不是为什么值不能正确打印的原因,更多的是在一点上)。实际上,也不要这样做;使用初始化列表:
CPPQueue::CPPQueue()
: front(0), rear(0), count(0)
{ }
另外,为什么你有initQueue
功能?你已经有了一个构造函数,依靠它来初始化你的实例(这不是C!)。
接下来,像IsEmpty
这样的函数是非静态成员函数,但它们不在当前实例上运行。不要将队列作为参数,只要在实例为空,满,等等时返回。您的代码必须像这样使用:
Queue q;
q.IsEmpty(q);
很奇怪。您的所有成员函数都以这种方式运行。当您使用成员函数时,将指向当前实例的隐式指针作为隐藏参数(this
)传递。因此,每次调用函数时,它都会在调用它的实例的上下文中运行。您不需要将实例作为参数。
还要意识到所有函数都按值来获取参数。你将像疯了一样创建这些队列的副本。如果修改参数,调用者将无法看到它。例如:
void CPPQueue::initQueue(CPPQueue q)
{
q.front = q.rear = q.count = 0;
}
这基本上是无用的(除了不需要初始化函数的事实)。当您在副本上操作时,对q.front
,q.rear
和q.count
的更改将不会在该函数之外显示。
因此,即使您的构造函数由于变量阴影而中断,此也是您在调用initQueue
后仍然无法打印预期的原因。 您正在修改副本。
至于你的实现,它根本不健壮。您将基础数组公开给您的类的客户端。这是一个坏主意。不应直接访问队列中的项目。如果我决定直接使用数组怎么办?现在你所有的状态变量都是错误的。 front
,rear
和count
都可能无效,因为我修改了队列状态而未通过任何功能。
甚至没有必要;我应该做的就是排队和出队物品。而已。这就是队列的作用。它不是一个数组,如果我想要一个数组,我会用一个。
因此,总而言之,开始学习一门相对复杂的语言。坚持下去,不要气馁,我们都必须在某些时候学习这些东西。
编辑:我必须跑步,但这里是你的一些课程的快速改写。我已删除了item类型的typedef。为什么?这是不必要的。您不会将其更改为某个平台或其他环境更改的其他类型,因此typedef只会伤害您的类的可用性。对于某些环境原因,typedef适用于可能发生变化的事情(即int32_t),但是如果它们没有帮助你或你的代码的客户,那么它们只是阻碍它的另一件事。class CPPQueue
{
public:
CPPQueue();
bool IsEmpty() const;
bool IsFull() const;
void Enqueue(char newItem);
char Dequeue();
void PrintQ() const;
void PrintQueueInfo() const;
private:
char item[MaxQueueSize];
int front
int rear;
int count;
};
CPPQueue::CPPQueue()
: front(0), rear(0), count(0) { }
bool CPPQueue::IsEmpty() const
{
// you don't actually need the this pointer
// here, but I included it to make it clear
// that you are accessing the count variable
// for the current instance of a CPPQueue
return this->count == 0;
}
我希望这可以帮助你重写课程的其余部分,现在就去。我在函数声明中添加了const
,这些函数不应该改变CPPQueue
的内部状态。搜索“const correctness”以更好地了解为什么要做这样的事情。祝你好运!
答案 1 :(得分:4)
在你的构造函数中:
int front, rear, count = 0;
错了。这些是影响成员变量的局部变量。
您应该使用成员初始值设定项(在构造函数名后面加冒号)。
另请注意,您在整个地方传递值 - 您可能希望通过引用传递 - 查看每个函数参数并问自己,“我是否需要我的参数的新副本或我是否要参考到我传入的相同参数(相同的内存位置)?“
CPPQueue::CPPQueue() :
front(0), rear(0), count(0)
{
}
注意:@OP这是初级C ++ - 您需要阅读并掌握基础知识,否则您将遇到很多困难,更难以解决问题。