2012-07-14 7 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"보다 더 좋은 이름을 준 때문에?. 죄송합니다. 저항 할 수 없습니다. –

+10

PF로 printf를 알리면 나를 조금만 더 죽게됩니다. – Corbin

+0

단순한'return * ip1 - * ip2'는'intcmp'의 전신으로 충분하지 않습니까? 왜 그는 두 개의 포인터가 더 필요했을까요? o__O –

답변

4

코드에서 몇 가지 기이있다 (PF와 기능이 기본으로 선언 된 방법은 아직 전역으로 정의) 그러나, 문제는 로직이 경우 두 곳에서 반전이다.

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

그리고 :

return *p1 - *p2 == 0; 

두 요소가 동일한 경우 정신적으로 그 통해 실행합니다. == 표현식은 숫자가 실제로 다른 숫자와 같을 때 1을 반환합니다. 1! = 0 따라서 발견 된 것으로 간주되지 않습니다.

부정 또는 부정한 방법을 통해 return *p1 - *p2;을 직접 입력하십시오.

+0

"함수가 전역에서 정의되었지만 전역 적으로 선언되는 방식"- 이전에는 전역 함수를 호출 한 함수에 로컬로 선언하는 것이 일반적이었습니다. Bell Labs 유닉스 코드는 이런 종류의 것이었다. "거기에서 부정을 통해"- "표준"cmp 함수는 < 0, 0, or >을 반환하여 정렬 된 비교를 허용하므로 '* ip1 - * ip2'가 올바른 해결책입니다. –

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. 
}