开发者

"this" pointer in C (not C++)

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?


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.


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


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);


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