C++ kolejka implementowana dynamicznie

0

Cześć! Próbuję zaimplementować dynamicznie kolejkę FIFO w C++.
Oto kod źródłowy:


using namespace std;

struct node {
    int data;
    node *next;
};

struct queue {
    int size;
    node *head;
    node *tail;
    node *tmp;
};

void initialize(queue &q) {
    q.size = 0;
    q.head = NULL;
    q.tail = NULL;
}

bool empty(queue &q) {
    if (q.size == 0) return true;
    else return false;
}

void push(queue &q, int d) {
    node* nd = new node;
    nd -> data = d;
    if (q.head == NULL) {
        q.tail -> next = NULL;
        q.tail -> data = d;
        q.head = q.tail;
        q.size++;
    } else {
        q.tail -> next = NULL;
        q.tail -> data = d;
        q.size++;
    }
}

void pop(queue &q) {
    if (q.head == NULL) {
        cout << "Kolejka jest pusta!";
    } else if (q.tail == q.head) {
        delete q.head;
        q.head = q.tail = NULL;
        q.size--;
    } else {
        q.tmp = q.head -> next;
        delete q.head;
        q.tmp = q.head;
        q.size--;
    }
}

int first(queue &q) {
    return q.head -> data;
}

int size(queue &q) {
    return q.size;
}

int main() {
    queue Q = *new queue;
    initialize(Q);
    push(Q, 1);
    push(Q, 3);
    push(Q, 6);
    push(Q, 8);
    push(Q, 2);
    
    first(Q);
    size(Q);
    return 0;
}```

Kompilator w linii 32 wskazuje na błąd krytyczny "Thread 1: EXC_BAD_ACCESS (code=1, address=0x8)"
Pomoże ktoś początkującemu koledze? :)
Z góry dzięki!
2
void push(queue &q, int d) 
{
    node* nd = new node;
    nd->data = d;
    nd->next = NULL;
    
    if (q.head == NULL) {
        q.head = nd;
    } else {
        q.tail->next = nd;
    }
    q.tail = nd;
    ++q.size;
}
4

O ile pamiętam to już było niedawno, np. https://4programmers.net/Forum/C_i_C++/351364-kolejka_napisana_dynamicznie?p=1761539#id1761539

Na "dzień dobry" skoro twierdzisz, że piszesz w C++ polecałbym skorzystać z dobrodziejstw modelu obiektowego tego języka i użyć
a. konstruktora i destruktora
b. metod zamiast funkcji zewnętrznych.

Póki co to jest C z referencjami.

0

@alagner: wiem, ale zadanie dotyczyło programowania proceduralnego...

0

@_0x666_: dzięki wielkie!

0

using namespace std;

struct node {
    int data;
    node *next;
};

struct queue {
    int size;
    node *head;
    node *tail;
    node *tmp;
};

void initialize(queue &q) {
    q.size = 0;
    q.head = NULL;
    q.tail = NULL;
}

bool empty(queue &q) {
    if (q.size == 0) return true;
    else return false;
}

void push(queue &q, int d) {
    node* nd = new node;
    nd -> data = d;
    nd -> next = NULL;
    
    if (q.head == NULL) {
        q.head = nd;
    } else {
        q.tail -> next = nd;
    }
    q.tail = nd;
    ++q.size;
}

void pop(queue &q) {
    if (q.head == NULL) {
        cout << "Kolejka jest pusta!";
    } else if (q.tail == q.head) {
        delete q.head;
        q.head = q.tail = NULL;
    } else {
        q.tmp = q.head -> next;
        delete q.head;
        q.tmp = q.head;
    }
    --q.size;
}

int first(queue &q) {
    return q.head -> data;
}

int size(queue &q) {
    return q.size;
}

int main() {
    queue Q = *new queue;
    initialize(Q);
    push(Q, 1);
    push(Q, 3);
    push(Q, 6);
    push(Q, 8);
    push(Q, 2);
    
    first(Q);
    size(Q);
    
    return 0;
}```

mam jeszcze dwa pytania:
1) dlaczego funkcja first() oraz size() nie zwraca żadnej wartości?
2) nie mogę wywołać funkcji empty w ciele innej funkcji... np.:

