2010-12-14 26 views
12

Tôi đang cố gắng tạo một ngăn xếp trong C cho vui, và nảy ra ý tưởng sử dụng cấu trúc để biểu diễn ngăn xếp. Sau đó, tôi thêm các con trỏ hàm vào cấu trúc cho các hoạt động push() và pop()."con trỏ" này trong C (không phải C++)

Cho đến nay tất cả đều tốt, nhưng, để thực hiện các hàm push() và pop() tôi cần tham khảo * bằng cách nào đó. Làm thế nào có thể (có thể nó?) Được thực hiện?

Đây là struct tôi

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

Và như một ví dụ ở đây là đẩy

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

    data[current_size] = val; 
    current_size++; 

    return 1; 
} 

Như bạn có thể tưởng tượng, trình biên dịch không có ý tưởng gì current_size là, vì nó mong chờ một cái gì đó giống như stack->current_size.

Điều này có thể khắc phục bằng cách nào đó không?

+0

điểm con trỏ hàm trong cấu trúc ngăn xếp của bạn là gì? – Nyan

+0

Để cố gắng nhận được câu trả lời nếu có thể gọi một chồng kiểu này như sau: 'stack-> push (10);'. Bây giờ, nếu câu trả lời không được đưa ra ở đây tôi có thể khá tự tin rằng nó thực sự là không thể. – foo

Trả lời

26

Không có tiềm ẩn this trong C. Làm cho nó rõ ràng:

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

Bạn sẽ đương nhiên phải vượt qua con trỏ đến struct vào mỗi cuộc gọi đến push và phương pháp tương tự.

Đây thực chất là trình biên dịch C++ đang làm cho bạn khi bạn xác định Stack làm lớp và push et al làm phương thức.

+1

Đây là cách C++ hoạt động đằng sau hậu trường. Làm cái này. – aib

+3

Đó là ý tưởng, nhưng bằng cách sử dụng 'this' như một biến là khó xử, nếu ai đó bao giờ cố gắng bao gồm C của bạn trong một chương trình C++. –

+0

@aib, @Victor: Điểm tốt; Tôi đã chỉnh sửa câu trả lời. Cảm ơn. – NPE

1

C không hoạt động như thế. Nó không phải là một ngôn ngữ hướng đối tượng. Các hàm điều khiển các cấu trúc dữ liệu cần đưa một con trỏ tới cấu trúc như một đối số.

0

Con trỏ hàm của bạn không phải là phương thức để chúng không có bất kỳ thông tin nào về đối tượng gọi. Cách duy nhất để làm những gì bạn muốn là truyền một con trỏ tới đối tượng, hoặc làm cho con trỏ đó là toàn cầu (cái này không được khuyến khích).

-2

Rõ ràng bạn có thể có một thành viên Stack * trong cấu trúc và sau đó chỉ cần khởi tạo nó với địa chỉ của cấu trúc trước khi bạn sử dụng các con trỏ hàm. Sau đó, hãy tạo tham số Stack * trên các con trỏ hàm.

+4

Bạn vừa khóa xe bằng các phím bên trong. –

+0

Điều đó có vẻ hiển nhiên. Đã không làm điều đó, phải thử nó ra. Cảm ơn – foo

+0

Tôi tự hỏi liệu những người dùng khác nhau trên trang web này có xem câu hỏi trước những người khác hay không. Tôi không thấy làm thế nào một câu hỏi như thế này có thể nhận được bốn câu trả lời trong vòng chưa đầy một phút. – ThomasMcLeod

2

Cách tiếp cận điển hình trong C là có các hàm mong đợi this làm thông số đầu tiên.

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

này có thêm lợi ích đó, trừ khi bạn cần đa hình, bạn không cần phải đặt các chức năng trong ngăn xếp, bởi vì bạn chỉ có thể gọi push(stack, 10) thay vì stack->push(stack,10).

+0

Cảm ơn. Đó là cách tiếp cận đầu tiên của tôi, nhưng tôi muốn có một số thú vị với các con trỏ hàm và muốn xem cách xa để có thể nhận được C để có được một hành vi C++. Mục đích của việc này là để giáo dục bản thân và thử nghiệm, không có gì nghiêm trọng. Tôi đồng ý rằng sử dụng 'push (stack, 10)' là điều hợp lý nhất để làm trong C. – foo

-1

Vì bạn sẽ chỉ có một cấu trúc Ngăn xếp (bạn đặt tên là ngăn xếp, rõ ràng), bạn có thể xác định nó là biến toàn cầu. Điều này sẽ cho phép cửa sổ bật/tắt tham chiếu trực tiếp biến số ngăn xếp.

Bạn sẽ làm điều gì đó như:

ngăn xếp.current_size + = 4;

hoặc sử dụng - điều hành> nếu bạn quyết định tuyên bố chồng như một con trỏ bộ nhớ để stack.

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