2012-06-28 21 views
14

Với printf(), tôi có thể sử dụng %hhu cho unsigned char, %hi cho một short int, %zu cho một size_t, %tx cho một ptrdiff_t vvspecifier chuyển đổi printf cho _Bool?

chuyển đổi gì format specifier để tôi sử dụng cho một _Bool? Liệu có tồn tại trong tiêu chuẩn?

Hoặc tôi phải bỏ nó như thế này:

_Bool foo = 1; 
printf("foo: %i\n", (int)foo); 
+1

Tôi không nghĩ rằng bạn cần một dàn diễn viên trước của 'foo':' _Bool' sẽ chuyển sang 'int' theo mặc định. – dasblinkenlight

+0

Bạn không cần. '_Bool' được gõ vào' int' trong C99. – Jack

+0

Plus, ngay cả khi '_Bool' không phải là typedef cho' int', 'printf()' không an toàn kiểu; nếu bạn đẩy một giá trị có cùng kích thước với 'int' vào chồng, và nói' printf() 'để in nó thành' int', bởi golly 'printf()' sẽ in nó thành 'int', không câu hỏi. – steveha

Trả lời

10

Không có công cụ sửa đổi độ dài chuyển đổi cụ thể cho loại _Bool.

_Boolunsigned loại số nguyên đủ lớn để lưu trữ các giá trị 01. Bạn có thể in một _Bool theo cách này:

_Bool b = 1; 
printf("%d\n", b); 

Bởi vì các quy tắc chương trình khuyến mãi số nguyên, _Bool được đảm bảo để thúc đẩy để int.

+0

% u hoạt động là tốt, đặc biệt là đối với những loại người cố định như bản thân mình, những người luôn muốn sử dụng các bộ định danh chưa ký với các loại chưa ký. Ngoài ra, tôi nghĩ rằng '_Bool b = true;' là cách sử dụng tốt hơn. –

+1

Đây là câu trả lời đúng nhất - '_Bool' sẽ được chuyển thành' int', không phải là 'int unsigned'. Đối với hậu thế, nó sẽ được tốt đẹp nếu câu trả lời có chứa các tham chiếu đến tiêu chuẩn C99 xác định hành vi này. –

+1

6.5.2.2p7 cho các quảng cáo đối số mặc định cho các đối số tương ứng với dấu ba chấm, 6.5.2.2p6 cho định nghĩa quảng cáo đối số mặc định, 6.3.1.1 cho các quảng cáo số nguyên –

6

Cho đến C99, bool là không ngoài tiêu chuẩn C, và do đó không tồn tại như một modifier printf. C99, được định nghĩa _Bool (mà bạn đang sử dụng) là một số nguyên, do đó bạn nên sử dụng nó làm số nguyên để hiển thị (ít nhất là từ phối cảnh máy). Ngoài ra, bạn có thể làm điều gì đó như:

printf("%d",foo?1:0); 
+4

hoặc nếu bạn muốn in chuỗi dưới dạng đầu ra bạn có thể thực hiện: 'printf (" foo:% s \ n ", foo?" True ":" false ");' – Jite

+0

Chắc chắn, thay thế đó cũng hoạt động và có lẽ dễ dàng hơn đánh máy. Tuy nhiên, tôi ít quan tâm đến nhiều cách để in '_Bool' hơn xác nhận rằng không có công cụ sửa đổi độ dài hoặc biến đổi cho' _Bool'. (Tiền thưởng sẽ là một liên kết để thảo luận về lý do tại sao nó không tồn tại: Giám sát? Được coi là không cần thiết?) –

+0

Câu trả lời trong các nhận xét ở trên là chính xác: không cần bỏ nó, vì nó được tự động quảng cáo ... và vì vậy không cần cho?: một trong hai. Và thực tế là không có một sửa đổi printf trước khi C99 là không liên quan; họ có thể đã thêm một khi họ thêm _Bool ... nhưng nếu họ có, nó sẽ in "true" hoặc "false". –

2

Như bạn đã nói trong một chú thích để @Jack, "6.3.1.1p1 nói rằng cấp bậc chuyển _Bool là ít hơn so với thứ hạng của tất cả các loại nguyên tiêu chuẩn khác".

Trong một cuộc gọi đến printf, một char hoặc short sẽ được thúc đẩy và thông qua trên stack như một int (hoặc một unsigned int), vì vậy tôi sẽ nghĩ rằng việc sử dụng %d như một specifier định dạng sẽ là tốt. Điều đó cũng có nghĩa là bạn không cần dàn diễn viên rõ ràng để int, bởi vì điều đó sẽ tự động diễn ra.

