2012-05-19 19 views
10

Tôi có một vấn đề trong khi sử dụng chức năng printf để in giá trị của loại unsigned long long intIn ấn unsigned long Loại dài int Value Trả kết quả Strange

Tôi không có ý tưởng gì sai. Tôi đang sử dụng Dev-Cpp 4.9.9.2 và Visual Studio 2010 Professional (tôi biết rằng nó không phải là trình biên dịch C, nhưng dù sao, muốn thử) trên Windows 7 Professional 64-bit. Để hiển thị, tôi đã sử dụng %llu modifier (theo How do you printf an unsigned long long int(the format specifier for unsigned long long int)?) nhưng tôi cũng đã cố gắng I64d không có hiệu lực thi hành ...


Trước hết, tôi chỉ muốn in giá trị tối thiểu và tối đa unsigned long long int (sử dụng ULONG_MAX từ limits.h)

printf("unsigned long long int: \n%llu to %llu \n\n", 0, ULONG_MAX); 

Returns:

unsigned long long int: 18446744069414584320-1580552164021 (Dev-Cpp)

unsigned long long int: 18446744069414584320-0 (Visual Studio)


Sau đó, tôi đã cố gắng để sử dụng printf để in hai số không

printf("unsigned long long int: \n%llu to %llu \n\n", 0, 0); 

Trả lại:

unsigned long long int: 0-1580552164021 (Dev-Cpp)

unsigned long long int: 0-0 (Visual Studio)


Cũng cố gắng hai ULONG_MAX giá trị

printf("unsigned long long int: \n%llu to %llu \n\n", ULONG_MAX, ULONG_MAX); 

Trả lại:

unsigned long long int: 18446744073709551615-1580552164021 (Dev-Cpp)

unsigned long long int: 18446744073709551615-0 (Visual Studio)


Tại sao nó cư xử như thế? Bạn có thể giải thích cho tôi không?

Trả lời

11

này là sai:

printf("unsigned long long int: \n%llu to %llu \n\n", 0, ULONG_MAX); 

Bạn sử dụng một định dạng specifier unsigned long long, nhưng bạn vượt qua một int và một giá trị unsigned long. Quy tắc quảng cáo có nghĩa là bạn có thể cẩu thả đối với mọi thứ int cỡ nhỏ hoặc nhỏ hơn, không không áp dụng cho long long.

Sử dụng phôi:

printf("unsigned long long int: \n%llu to %llu \n\n", 
     0ULL, (unsigned long long) ULONG_MAX); 

Giải thích: Khi đi qua lập luận để printf, bất kỳ loại mà có thể phù hợp trong một int được thăng int, và sau đó bất kỳ loại mà có thể phù hợp trong một unsigned int được thăng chức unsigned int. Bạn cũng có thể chuyển một loại chưa ký cho một chỉ định định dạng đã ký hoặc ngược lại miễn là giá trị được truyền có thể được biểu diễn bằng loại được chỉ định bởi trình định dạng định dạng.

Vì vậy, bạn phải cẩn thận với longlong long, nhưng bạn có thể cẩu thả với int, short, và char.

Hầu hết các trình biên dịch đều có cài đặt để cảnh báo bạn về loại lỗi này, vì nó có thể được phát hiện tại thời gian biên dịch khá dễ dàng; GCC và Clang có -Wformat mà kết quả trong những lời cảnh báo sau đây:

 
test.c:5: warning: format ‘%llu’ expects type ‘long long unsigned int’, but argument 2 has type ‘int’ 
test.c:5: warning: format ‘%llu’ expects type ‘long long unsigned int’, but argument 3 has type ‘long unsigned int’ 
+0

0 là int, không dài. –

+1

Điều đó thật cẩu thả. –

10

Bạn không vượt qua unsigned long longs. Bạn đang chuyển một số int (0) và unsigned long (ULONG_MAX). Bạn phải chuyển đến printf() chính xác những gì bạn hứa sẽ chuyển vào chuỗi định dạng.

Hãy thử điều này thay vì:

printf("unsigned long long int: \n%llu to %llu \n\n", 0ULL, (unsigned long long)ULONG_MAX); 
4

ULONG_MAX đề cập đến unsigned long và không unsigned long long. Sau đó, sử dụng ULLONG_MAX (lưu ý thêm L).

Bạn cần phải thay đổi printf() cuộc gọi như vậy:

printf("unsigned long long int: \n%llu to %llu \n\n", 0ULL, ULLONG_MAX); 
printf("unsigned long long int: \n%llu to %llu \n\n", ULLONG_MAX, ULLONG_MAX); 

này đảm bảo rằng các đối số printf() phù hợp với specifiers định dạng.

0

dài int dài là một loại từ tiêu chuẩn C99, MSVC không hỗ trợ này. Lấy một trình biên dịch có hỗ trợ C99 (như MinGW cho Windows) và nó sẽ hoạt động.

+1

MSVC hỗ trợ 'long long' mặc dù không hỗ trợ đầy đủ C99. –