I'm trying to create a stack in C for fun, and came up with the idea of using struct to represent the stack. Then I add function pointers to the struct for push() and pop() operations.

So far all is good it seems, but, for the implementation of the push() and pop() functions I need to refer to *this somehow. How can that (can it?) be done?

This is my struct

struct Stack { int *data; int current_size; int max_size; int (*push)(int); int (*pop)(); }; 

And as an example here's push

int push(int val) { if(current_size == max_size -1) return 0; data[current_size] = val; current_size++; return 1; } 

As you can imagine, the compiler has no idea what current_size is, as it would expect something like stack->current_size.

Is this possible to overcome somehow?

2

7 Answers

There's no implicit this in C. Make it explicit:

int push(Stack* self, int val) { if(self->current_size == self->max_size - 1) return 0; self->data[self->current_size] = val; (self->current_size)++; return 1; } 

You will of course have to pass the pointer to the struct into every call to push and similar methods.

This is essentially what the C++ compiler is doing for you when you define Stack as a class and push et al as methods.

4

The typical approach in C is to have functions expect this as the first parameter.

int push(Stack *self, int val) { if (self->current_size == self->max_size -1) return 0; self->data[self->current_size++] = val; return 1; } 

This has the added benefit that, unless you need polymorphism, you don't need to put the functions in the stack, because you could just call push(stack, 10) instead of stack->push(stack,10).

1

C doesn't work like that. It's not an object oriented language. Functions that manipulate data structures need to take a pointer to the structure as an argument.

In header file you can declare static this variable

static struct Stack *this; 

And then in push method you can use this variable

static int push(int val) { if(this->current_size == this->max_size - 1) return 0; this->data[this->current_size] = val; (this->current_size)++; return 1; } 

The caveat is you have to manually set this variable through some method before you want to invoke other methods, eg:

struct Stack { struct Stack (*_this)(struct Stack *); // <-- we create this method int *data; int current_size; int max_size; int (*push)(int); int (*pop)(); }; 

And then we can implement _this method as

static struct Stack *_this(struct Stack *that) { retrun this = that; } 

The example:

struct Stack stack1, stack2; ... some initialization ... stack1->_this(&stack1)->push(0); stack1->push(1); stack1->push(2); stack2->_this(&stack2); stack2->push(10); stack2->push(20); 
1

Your function pointers aren't methods so they don't have any information about the calling object. The only way to do what you want is to either pass in a pointer to the object, or make that pointer global (the latter is not recommended).

Obviously you can have a Stack * member in the struct and then just initialize it with the address of the struct before you use the function pointers. Then make the Stack * a parameter on the function pointers.

8

Since your are going to have only one Stack structure (that you named stack, apparently), you could define it as a global variable. This would allow pop/push to refer to the stack variable directly.

You would do something like:

stack.current_size += 4;

or use the -> operator if you decide to declare stack as a memory pointer to Stack.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy