我必須參考這個頁面stdint.h:stdint.h中的無符號整數類型對可存儲內容沒有限制?
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdint.h.html
我完全驚訝地看到,我可以定義爲uint64_t中類型 變量中存儲負數。我的想法是,我的腦海裏一個無符號的 數據類型總是一個正數,如果我試圖在那裏存儲一個 負數,我會得到一個錯誤。下面讓我大吃一驚:
#define _XOPEN_SOURCE 600
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stddef.h>
#include <errno.h>
int main (int argc, char *argv[]) {
uint64_t a_big_positive_number;
unsigned long another_big_positive_number;
if (argc < 2) {
printf ("usage : %s some_integer\n", argv[0]);
exit(EXIT_FAILURE);
}
a_big_positive_number = 0;
a_big_positive_number = strtol(argv[1], (char **)NULL, 10);
fprintf (stderr, "%i : %s\n", errno, strerror(errno));
another_big_positive_number = a_big_positive_number;
fprintf (stderr, "%i : %s\n", errno, strerror(errno));
return (EXIT_SUCCESS);
}
當我編譯的全C99迂腐的標誌,我得到一個二進制文件做了 以下驚人的事情:
$ ./boffo -12345
0 : Error 0
0 : Error 0
真的嗎?
我跑了一個調試器中,我看到的確是的,uint64_t中是完全 精細與具有負數和近,我可以告訴我可以在那裏stuiff任何 64位我想:
(dbx) run -12345
Running: boffo -12345
(process id 16270)
stopped in main at line 15 in file "boffo.c"
15 if (argc < 2) {
(dbx) step
stopped in main at line 20 in file "boffo.c"
20 a_big_positive_number = 0;
首先,我想看看在內存中(在棧上我猜的)這個變種是:
(dbx) print &a_big_positive_number
&a_big_positive_number = 0xffffffff7ffff620
大......現在得到的argv [1]輸入字符串,並將其轉換爲長整型:
(dbx) step
stopped in main at line 22 in file "boffo.c"
22 a_big_positive_number = strtol(argv[1], (char **)NULL, 10);
(dbx) step
stopped in main at line 23 in file "boffo.c"
23 fprintf (stderr, "%i : %s\n", errno, strerror(errno));
我們現在在那個地址有什麼記憶?
(dbx) x &a_big_positive_number/4 x
0xffffffff7ffff620: 0xffff 0xffff 0xffff 0xcfc7
無符號的64位數據類型內負數。根本沒有錯誤!
(dbx) cont
Reading libc_psr.so.1
0 : Error 0
0 : Error 0
execution completed, exit code is 0
(dbx) quit
所以現在的問題是,什麼是目的或 stdint.h內的無符號整數的值時,它好像我可以用一個64位的位字段或排列的8個無符號的字符 或任何一塊內存足夠大?價值 在哪裏?可移植性?從鄉親
/************** COMMENT AFTER SEEING GREAT ANSWERS BELOW ************/
偉大的答案下面不吝我,我看到stdint.h類型 可以跨平臺移植,他們允許正 整數值的更大範圍。存儲在變量中的數據的解釋是 ,這是我需要處理的事情,不要指望我的編譯器或調試器神祕地 或神奇地知道我們只在這裏使用正數。
其實,我認爲最安全的做法是堅持使用uint32_t的是在 C99標準,然後做在那裏得到一個正確的正值:
a_big_positive_number = (uint32_t) labs(strtol(argv[1], (char **)NULL, 10));
是超級「帶和吊帶「安全我應該在我接受 之前自己檢查argv [1]。誰知道,這可能是負面的,或者它可能是垃圾數據。
將有符號整數類型轉換爲無符號整數類型?但是沒有轉換。我在uint64_t類型對象中仍然有一個負數,調試器輸出證實了這一點。我看不到有任何「轉換」發生。 –
@paullanken「消極」或「正面」和「有符號」和「無符號」(以及一般類型) - 這些只是慣例,由編譯器和程序員在高層使用。問題是你的號碼將包含一些位模式,不管它的類型是什麼。現在您可以將其解釋爲有符號或無符號,並且您將看起來會得到不同的結果 - 但這實際上只是您想如何解釋由變量表示的原始內存內容的問題。 – 2013-08-04 18:49:41
@paullanken如果在調試器中將無符號變量的內容作爲有符號整數進行打印,您將獲得一個有符號值。調試器不知道符號的類型,並使用您指示的類型來解釋內存的內容。 –