Rzutowanie z voida

0

Cześć mam funkcje ktora ma posortować wskazaną tablicę
Funkcja przyjmuje jako parametry
wkaznik na tablice(void), rozmiar tablicy(int), rozmiar elementu tablicy(int), wskaznik na funkcje ktora porówna dwa elementy tablicy.
Przykład dla int.

 int sort(void *tab,int size,int size_element,int (*wsk)(void,void))
 {
 	if(size_element==sizeof(int))
 	{
 		int tmp;
 		int i,j;
 		for(i=0;i<size;i++)	
	       {
			for(j=0;j<size-1;j++)
 			{
 				if(wsk(*(tab+j),*(tab+j+1))==1)
 				{
					tmp=*(tab+j);
					*(tab+j)=*(tab+j+1);
 					*(tab+j+1)=tmp;
				}
			}
		}
	
 	}
 return 0;
 }

Jednak pojawiają się warningi, z którymi za bardzo nie potrafie sobie poradzić.

2

Nie możesz przekazać void bez wskaźnika

 int sort(void *tab,int size,int size_element,int (*wsk)(void,void)) =>  int sort(void *tab,int size,int size_element,int (*wsk)(void*,void*))
2

void i void* mają się tak do siebie jak krzesło do krzesła elektrycznego, nie możesz ich mylić.

3

To zadanie pod żadnym pozorem nie polega na tym, że masz sobie zrobić drzewko ifów dla różnych typów. Po to masz wielkość typu przekazane w parametrze aby tego użyć. Tak samo *(tab+j) dla void* tab jest bez sensu. Użyj memcpy

0

W jaki sposób użyć memcpy?

0

Jak powinna wygladać ta funkcja .
Przy takiej deklaracji int sort(void *tab,int size,int size_element,int (*wsk)(void* ,void* ));
pojawiają się błędy przy wskaźniku do funkcji. nieodpowiedni typ parametrów .

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

void sort(void *tab, int size, int size_element, int (*cmp)(void*, void*)){
    void* tmp = malloc(size_element);
    int i,j;
    for(i=0;i<size;i++) {
        for(j=0;j<size-1;j++){
            void* x = (char*)tab+(j*size_element); // fixed
            void* y = (char*)tab+((j+1)*size_element); // fixed
            if(cmp(x, y) == 1){
                memcpy(tmp, x, size_element);
                memcpy(x, y, size_element);
                memcpy(y, tmp, size_element);
            }
        }
    }
    free(tmp);
}

int int_cmp(void* x, void* y){
    return *(int*)x < *(int*)y;
}

int char_cmp(void* x, void* y){
    return *(char*)x < *(char*)y;
}

int main(){
    int i;
    int int_arr[] = {1,2,3};
    int element_size = sizeof(int_arr[0]);
    int size = sizeof(int_arr)/element_size;
    sort(int_arr, size, element_size, int_cmp);
    for(i=0;i<size;i++){
        printf("%d ",int_arr[i]);
    }
    printf("\n");
    
    char char_arr[] = {'a','b','c'};
    element_size = sizeof(char_arr[0]);
    size = sizeof(char_arr)/element_size;
    sort(char_arr, size, element_size, char_cmp);
    for(i=0;i<size;i++){
        printf("%c ",char_arr[i]);
    }
    printf("\n");
    return 0;
}

Myśle że jakoś tak.

0

Odpaliłem z ciekawości twój kod. Pojawił się problem

error: pointer of type ‘void *’ used in arithmetic

przy

void* x = tab+(j*size_element);
void* y = tab+((j+1)*size_element);

1

Godbolt mówi że w takiej wersji pyknie już wszędzie, zarówno na clangu jak i na msvc (za to gcc łykał nawet arytmetykę z void*)

void* x = (char*)tab+(j*size_element);
void* y = (char*)tab+((j+1)*size_element);
0

Tylko z założenia funkcja ma działać dla różnych zmiennych/struktur . GCC na linuxie.

2

No a nie działa? o_O Widzisz ten kod wyżej? Przecież masz tam example z int i z char na TYM SAMYM KODZIE. Możesz tam wrzucić dowolny inny typ czy własną strukturę i nadal zadziała. W przeciwieństwie do bzdur które wstawiłeś na początku tego wątku.
To rzutowanie na char jest tylko potrzebne do samej arytmetyki wskaźników i korzysta z faktu ze sizeof(char) == 1. Chodzi tylko o przesuwanie się w pamięci po 1 bajcie i nie ma nic wspólnego z typami na których pracuje funkcja sort.

1 użytkowników online, w tym zalogowanych: 0, gości: 1