1

For an assignment I was tasked with creating a queue with linked lists. Our professor has given us the test code to insure the program is working properly and for grading. My serve function returns a character. However in the main(), the function is called twice within one cout statement, and it returns the character in incorrect order. The getSize function is also called, however it does not seem to do anything.

cout << boolalpha;
Queue q1 = Queue();
q1.append('m');
q1.append('a');
q1.append('b');
q1.append('b');
q1.display();
cout << q1.serve() << " " << q1.serve() << " " << q1.getSize() << endl;

the display outputs: m a b b. However the cout shows as: a m 4. This should obviously come out as: m a 2.

If i separate the serve and the getSize functions, it works just fine, i.e. cout << q1.serve() << " "; cout << q1.serve() << " "; cout << q1.getSize() << " ";

Below I have posted the code for the linked queue. I imagine I have made a mistake with my node pointers, however I have drawn pictures and re-written the code to no avail. I also apologize if Ive improperly formatted this as it is my first posting. Thank you.

#include <iostream>
using namespace std;
struct Node {
    char data;
    Node* next;
};

class Queue {
private:
    Node* front, * rear;
    int size;
public:
    Queue();
    void append(char);
    char serve();
    bool isEmpty();
    bool isFull();
    int getSize();
    void display();
}; 

Queue::Queue() {
    front = rear = nullptr;
    size = 0;
}

void Queue::append(char v) {
    Node* p = new Node;
    p->data = v;
    p->next = nullptr;
    if (size == 0) {
        front = rear = p;
        size++;
    }
    else if (size == 1) {
        front->next = p;
        rear = p;
        size++;
    }
    else {
        rear->next = p;
        rear = p;
        size++;
    }
}

char Queue::serve() {
    if (front != nullptr) {
        Node* temp = front;
        char v = temp->data;
        front = front->next;
        delete temp;
        size--;
        return v;
    }
}

bool Queue::isEmpty() {
    return size == 0;
}

bool Queue::isFull() {
    return false;
}

int Queue::getSize() {
    return size;
}

void Queue::display() {
    Node* runner = front;
    while (runner != nullptr) {
        cout << runner->data << " ";
        runner = runner->next;
    }
    cout << endl;
}

int main() {
    cout << boolalpha;
    Queue q1 = Queue();
    q1.append('m');
    q1.append('a');
    q1.append('b');
    q1.append('b');
    q1.display();
    cout << endl << q1.isEmpty() << " " << q1.isFull() << " " << q1.getSize() << endl;
    cout << q1.serve() << " " << q1.serve() << " " << q1.getSize() << endl;
    q1.display();
    cout << endl;

    /*cout << q1.isEmpty() << " " << q1.isFull() << " " << q1.getSize() << endl;
    char a = q1.serve(); char b = q1.serve();
    cout << a << " " << b << " " << q1.getSize() << endl;*/ 
}
  • With `std::cout` the order of evaluation of arguments is unspecified. It doesn't have to be left to right. – jignatius Dec 04 '19 at 23:58
  • Looks like dupe of [order of evaluations](https://stackoverflow.com/questions/7718508/order-of-evaluation-of-arguments-using-stdcout)? – Kai Dec 04 '19 at 23:59

1 Answers1

0

I'll give you a big hint: Your output is "a m 4", not "m a 4". The remainder of the answer is below...

.

.

.

.

.

.

(edit: added more explanation)

The cout is running the arguments right to left, because of the associativity of the << operator. So it's getting the size, then getting the first item in the queue, then getting the next one. Even though the operator itself is Left-to-Right, in order to apply them in that order, it's evaluating the arguments right to left.

Think of it this way, while it's required to apply the operators on the left before it applies the ones on the right, it's still evaluating the argument on the right of the operator before it evaluates the one on the left.

This is fundamentally about how the stack works. It's loading the evaluation of the arguments and operators right to left so that it can apply the operators in the reverse order.

Since the operators are all the same precedence, it's pushing the right most operand, then the right most operator, then that' operator's left operand, which is everything to the left.

If your operators are L-R associative, that means that the operands are evaluated R-L before being operated on L-R.

Just do

        cout << q1.serve() << " ";
        cout << q1.serve() << " ";
        cout << q1.getSize() << endl;
Community
  • 1
  • 1
Trenchie
  • 11
  • 2
  • And your professor should *really* know this. If they're teaching C++, they should understand the stack. Like, this should have been REALLY obvious to him. – Trenchie Dec 05 '19 at 00:12