Hi /prog/,
so I'm new into ANSI C because you guys always advocate for it. I crammed together this piece of code but it seems that I did not really understand why I had to use a double-reference in the function call. Could you please enlighten me!
#include <stdio.h>
#include <stdlib.h>
#define MAX 10
typedef struct stack{
int value;
struct stack *next;
} STACK;
STACK s;
void push(STACK **, int);
int pop(STACK **, int *);
int main(void){
STACK *p, **pp;
p = &s; pp = &p;
*pp = NULL;
int i, x, error;
for(i = 0; i < MAX; i++){
push(pp, i);}
for(i = 0; i < MAX+1; i++){
x = pop(pp, &error);
if(!error) printf("pop (): %d\n", x);
else printf("error: stack empty\n");}
The sane way to represent a stack is with an [b][u][i]ADT[/Ii][/u][/b], in C that'd be with a struct:
struct stackobject {
stack* _stack;
};
struct stack {
node* head;
};
struct node {
int value;
node* next;
};
To functions manipulating the stack you can then pass either a pointer:
void push(stackobject* s, int item);
(example accessing stack head value: s->_stack->head.value)
...or a value:
void push(stackobject s, int item);
(s._stack->head.value)
you could then branch into buiOoP techniques and have stuff like
struct stackobject {
stack* _stack;
void (*push)(stackobject* s, int item);
int (*pop)(stackobject* s, int error);
};
("s->push(s, 1234)" styled syntax and bundling operations in datastructures is supposed to be convenient or whatever);
but the enterprise microoptimizing genius that wrote that decided that the stack object will only ever contain the equivalent to _stack member, in my notation this'd be:
struct stackobject {
node* _head;
};
struct node {
int value;
node* next;
};
he then figured that a struct with one member is the same(durr) as having just the member,
typedef node* stackobject; //bastard doesnt even typedef it
struct node {
int value;
node* next;
};
... then made an extra mistake; the "node*" typed stackobject points to the stack head, instead of pointing to an another struct that contains a pointer to head.
since the head will change as you push and pop items, those functions will have to have the node* passed a pointer (so node**) (reason for this is so push/pop can change head with sideeffects) example signature:
...you'd be able to implement push and pop to work with either stackobject (stack*) or stackobject* (stack**) being passed in (head is changed through a pointer in a pointer inside stackobject so no problem).
tldr; buioeXTRAlEVELoFiNDIRECTION you have double pointers because someone didnt read their SICP chapter 3.
im stoned as a canadian ATM so i dont dare attempt to put in code tags someone help oh god they are coming for me wh
Name:
Anonymous2010-03-26 23:47
>>5
I fail to see what Atlantic Daylight Time has to do with anything.
>>12
Because ``the computer'' (evidently a library or toy language runtime of some kind) probably sucks at it as much as every other such implementation.
>>11 >>8 just uses the same struct node each time. that's why the stack ends up with every value being 9.
here's a fixed version: #include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#define MAX 10
struct node { int value; struct node *next; };
struct stack { int depth; struct node *top; };
int main(void)
{ struct stack s = {0, NULL};
for(int i = 0; i < MAX; ++i) push(&s, i);
for(int i = 0; i < MAX + 1; ++i) printf("pop: %d\n", pop(&s));
return 0; }