Vấn đề duy nhất có thể xảy ra là cách trình biên dịch đại diện cho một _Bool, một cái gì đó mà nó có thể thực hiện được xác định và có thể thay đổi từ trình biên dịch này sang trình biên dịch khác. Tôi thấy hai khả năng triển khai - 0 và 1 hoặc 0 và -1.

Để tối ưu hóa tính di động, hãy làm theo câu trả lời của @ user325181 và sử dụng số ba để chọn giữa hai tùy chọn. Hoặc là số nguyên (trình biên dịch có thể tối ưu hóa) hoặc chuỗi.

Edit: Theo báo cáo trong câu trả lời khác, một _Bool được định nghĩa là một kiểu không thể thiếu unsigned có thể lưu trữ hoặc là 0 hoặc 1. Do đó, và thực tế là nó sẽ được đề bạt lên một unsigned int khi truyền cho printf(), tôi có thể nói rằng %u %d là trình chỉ định thích hợp nhất.

+2

Không thể lưu trữ vào '_Bool' bất kỳ giá trị nào khác ngoài' 0' hoặc '1' (6.3.1.2). Vì vậy, việc chuyển đổi trở lại 'int' sẽ (chặn hành vi không xác định) luôn mang lại' 0' hoặc '1'. – ecatmur

+0

@ecatmur: Có, và các macro 'false' và' true' trong '' mở rộng thành '0' và' 1', tương ứng. –

+0

C nói '_Bool' là một số nguyên không dấu nên không thể' -1'. – ouah

1

Không có. Chỉ cần xử lý nó như là một int bằng cách sử dụng %d hoặc %i thông số.

_Bool

Trong C99, một từ khóa mới, _Bool, được giới thiệu như kiểu boolean mới. Trong nhiều khía cạnh, nó hoạt động giống như int không dấu, nhưng chuyển đổi từ các kiểu số nguyên khác hoặc con trỏ luôn bị giới hạn ở 0 và 1. Khác với các loại chưa ký khác và như mong đợi đối với loại boolean chuyển đổi là 0 nếu và chỉ khi biểu thức trong câu hỏi đánh giá là 0 và nó là 1 trong tất cả các trường hợp khác. Tiêu đề stdbool.h cung cấp macro bool, true và false được định nghĩa là _Bool, 1 và 0, tương ứng.

Cách đầu tiên để thực hiện nó đến từ trong tâm trí là bằng cách sử dụng một char hoặc (int8_t) một enum và với bit fields. Nhưng thực sự, nó phụ thuộc. Nó có thể là typedef cho một số int (như tôi đã đề cập, nó được sử dụng, nhưng không được đề xuất, tùy thuộc vào lỗi) hoặc char hoặc unsigned int hoặc enum và #define thường được sử dụng.

Đối với exampe, Apple's implementation sử dụng int, như bạn có thể thấy:

#ifndef _STDBOOL_H_ 
#define _STDBOOL_H_ 

#define __bool_true_false_are_defined 1 

#ifndef __cplusplus 

#define false 0 
#define true 1 

#define bool _Bool 
#if __STDC_VERSION__ < 199901L && __GNUC__ < 3 
typedef int _Bool; 
#endif 

#endif /* !__cplusplus */ 

#endif /* !_STDBOOL_H_ */ 

Khác triển khai:

typedef int8_t _Bool;

typedef enum { false = 0, true = 1 } bool;

typedef unsigned char Boolean; typedef _Bool Boolean;

+1

Và không có triển khai nào trong số đó là C99. '_Bool' là từ khóa trong C99 và bạn sẽ không tìm thấy từ khóa được xác định trong bất kỳ tiêu đề nào. Trong ví dụ của Apple ở trên, nó định nghĩa nó cho các phiên bản của C trước C99. Trong các ví dụ khác, bạn có kiểu 'bool' và kiểu' Boolean' được định nghĩa là 'unsigned char' hoặc' _Bool'. – tomlogic

0

Tôi sử dụng %b cho một số tham chiếu Java printf(). Tôi đã thử nó gần đây và ngạc nhiên của tôi nó đã làm việc.

Đây là dòng mã:

System.out.printf("firstRobot == secondRobot: %b",firstRobot == secondRobot); 

Đây là kết quả:

firstRobot == secondRobot: false