LINUX.ORG.RU

Не работает push() в стеке

 ,


1

1

Привет. Стек через массив. Не работает push(), скорее я где-то накосячил.
Должно в стеке в итоге быть 0 .. 9, а там фигня.

#include <stdio.h>
#include <stdlib.h>
#define SIZE 10

void push(int *stack, int *sp, int x);
int pop(int *stack, int *sp);

int main() {
	int *stack = malloc(sizeof(int) * SIZE);
	int *sp = stack;


	for (int i = 0; i < SIZE; i++)
		push(stack, sp, i);

	for (int i = 0; i < SIZE; i++)
		printf("%i\n", stack[i]);

	free(stack);

	return 0;
}


int pop(int *stack, int *sp) {
	return stack[*sp--];
}


void push(int *stack, int *sp, int x) {
	stack[*sp++] = x;
}

В чем ошибка?



Последнее исправление: CYB3R (всего исправлений: 1)

Должно в стеке в итоге быть 0 .. 9, а там фигня.

а где-же тогда 0..9? куда они скрылись.. :-)

PS. кое-где есть кое-что лишнее

MKuznetsov ★★★★★
()
stack[*sp--]
d ★★★★★
()

В понимании того, что ты пишешь, разрисуй на бумажке что у тебя с указателями получается (причём разрисовывать надо механически - чтобы твои мысли о том, что код должен делать не влияли на то, что ты рисуешь). Ну и в качестве намёка:

Что ты тут делаешь на самом деле:

int *sp = stack;
stack[*sp++] = x;

Begemoth ★★★★★
()
Ответ на: комментарий от Begemoth

лол. Я же когда sp++, то и stack тоже смещается на один.

ChuCha
() автор топика
Ответ на: комментарий от Begemoth

Думаю, что оба варианта. Причём первое следует из второго.

CYB3R ★★★★★
()
Ответ на: комментарий от FIL

Это я ему вопрос задал. Защемта вы позалезли? Пусть бы сам подумал.

deep-purple ★★★★★
()

Выше уже писали, но без объяснения. Трудно им что ли. В квадратных скобках должен быть индекс, а не адрес. Меняй int *sp = stack; на int *sp = SIZE;

Cactus64k
()
Ответ на: комментарий от deep-purple

Что будет если добавить 11-й элемент?

ко коду ТС - то-же что и при добавлении 1-го...9 и 10-го :-) продолжит дальше пахать

ему в принципе повезло что до printf добрался

MKuznetsov ★★★★★
()
return stack[*sp--];
stack[*sp++] = x;

Это что за хрень?
p.s. нее, то что ты понаписал работать не будет никак. переделывай

FIL ★★★★
()
Последнее исправление: FIL (всего исправлений: 1)
Ответ на: комментарий от deep-purple

Когда исправит - будет, потом он дойдёт до того, что указатель на память и вершину стека надо хранить вместе в структуре.

Begemoth ★★★★★
()
Ответ на: комментарий от ChuCha

Можно вообще один указатель оставить, без индекса. И так проверок на выход за массив нету.

Cactus64k
()

В чем ошибка?

В sp. В твоем случае проще чтоб он был индексом, не указателем на голову стека. Если хочешь указателем, то:

void push(int *stack, int **sp, int x) {
        *((*sp)++) = x;
}

И вызывать как push(stack, &sp, i);

pop() тоже нужно переписать, конечно

Deleted
()
Ответ на: комментарий от Begemoth

Нуу, тогда и код будет совсем не тот который он тут щас презентовал. Подождем.

Кстати вот, я делал возврат к вершине и через остаток от деления и через проверку позиции. Как оно кавайнее то? Говорят что x%y затратная хрень. Кто-нибудь замерял?

deep-purple ★★★★★
()
Ответ на: комментарий от ChuCha

Гм. Хорошо, вот вариант с целочисленным индексом:

#include <stdio.h>
#include <stdlib.h>
#define SIZE 10

void push(int *stack, int *sp, int x);
int pop(int *stack, int *sp);

int main() {
        int *stack = malloc(sizeof(int) * SIZE);
        int sp = 0;


        for (int i = 0; i < SIZE; i++) {
                push(stack, &sp, i);
        }

        for (int i = 0; i < SIZE; i++)
                printf("%i\n", stack[i]);

        free(stack);

        return 0;
}


int pop(int *stack, int *sp) {
        return stack[(*sp)--];
}

void push(int *stack, int *sp, int x) {
        stack[(*sp)++] = x;
}
Deleted
()
Ответ на: комментарий от deep-purple

код со структурой есть. На массиве делается для понимания, так как есть вот такие видосы про алгоритмы для начинающих: алгоритмы там на массиве, и я решил попробовать.

prooflink
тема с кодом

ChuCha
() автор топика
Ответ на: комментарий от ChuCha

invalid type argument of unary «*»

Это скорее всего потому что ты в прототипе не исправил. Который до main. Оба варианта должны работать нормально

Deleted
()
int pop(int **stack);
void push(int **stack, int x);
E ★★★
()
Ответ на: комментарий от deep-purple

Насколько я помню деление с остатком идет через побитовое И.

Cactus64k
()
Ответ на: комментарий от deep-purple

Даешь больше кастов!

Ты про это *((*sp)++) = x;? Нет же ни одного каста. Вообще да, выглядит страшненько, лучше записать двумя строками, но решил оставить в стиле ТС.

Deleted
()
Ответ на: комментарий от anonymous

хаха, он уже над моим кодом угарал =)

ChuCha
() автор топика
Ответ на: комментарий от deep-purple
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10

int st_is_full();
int st_is_empty();
void push(int item);
int pop();
void print_stack();

struct stack {
	int s[SIZE];
	int top;
} st;


int main() {
	st.top = 0;

	push(12);
	push(11);
	push(10);

	pop();

	push(10);
	push(12);

	print_stack();
	return 0;
}

int st_is_full() {
	if (st.top >= SIZE - 1)
		return 1;
	else
		return 0;
}


int st_is_empty() {
	if (st.top == -1)
		return 1;
	else
		return 0;
}


void push(int item) {
	st.top++;
	st.s[st.top] = item;
}


int pop() {
	int item;
	item = st.s[st.top];
	st.top--;

	return item;
}


void print_stack() {
	if (st_is_empty())
		printf("\nStack is empty\n");
	else {
		for (int i = st.top; i > 0; i--)
			printf("%i\n", st.s[i]);
	}
}
ChuCha
() автор топика
Ответ на: комментарий от ChuCha
	st.top++;
	st.s[st.top] = item;

Надо наоборот, сначала присваивать, потом увеличивать. Ну и проверка на пустой стек неправильная.

По хорошему, и в push() и в pop() нужно делать проверки размера стека.

Нарисуй на бумаге, проще же будет.

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.