Nano Hash - криптовалюты, майнинг, программирование

Как функции C, такие как qsort, работают с разными типами данных?

В stdlib.h есть объявление функции qsort() с прототипом:

void qsort( void *ptr, size_t count, size_t size,
        int (*comp)(const void *, const void *) );

Очевидно, что это универсальное программирование. Интересно, как это реализовать, как получить элемент из типа void*?

21.11.2012

  • Примечание к большинству ответов: этот вопрос не о том, как использовать qsort(), а о том, как, например. qsort внутренне может определить расположение элементов в пустоте * 21.11.2012

Ответы:


1

void * указатели приводятся в соответствии с size_t size (3-й аргумент в qsort)

Сначала мы приводим void* к char*, а затем выполняем арифметику указателя в соответствии с size (поскольку char занимает 1 байт, поэтому добавление размера даст правильную арифметику указателя)

РЕДАКТИРОВАТЬ: (для встроенных типов данных)

char *ptr = (char*)vp; //here vp is void *p

*(ptr + (n-1)*size); //will give you nth element 

e.g.

size =1 and want 3rd element it means it will give you 3rd char
size =4 and want 3rd element it means it will give you 3rd int or float
size =2 and want 3rd element it means it will give you 3rd short int
size =8 and want 3rd element it means it will give you 3rd double

ПРИМЕЧАНИЕ. Размер определяется реализацией, поэтому он может варьироваться в зависимости от компилятора.

21.11.2012
  • Да, и что я хочу знать, так это конкретный процесс. Например, как получить 3-й элемент в ptr? 21.11.2012

  • 2
    #include <stdio.h>
    
    void compare_first_to_rest(void *ptr, size_t nelem, 
       size_t size, int (*cmp)(const void*, const void*)) {
        unsigned i;
        for(i = 1; i < nelem; ++i)
            {
            int res = cmp(ptr, (char*)ptr + i * size);
            if(res < 0)
                printf("First element is less than element at %u\n", i);
            else if(res > 0)
                printf("First element is greater than element at %u\n", i);
            else
                printf("First element is equal to element at %u\n", i);
            }
    }
    
    int icmp(const void *x, const void *y) {
       return *(int*)x - *(int*)y;
    }
    
    int main()
    {
       int x[] = { 5, 3, 6, 2, 4, 8, -1, 10 };
       compare_first_to_rest(x, 8, sizeof(int), icmp);
    }
    

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

    21.11.2012

    3

    Последний параметр является указателем на функцию. Как вы неявно упомянули, вы должны где-то реализовать эту функцию. Но когда вы его реализуете, вы знаете, какой король указателей на самом деле является вашим элементом void*.

    В вашей функции comp вы должны привести свои 2 параметра к типу указателя, с которым вы хотите работать, как показано ниже:

    int myCompFn(const void * e1, const void * e2)
    {
        MyType *elem1=(MyType*)e1;
        MyType *elem2=(MyType*)e2;
        ... /* then compare elem1 and elem2 regarding to there definition */
    }
    
    21.11.2012
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..