C語言變量類型隱式轉換小陷阱

int型變量可以直接和unsigned int 比較大小嗎?不可以。

 


問題描敘:

這個問題是我在寫kmp算法時遇到的。

int Index_KMP(char *S, char *T, int pos)
{
        int next[strlen(T)];
        get_next(T,next);
 
        int len = strlen(S);
        int i = pos, j = 0;
 
        while((i < len) && (j < strlen(T)))
        {
                if ( j == -1 || S[i] == T[j])
                {
                        ++i;
                        ++j;
                }
                else
                {
                        j = next[j];
                }
        }
        
        if ( j == strlen(T))
                return i - j;
        else 
                return -1;
}

老不能得到正確的結果,我用gdb斷點跟蹤了一下,發現while循環過早的退出了。

gdb跟蹤的結果:

(gdb) n
32        while((i < len) && (j < strlen(T)))
(gdb) n
34            if ( j == -1 || S == T[j])
(gdb) n
41                j = next[j];
(gdb) n
32        while((i < len) && (j < strlen(T)))
(gdb) p i 
$1 = 4
(gdb) p j
$2 = -1
(gdb) p len
$3 = 24
(gdb) p strlen(T)
$4 = 3
(gdb) p ((i < len) && (j < strlen(T)))  //這裏((i < len) && (j < strlen(T)))爲真,可是下一步居然跳出了循環
$5 = 1
(gdb) n
45        if ( j == strlen(T))  //爲什麼跳出了while循環呢
(gdb) 

 


原因分析:

strlen函數的返回值類型爲size_t

while條件語句中的j==-1時,j < strlen(T)返回值是爲0的。因爲-1轉換爲無符號整數是最大的無符號整數,所以j < strlen(T)一定爲假。

但是我用gdb中打印 -1  <  strlen(T)的結果居然爲1。在j==-1p  ((i < len) && (j < strlen(T))) 的結果居然也是1gdb中打印的結果和真實運行情況不一樣。

 

j < strlen(T)改爲j < (int)strlen(T)問題解決。

 


關於size_t

都說size_t是無符號整數,而且32位環境中爲unsigned int64位環境中爲unsigned long可是它在哪個文件中定義的呢?小弟在ubuntu13.04上用whereislocate找了好久翻遍了各種types.hstdio.h最終找到一個/usr/lib/syslinux/com32/include/bitsize/stddef.h裏面定義了size_t。這個文件中的內容如下:

/*
* bits32/stddef.h
*/

#ifndef _BITSIZE_STDDEF_H
#define _BITSIZE_STDDEF_H

#define _SIZE_T
typedef unsigned int size_t;

#define _PTRDIFF_T
typedef signed long ptrdiff_t;

#endif /* _BITSIZE_STDDEF_H */
 

哪位能找到其他地方的size_t32位和64位明確的定義,麻煩把詳細的平臺和路徑給我說一下,或者一個源代碼的鏈接。



C語言變量隱式轉換規則

如果把不同類型的數據放在一起運算,隱式轉換規則爲:窄的轉爲寬的,範圍小的提升爲範圍大的。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章