2011-02-02 79 views
10

Cách khai báo một con trỏ để hoạt động trong C, để con trỏ tự biến động.C: Khai báo con trỏ biến động thành hàm

static void volatile (* f_pointer)(void*); 

static void (volatile * f_pointer)(void*); 

static void (* volatile f_pointer)(void*); 

Tại sao tôi hỏi điều này? Tôi đọc tại http://wiki.answers.com/Q/Volatile_example_code_sample_coding_of_volatile_pointer về con trỏ dễ bay hơi.

Có đôi khi vấn đề với con trỏ dễ bay hơi và con trỏ đến biến động:

Bây giờ, nó chỉ ra rằng các con trỏ tới biến không ổn định là rất phổ biến. Cả hai tờ khai tuyên bố foo là một con trỏ đến một số nguyên không ổn định:

volatile int * foo; 
int volatile * foo; 

con trỏ dễ bay hơi để biến non-volatile là rất hiếm (Tôi nghĩ rằng tôi đã sử dụng chúng một lần), nhưng tốt hơn tôi nên đi trước và cung cấp cho bạn cú pháp:

int * volatile foo; 

Vì vậy, tôi muốn có được một con trỏ biến động thực hiện chức năng không phải là một con trỏ đến "dễ bay hơi" chức năng.

Cảm ơn

+4

Tại sao bạn muốn một con trỏ dễ bay hơi đến một hàm? Ai sẽ thay đổi con trỏ này? Bạn có biết 'volatile' _really_ có nghĩa là gì không? –

+0

@ James McNellis, Vâng, tôi muốn. Con trỏ này được thay đổi bởi chuỗi 0 và được sử dụng bởi các chủ đề 1..7 để bắt đầu một hàm.Có một rào cản giữa, nhưng tôi muốn trình biên dịch chuyển con trỏ này sang bộ nhớ trong chuỗi 0 trước khi vào một rào cản. Ngoài ra tôi muốn các chủ đề 1..7 để đọc lại con trỏ này (có một vòng lặp '{barrier, pointer read, calling function}'). Tôi sử dụng một hệ thống với rất nhiều thanh ghi có sẵn, do đó trình biên dịch có thể lưu vào bộ nhớ cache rất nhiều biến. Tôi có đúng không? – osgx

+0

Nếu rào chắn được viết chính xác, trình biên dịch không nên lưu vào bộ nhớ đệm các giá trị trên nó - 'biến động' không cần thiết. – caf

Trả lời

11

Hãy suy nghĩ về các dấu hoa thị như là một "rào cản". Vòng loại (const hoặc volatile) gần tên biến hơn dấu hoa thị sửa đổi chính con trỏ. Vòng loại cách xa tên biến hơn dấu hoa thị sửa đổi những gì con trỏ sẽ tham chiếu đến. Trong trường hợp này, do đó, bạn sẽ có:

static void * volatile f_pointer(void *); 

Trừ, tất nhiên, mà bạn cần dấu ngoặc để xác định một con trỏ tới một hàm thay vì định nghĩa một hàm trả về một con trỏ:

static void (*volatile f_pointer)(void *); 

static là một lớp lưu trữ chứ không phải là một vòng loại, do đó, giống nhau là không phải là đúng trong trường hợp của nó. Bạn chỉ có thể chỉ định một lớp lưu trữ cho chính biến đó chứ không chỉ định nó. Không có điều gì như là một "con trỏ đến extern int" hoặc "con trỏ đến tĩnh int", chỉ "con trỏ đến int". Nếu bạn chỉ định một lớp lưu trữ (static hoặc extern), nó luôn luôn là trước tiên.

Khác threads đã thảo luận mối quan hệ giữa luồng và volatile vì vậy tôi sẽ không lặp lại điều đó ở đây ngoài việc lưu ý rằng có thể này sẽ không hữu ích.

6
static void (* volatile f_pointer)(void*); 
9

cdecl do thỏa thuận thực sự tiện dụng cho loại vấn đề:

$ cdecl 
Type `help' or `?' for help 
cdecl> declare f_pointer as static volatile pointer to function(pointer to void) returning void 
static void (* volatile f_pointer)(void *) 
cdecl> 

Nguồn cdecl: http://cdecl.org/files/cdecl-blocks-2.5.tar.gz

+2

@osgx - Có phiên bản trực tuyến tại http://cdecl.org/ –

+0

@osgx, bao gồm rất nhiều môi trường phát triển. Tôi dường như nhớ xây dựng mỏ từ nguồn, nhưng tôi không nhớ mình đã lấy nó ở đâu. Bạn có thể sử dụng nó trực tuyến tại http://cdecl.org/. –

+0

Cảm ơn! Bạn có thể đặt tên một số IDE, trong đó bao gồm một cdecl? (Tôi nghĩ rằng ny IDE với cdecl bao gồm phải rất thân thiện) – osgx

Các vấn đề liên quan