2012-07-14 59 views
0

我的lsearch函數應該在我的數組中找到值11。它沒有,我不知道錯誤在哪裏。爲什麼這個代碼沒有找到值11?C線性搜索錯誤

#include <stdio.h> 
#include <string.h> 
#define PF printf 
int main() { 
    int intcmp(void *ip1, void * ip2); 
    void * lsearch(void *key, void *base, int n, int elemSize, 
        int(* cmpfun)(void *, void *)); 
    int arr[] = {4, 6, 2, 3, 11, 22, 15}; 
    int n = sizeof(arr)/sizeof(int); 
    int key = 11; 
    int *found = lsearch(&key, &arr, n, sizeof(int), intcmp); 
    PF("found=%p", found); 
    return 1; 
} 
int intcmp(void *ip1, void * ip2) { 
    int *p1 = ip1; 
    int *p2 = ip2; 
    return *p1 - *p2 == 0; 
} 
void * lsearch(void *key, void *base, int n, int elemSize, 
       int(* cmpfun)(void *, void *)) { 
    int i; 
    for(i = 0; i < n; i ++) { 
     void *elemArr = (char *)base + i * elemSize; 
     if(cmpfun(key, elemArr) == 0) 
      return elemArr; 
    } 

    return NULL; 
} 
+1

*爲什麼不是我發現那位11 *因爲你的父母給你比「潤版液11」更好的名字?對不起,無法抗拒。 – 2012-07-14 05:56:49

+10

將PF與別名混爲一談,讓我有點內心死亡。 – Corbin 2012-07-14 05:57:58

+0

作爲'intcmp'的整個主體是不是一個簡單的'return * ip1 - * ip2'?爲什麼他需要兩個指針? o__O – 2012-07-14 07:46:30

回答

4

有一個在你的代碼的一些古怪(PF和功能在主聲明的路要走全局定義),然而,問題是,你的邏輯,如果倒在一兩個地方。

if(cmpfun(key, elemArr) == 0) 
     return elemArr; 

和:

return *p1 - *p2 == 0; 

精神上通過運行,當兩個元件是相等的。當數字實際上等於另一個時,==表達式將返回1。 1!= 0因此它不被認爲是被發現的。

要麼通過否定,要麼直接通過return *p1 - *p2;

+0

「函數在主要但全局定義的方式」 - 曾幾何時,通常在調用它們的函數本地聲明全局函數。貝爾實驗室的UNIX代碼充滿了這樣的事情。 「要麼通過[原文]否定在那裏」 - 「標準」cmp函數返回< 0, 0, or > 0以允許有序比較,所以'* ip1 - * ip2'是正確的解決方案。 – 2012-07-14 12:15:12

1

我已經註釋下面的代碼:

#include <stdio.h> 
#include <string.h> 

// This is bad practice. It makes your code less readable. 
// I won't use it below. 
#define PF printf 

// Declare this first so a prototype is not needed. 
// You violated a C pattern by using `cmp` in the name. 
// Comparison functions in C return <0, 0, >0, not a binary value. 
// To wit, later you used the comparison correctly. I've fixed the 
// inconsistency. 
int intcmp(void *vp1, void *vp2) 
{ // Most C styles have the brace on its own line, unlike Java. Roll with it. 
    int *p1 = vp1, *p2 = vp2; 
    return *p1 - *p2; 
} 

// Search n elements of size elemSize in the array at 
// base in sequence using cmpfun on key, 
// to test for equality (cmpfun == 0). Return a pointer 
// to the found element or NULL if none. 
void *lsearch(void *key, void *base, int n, 
       int elemSize, int(* cmpfun)(void *, void *)) 
{ 
    int i; 

    for (i = 0; i < n; i++) { 
     void *elemArr = (char*)base + i * elemSize; 
     if (cmpfun(key, elemArr) == 0) 
      return elemArr; 
    } 
    return NULL; 
} 

int main() 
{ 
    int arr[] = {4, 6, 2, 3, 11, 22, 15}; 
    int n = sizeof(arr)/sizeof(int); 
    int key = 11; 
    int *found = lsearch(&key, &arr, n, sizeof(int), intcmp); 
    printf("found=%p (%d)", found, *(int*)found); 
    return 0; // By convention zero corresponds to no error. 
}