Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

ANUS C

Name: Anonymous 2010-03-26 20:36

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");}
   
    return 0;
    }

void push(STACK **s, int item){
    STACK *new;
    new = (STACK *) malloc(sizeof(STACK));
    new->value = item;
    new->next = *s;
    *s = new;}

int pop(STACK **s, int *error){
    STACK *old = *s;
    int oldValue;
    if(*s){
        oldValue = old->value;
        *s = (*s)->next;
        free(old);
        *error = 0;}
    else{
        oldValue = 0;
        *error = 1;}
    return(oldValue);}

Name: HIBT 2010-03-26 23:26

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:

void push(node** s, int item);
((*s)->value)

if instead he were to change it to:

typedef stack* stackobject;
struct stack {
  node* head;
};

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

...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

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List