```void pop(queue &q) {
    if (empty(queue &q)) {
        cout << "Kolejka jest pusta!";
    } else if (q.tail == q.head) {
        delete q.head;
        q.head = q.tail = NULL;
    } else {
        q.tmp = q.head -> next;
        delete q.head;
        q.tmp = q.head;
    }
    --q.size;
}```

błąd: 'queue' does not refer to a value 

```void pop(queue &q) {
    if (empty()) {
        cout << "Kolejka jest pusta!";
    } else if (q.tail == q.head) {
        delete q.head;
        q.head = q.tail = NULL;
    } else {
        q.tmp = q.head -> next;
        delete q.head;
        q.tmp = q.head;
    }
    --q.size;
}```

błąd: No matching function for call to 'empty'
0

@insanity: na szkołę i władzę nie poradzę... w każdym razie na zaś:

kompiluj w miarę możliwości pod gcc/clangiem -fsanitize=address -Wall

Co do Twojego pytania nr 2:
empty(queue &q) popatrz co tu jest nie tak.

Kompilator mówi Ci dość jasno

<source>:44:21: error: expected primary-expression before '&' token

44 | if (empty(queue &q)) {
| ^

W tym drugim przypadku po błędzie dostajesz info:
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/bits/range_access.h:263:5: note: candidate: 'template<class _Container> constexpr decltype (__cont.empty()) std::empty(const _Container&)'
263 | empty(const _Container& __cont) noexcept(noexcept(__cont.empty()))
| ^~~~~

A teraz popatrz na sygnaturę funkcji pop.

1
  1. Piszesz bardzo rozwlekłe, zwłaszcza push
  2. http://forum.4programmers.net/1101404
  3. Komunikaty który wali na ekran funkcja obsługująca kolejkę to jakiś nonsens.
#include <iostream>
using namespace std;

struct node
{
    int data;
    node *next;
};

struct queue
{
    size_t size;
    node *head,*tail;
};

void initialize(queue &q) 
{
	q.head=q.tail=NULL;
	q.size=0; 
}

bool empty(const queue &q) { return !q.size; }
int size(const queue &q) { return q.size; }
int first(const queue &q) { return q.head->data; }

void push(queue &q,int data) 
{
	node* tmp=new node;
	tmp->data=data;
	tmp->next=NULL;
	q.tail=(q.tail?q.tail->next:q.head)=tmp;
	++q.size;
}

bool pop(queue &q) 
{
    if(!q.head) return false;
    node *tmp=q.head;
    q.head=tmp->next;
    if(!q.head) q.tail=NULL;
    --q.size;
    delete tmp;
    return true;
}

int main()
{
    queue Q;
    initialize(Q);
    push(Q,1);
    push(Q,3);
    push(Q,6);
    push(Q,8);
    push(Q,2);
    cout<<"size="<<size(Q)<<endl;
	while(!empty(Q))
	{
		cout<<first(Q)<<endl;
		pop(Q);
	}
    cout<<"size="<<size(Q)<<endl;
    return 0;
}
3
insanity napisał(a):

@alagner: wiem, ale zadanie dotyczyło programowania proceduralnego...

WSJZW ?

Wyższa Szkoła Jedzenia Zupy Widelcem ?

Nie wiem, jak można kogoś uczyć GORSZEGO, zakazując, gdy sa możliwości.
Konstruktor a procedury iniXxxxx dzieli przepaść

0

Nota bene, na hugona pole q.tmp? Proszęż ja programistów proceduralne STRUKTURALNYCH ?

Programowanie zwane skrótowo proceduralnym, szerzej proceduralno-strukturalnym, jest starzejącym się, ale szanowanym sposobem programowania, i ja nie mam przyzwolenia, aby na to pluć.

Jednak w praktyce, jak delikwent mówi "programuję proceduralnie", najczęściej ma to znaczenie "nie programuję obiektowo". Dokładnie jak "nie szło mi z matmy" -> "jestem humanistą"
Przemyślenie STRUKTUR jest równie ważną częścią p.p. jak cięcie na funkcje

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.