1. 程式人生 > >int與long 兩種資料型別有什麼區別?|__int64固定大小為8位元組,不受執行環境(的CPU和作業系統位數)影響

int與long 兩種資料型別有什麼區別?|__int64固定大小為8位元組,不受執行環境(的CPU和作業系統位數)影響

筆記原創: 蘭特
聯絡郵件: [email protected]
系統平臺:linux平臺,gcc


有這樣的一個程式,是關於使用隨機函式rand()的:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>


int main()
{
        time_t tm;
        long random_num;

        tm = time(NULL);
        srand(tm);

        while (1) {
                random_num = rand()*0x10000 + rand();
                if (random_num < 0) {
                        printf("%0Lx\n", random_num);
                        break;
                }
        }
}
這個函式輸出一個隨機數random_num,執行程式會發現它的輸出值是負值;查詢程式
很快發現,原來是random_num是一個long型別的變數,rand()*0x10000+rand()的值有
可能大於一個long型別資料的最大尺寸。
讓我們分析一下rand()*0x10000+rand()的最大可能值:rand()的最大可能取值為:
RAND_MAX (參考man說明),而 RAND_MAX的值在/usr/include/stdlib.h中定義:
#define   RAND_MAX  2147483647,所以我們計算一下rand()*0x10000+rand()最大可能值
為:2147483647*66636+2147483647=143101867785139=0x82267FFEFBB3,這也就意味著
random_num需要至少6個位元組的資料型別,那麼我們只有選擇long long型別了。

因此,上面的程式碼修改如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>


int main()
{
        time_t tm;
        long long random_num;

        tm = time(NULL);
        srand(tm);

        while (1) {
                random_num = rand()*0x10000 + rand();
                if (random_num < 0) {
                        printf("%0Lx\n", random_num);
                        break;
                }
        }
}

但是,我們發現random_num輸出的依然是負值。經過分析發現,random_num = rand()*0x10000+rand()這條賦值語句中,右值的運算是按照int型別運算的,我們可以檢視rand()函式的原型:
int rand(void); 所以當右值的運算超過int型別的最大值,則運算不正確,發生了溢位,所以賦給左值的值肯定是錯誤的,random_num得出的值為負值就不足奇怪了。

因此上面的程式碼修改如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>


int main()
{
        time_t tm;
        long long random_num;

        tm = time(NULL);
        srand(tm);

        while (1) {
                random_num = (long long)rand()*0x10000 + (long long)rand();
                if (random_num < 0) {
                        printf("%0Lx\n", random_num);
                        break;
                }
        }
}

這樣,程式碼就正確了:當然了,正確的程式碼輸出是個死迴圈,你只能按下ctrl+c終止程式執行。

總結:
這個問題可以看出,long long 型別並不屬於int,char,short等內建資料型別一類(因為int,char,short之間
不存在這個問題,它們隱含了資料型別優先順序自動轉換);在編寫程式碼的同時,我們最好能夠
顯示的進行資料型別的轉換,不依賴於隱含的規則,這樣就會少一些BUG。