2010-09-05 54 views
6

「設置」如果我分配C數組是這樣的:如何檢查是否在C

int array[ 5 ]; 

然後,只設定一個目標:

array[ 0 ] = 7; 

如何檢查是否所有其他密鑰(array[1]array[2],...)正在存儲一個值? (在這種情況下,當然不是)

是否有像PHP的isset()這樣的函數?

if (isset(array[ 1 ])) ... 
+0

AFAIK您只能對證0 – Robus 2010-09-05 19:30:09

+1

@Robus事實上沒有。 C數組不應被初始化爲0. – log0 2010-09-05 20:38:55

回答

6

在C中沒有這樣的東西。靜態數組的內容總是「設置」。但是,您可以填寫一些特殊的值來假裝它是未初始化的,例如

// make sure this value isn't really used. 
#define UNINITIALIZED 0xcdcdcdcd 

int array[5] = {UNINITIALIZED, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED}; 

array[0] = 7; 

if (array[1] != UNINITIALIZED) { 
    ... 
+0

我想這是C – rano 2010-09-05 19:33:14

+0

中唯一可能的選擇謝謝,不知道爲什麼這個我以前沒有發生過! – pop850 2010-09-05 19:42:29

6

不能

有值都是不確定的(因此是隨機的)。

您可以明確地將所有值都清零,以便您至少有一個好的起點。但是使用幻數來檢測一個對象是否被初始化被認爲是不好的做法(但初始化變量被認爲是一種好的做法)。

int array[ 5 ] = {}; 

但是,如果你想明確地檢查他們是否已顯式設置(不使用魔法數字)自創建你需要存儲在另一個結構信息。

int array[ 5 ] = {}; // Init all to 0 
int isSet[ 5 ] = {}; // Init all to 0 (false) 

int getVal(int index)   {return array[index];} 
int isSet(int index)   {return isSet[index];} 
void setVal(int index,int val) {array[index] = val; isSet[index] = 1; } 
+0

,這取決於。 Ç可能初始化值(我認爲它會爲靜態和全局變量) – knittl 2010-09-05 19:32:32

+1

@knittl:從問題的上下文中,強制執行可講,所以我有失謹慎的一面。顯式初始化使用初始化列表並沒有什麼壞處。 – 2010-09-05 19:36:01

+0

C中沒有'std :: map' @ – kennytm 2010-09-05 19:41:28

2

在C中,所有元素在分配時都會有值(垃圾)。所以你不能真正擁有你所要求的功能。

但是,默認情況下,可以使用memset()填充一些標準值(如0或INT_MIN),然後編寫isset()代碼。

+1

'memset'不能填充'INT_MIN'。它只填充字節。 – 2010-09-05 19:42:27

+0

垃圾只有自動變量和堆分配纔是真實的。如果沒有特別說明,全局和靜態數組將被初始化爲0。 – dmckee 2010-09-05 20:02:46

+0

@R ..雖然這是真的,但在大多數現代平臺上,'INT_MIN'是'〜0',並且會用'-1'填充int []'的所有元素。 – strager 2010-09-06 04:35:26

1

一個解決方案也許是使用單獨的標誌陣列。當您分配其中一個元素時,請在布爾數組中設置該標誌。

你也可以使用指針。您可以使用空指針來表示尚未分配的數據。我做了下面的例子:

int * p_array[3] = {NULL,NULL,NULL}; 
     p_array[0] = malloc(sizeof(int)); 
     *p_array[0] = (int)0; 
     p_array[2] = malloc(sizeof(int)); 
     *p_array[2] = (int)4; 
     for (int x = 0; x < 3; x++) { 
      if (p_array[x] != NULL) { 
       printf("Element at %i is assigned and the value is %i\n",x,*p_array[x]); 
      }else{ 
       printf("Element at %i is not assigned.\n",x); 
      } 
     } 

你可以把它分配內存,並把數據和通過爲NULL測試你的作品像PHP的isset功能其他功能的功能。

我希望能幫到你。

編輯:確保內存一旦完成就釋放。另一個函數可以用來釋放某些元素或整個數組。

我以前用NULL指針來表示數據尚未創建或需要重新創建。

2

我不知道PHP,但兩件事情之一是要在這裏

  • PHP的陣列實際上是一個哈希地圖(AWK這是否)
  • 的PHP數組被填滿可空類型

在任何一種情況下,對於數組的值都存在「未設置」的有意義的概念。另一方面,內置類型的c數組在每個單元中始終具有的一些值。如果數組未初始化並且是自動的或者已經分配到堆上,那麼這些值可能是隨機的,但它們是存在的。

爲了讓PHP行爲:

  • 實現(或找到一個圖書館WIT)和陣列上使用HashMap代替。
  • 使其成爲包含isNull字段的結構數組。
  • 將數組初始化爲所有單元格中的某個最終值。
+0

+1表示PHP和C之間的區別 – alex 2010-09-06 04:20:20

1

我喜歡的方法是創建2個數組,一個位數組標記數組的哪些索引被設置,另一個包含實際值。即使在您不需要知道數組中的項是否「設置」的情況下,它也可能是一種有用的優化。歸零的1位每單元位陣列比初始化一個8字節每元件陣列的size_t快得多,尤其是如果該數組將保持稀疏(主要是未填充的),用於其整個生命週期。在這裏我用這一招

一個實際的例子是在一個字符串搜索功能,使用博耶 - 摩爾風格的壞字符跳躍表。該表格需要輸入size_t類型的256個條目,但只需填寫與實際出現在針串中的字符相對應的條目。在非常短的搜索情況下,1kb(或64kb的2kb)memset將主導cpu使用,導致其他實現拋出啓發式方法來決定是否使用該表。但是,我讓跳轉表進入未初始化狀態,並使用一個256位的位數組(只有32個字節提供給memset)來標記哪些條目正在使用。