2010-12-14 13 views
12

Estoy intentando crear una pila en C por diversión, y se me ocurrió la idea de usar struct para representar la pila. Luego agrego punteros a la estructura para las operaciones push() y pop()."este" puntero en C (no en C++)

Hasta ahora todo parece bueno, pero, para la implementación de las funciones push() y pop(), necesito referirme a * esto de alguna manera. ¿Cómo puede eso (¿puede?) Hacerse?

Esta es mi estructura

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

Y como ejemplo aquí es empujar

int push(int val) { 
    if(current_size == max_size -1) 
      return 0; 

    data[current_size] = val; 
    current_size++; 

    return 1; 
} 

Como se puede imaginar, el compilador no tiene idea de lo que current_size es decir, como sería de esperar algo así como stack->current_size.

¿Es posible superar esto de alguna manera?

+0

¿cuál es el punto de función de los punteros en su stack struct? – Nyan

+0

Para tratar de obtener una respuesta, si es posible llamar a una pila de este tipo como esta: 'stack-> push (10);'. Ahora, si la respuesta no está aquí, puedo estar seguro de que es imposible. – foo

Respuesta

26

no hay implícita this en C. hacerlo explícito:

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

Usted, por supuesto, tiene que pasar el puntero a la estructura en cada llamada a push y métodos similares.

Esto es esencialmente lo que hace el compilador de C++ cuando define Stack como una clase y push y otros como métodos.

+1

Así es como trabaja C++ detrás de escena. Hacer esto. – aib

+3

Esa es la idea, pero usar 'this' como variable es incómodo, si alguien alguna vez intenta incluir tu C en un programa C++. –

+0

@aib, @Victor: buenos puntos; He editado la respuesta. Gracias. – NPE

1

C no funciona así. No es un lenguaje orientado a objetos. Las funciones que manipulan las estructuras de datos deben tomar un puntero a la estructura como argumento.

0

Los punteros de función no son métodos, por lo que no tienen información sobre el objeto que realiza la llamada. La única forma de hacer lo que desea es pasar un puntero al objeto o hacer que ese puntero sea global (no se recomienda este último).

-2

Obviamente, puede tener un miembro de pila * en la estructura y luego simplemente inicializarlo con la dirección de la estructura antes de utilizar los punteros de función. Luego, haga que Stack * sea un parámetro en los punteros de función.

+4

Usted acaba de cerrar su automóvil con las llaves adentro. –

+0

Eso parece obvio. No me acuerdo de eso, debo probarlo. Gracias – foo

+0

Me pregunto si los usuarios diferentes en este sitio ven preguntas antes que los demás. No veo cómo una pregunta como esta puede obtener cuatro respuestas en menos de un minuto. – ThomasMcLeod

2

El enfoque típico en C es que las funciones esperen this como primer parámetro.

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

Esto tiene la ventaja añadida de que, a menos que necesite polimorfismo, no es necesario poner las funciones de la pila, ya que sólo podría llamar push(stack, 10) en lugar de stack->push(stack,10).

+0

Gracias. Ese fue mi primer enfoque, pero quería divertirme un poco con los indicadores de función y quería ver hasta qué punto era posible conseguir que C obtuviera un comportamiento en C++. El propósito de esto es educarme y experimentar, nada serio. Estoy de acuerdo en que usar 'push (stack, 10)' es lo más sensato que se puede hacer en C. – foo

-1

Debido a que su van a tener un solo Pila estructura (que denominó pila, al parecer), se podría definir como una variable global. Esto permitiría que pop/push haga referencia directamente a la variable stack.

Se podría hacer algo como:

pila.current_size + = 4;

o utilizar el - operador> si decide declarar pila como un puntero de memoria a Pila.

-1
#include <stdio.h> 
#include <stdlib.h> 
#include <malloc.h> 


typedef struct _foo 
{ 
    int q; 
    void (*Bar)(); 
} Foo; 
Foo * This; 

Foo * foo(Foo * f) 
{ 
    This = f; 
    return f; 
} 

void Bar() 
{ 
    printf("%i\n",This->q); 
    This->q++; 
} 


Foo * FooNew() 
{ 
    Foo * foo = malloc(sizeof(Foo)); 
    foo->q = 1; 
    foo->Bar = &Bar; 
} 

int main() 
{ 
    Foo *f = FooNew(); 
    Foo *g = FooNew(); 


    foo(f)->Bar(); 
    foo(f)->Bar(); 
    foo(f)->Bar(); 

    foo(g)->Bar(); 
    foo(g)->Bar(); 
    foo(g)->Bar(); 

    return 0; 
}