Нечетная проблема с нулевым указателем

Я делаю код практики с использованием языка Си.

Как показано ниже коды,

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _CRT_SECURE_NO_WARNINGS

int ACDSort(const void *p1, const void *p2);
int Compare(const void *pKey, const void *pValue);
int main(void)
{
    char * strAry[4] = {"Hardware","Cookie","Boy","Power"};
    char * destStr = "Cookie";

    //qsort((void*)strAry, sizeof(strAry) / sizeof(char*), sizeof(char*), ACDSort);

    char **ptrAdr = (char**)bsearch((void*)destStr, strAry, sizeof(strAry) / sizeof(char*), sizeof(char*), Compare);

    printf("%s\n", *ptrAdr);
}

int Compare(const void *pKey, const void *pValue) {
    char *key = ((char*)pKey);
    char *value = *((char**)pValue);
    return strcmp(key, value);
}

int ACDSort(const void *p1, const void *p2) {

    char * n1 = *((char**)p1);
    char * n2 = *((char**)p2);
    int ret;

    if (strlen(n1) > strlen(n2))
        ret = 1;
    else if (strlen(n1) < strlen(n2))
        ret = -1;
    else
        ret = 0;
    return ret;
}

я звонил bsearch найти строку cookie, Проблема в том, что ошибка произошла, когда я стер // для того, чтобы отсортировать массив на основе длины строки. Я не знаю, почему ошибка была выполнена, потому что я думаю, что qsort не может быть в состоянии существенно повлиять на мои коды.

Не могли бы вы сказать мне причину, по которой произошла ошибка, возвращая нулевой указатель при удалении //?

Ps. я использовал qsort а также bsearch познакомиться с указателями переменных.

2 ответа

Решение

bsearch использует бинарный поиск, вот почему. Бинарный поиск требует сортировки данных. Сортируйте массив строк в алфавитном порядке, и он будет работать.

Как примечание стороны, вам нужно избавиться от всех этих лишних приведений, все, что они делают, это скрывают потенциальные ошибки.

Рабочая программа после исправлений и очистки:

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

int compare (const void* p1, const void* p2);

int main (void)
{
    const char* strAry[4] = {"Boy", "Cookie", "Hardware", "Power"};
    const char* key = "Cookie";

    char** ptrAdr = bsearch(key, 
                            strAry, 
                            sizeof(strAry)/sizeof(*strAry), 
                            sizeof(*strAry), 
                            compare);

    printf("%s\n", *ptrAdr);
}

int compare (const void* p1, const void* p2) 
{
  const char* s1 = p1;
  const char* s2 = *(const char* const*)p2;

  return strcmp(s1, s2);
}

р2 закончится const пустой указатель на const char*Вот почему мы получаем этот странный вид актеров, когда стремимся к константности.

Тип destStr может быть изменен, чтобы быть таким же, как тип strAryНапример:

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

int Compare(const void *pKey, const void *pValue)
{
    char *key = *((char**)pKey);
    char *value = *((char**)pValue);
    return strcmp(key, value);
}

int main(void)
{
    char * strAry[4] = { "Hardware", "Cookie", "Boy", "Power" };
    char * destStr[1] = { "Cookie" }; // Type changing

    qsort(strAry, sizeof(strAry) / sizeof(char*), sizeof(char*), Compare);

    char **ptrAdr = (char**)bsearch((void*)destStr, strAry, sizeof(strAry) / sizeof(char*), sizeof(char*), Compare);

    printf("%s\n", *ptrAdr);
}

Кроме того, если вы используете язык C (и компилятор), рассмотрите возможность использования strcmp непосредственно как функция обратного вызова, которая сравнивает два элемента.

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

/*int Compare(const void *pKey, const void *pValue)
{
    char *key = *((char**)pKey);
    char *value = *((char**)pValue);
    return strcmp(key, value);
}*/

int main(void)
{
    char * strAry[4] = { "Hardware", "Cookie", "Boy", "Power" };
    char * destStr[1] = { "Cookie" }; // Type changing

    //qsort(strAry, sizeof(strAry) / sizeof(char*), sizeof(char*), Compare);
    qsort(strAry, sizeof(strAry) / sizeof(char*), sizeof(char*), strcmp);

    //char **ptrAdr = (char**)bsearch((void*)destStr, strAry, sizeof(strAry) / sizeof(char*), sizeof(char*), Compare);
    char **ptrAdr = (char**)bsearch(destStr, strAry, sizeof(strAry) / sizeof(char*), sizeof(char*), strcmp);

    printf("%s\n", *ptrAdr);
}

Замечания:

Это решение имеет один недостаток, который выглядит как...

предупреждение: передача аргумента 5 'bsearch' из несовместимого типа указателя [по умолчанию включено]

Но это работает (я пробовал с GCC версии 4.8.2 и MS Visual Studio 12.0)

Другие вопросы по тегам