2012-12-04 32 views
14

Nếu tôi có một va_list tôi biết làm thế nào để trích xuất tất cả các yếu tố của nó:Làm thế nào để điền vào một va_list

void printInts(int n,...) 
{ 
    va_list va; 
    va_start(va, n); 
    for(unsigned int i=0; i<n; i++) 
    { 
     int arg=va_arg(va, int); 
     printf("%d",arg); 
    } 
    va_end(va); 
} 

Vì vậy, khi tôi gọi printInts (3,1,2,3) các va_list được điền tất cả những thông số.
Nhưng làm cách nào để tự điền một va_list mà không dùng va_start? Ý tôi là tôi muốn một cái gì đó như:

va_list va; 
push_arg(va, int, 5); // And so on until I fill all parameters 
... 

Tôi cần điều này vì có hàm chấp nhận va_list làm đối số và tôi không biết cách điền vào va_list của tất cả các tham số của nó.

+0

Loại 'va_list' không thực sự là một danh sách như vậy, nó thực sự thường là một loại con trỏ vào ngăn xếp và' va_arg' sửa đổi con trỏ này để trỏ đến đối số tiếp theo trên ngăn xếp. –

+0

@JoachimPileborg: Đôi khi nó không phải là một con trỏ vào ngăn xếp. –

+0

Tại sao bạn không muốn sử dụng 'va_start'? – szx

Trả lời

12

Không có khả năng điền va_list một cách rõ ràng.

Bạn nên viết hàm bao bọc. Giả sử bạn cần phải gọi hàm foo của bạn, thay vì bằng tay điền vào một va_list, bạn định nghĩa một hàm mới như vậy:

void call_foo(int arg1, ...) 
{ 
    va_list ap; 
    va_start(ap, arg1); 
    foo(arg1, ap); 
    va_end(ap); 
} 

Bây giờ bạn có thể gọi foo, trong đó có một va_list, tuy nhiên bạn thích, bằng cách làm ví dụ call_foo (1,2,3,4) ;, call_foo (1, 1, "Hello"); v.v.

Điều này sẽ chỉ cho phép bạn chỉ định đối số tại thời gian biên dịch, bạn không thể tạo đối số khi chạy.

0

Tôi không nghĩ rằng có một cách tiêu chuẩn để thực hiện việc này. Mặt khác, một số tiền được điền sẵn va_list sẽ hoàn toàn vô ích, vì không có cách nào "truy vấn" nó cho số và loại đối số có sẵn.

+2

Tôi nghĩ câu hỏi này giống như "làm cách nào để gọi" vprintf() '?" và câu trả lời là "write' printf() 'và gọi nó từ đó". –

+0

Có một chức năng của một khung công tác chấp nhận va_list, làm cách nào để tôi thực hiện việc này? –

+0

@RamyAlZuhouri Như được viết trong - cho đến nay - hai câu trả lời. – glglgl

8

Thông thường, các hàm này theo cặp. Nếu bạn có một "va-chấp nhận" chức năng, nó rất dễ dàng để tạo ra một số khác:

void printInts_v(int n, va_list ap) 
{ 
    unsigned int i=0; 
    for(i=0; i<n; i++) 
    { 
     int arg=va_arg(ap, int); 
     printf("%d", arg); 
    } 
} 

Chức năng này có thể được gọi theo cách này:

void printInts(int n,...) 
{ 
    va_list ap; 
    va_start(ap, n); 
    printInts_v(n, ap); 
    va_end(va); 
} 

Nhưng tôi không nghĩ rằng có một cách để điền trước một số va_list để sử dụng sau này.

Nếu bạn làm việc trên một kiến ​​trúc và tính di động không phải là một vấn đề, bạn có thể tự mình làm một cái gì đó. Làm thế nào chính xác để làm điều đó là nền tảng cụ thể.

+1

Đó là hợp lệ C. Nó đã được hợp lệ C trong 13 năm qua. Nó đã là một phần mở rộng phổ biến cho C lâu hơn. –

+0

Tôi sử dụng nó trong C99. –

+0

Ok, thx & sorry :-) – glglgl

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