2015-06-07 3 views
4

Я играл вокруг с литьем типа в C. В частности, я (после K & R) пытаюсь реализовать программу, которая будет принимать «общие» тип ввода (в частности, K & R реализует qsort, который сортирует массив указателей на общие данные). При этом, я столкнулся следующий вопрос:типа отбрасывать аргументы функции

#include <stdio.h> 

int comp(int *a, int *b); //*a == *b 

main() 
{ 
    int a = 2; 
    int b = 3; 
    int *pa = &a; 
    int *pb = &b; 

    int (*pfunc)(void *, void *) = (int (*)(void *, void *)) comp; 
    int fin = (*pfunc)((void *)pa, (void *)pb); 

    printf("%d \n", fin); 
} 

Это соответствует очень хорошо, и делает то, что вы могли бы ожидать, что это сделать. Проблема в том, что это:

#include <stdio.h> 

main() 
{ 
    int a = 2; 
    int b = 3; 
    int *pa = &a; 
    int *pb = &b; 

    void *pVoid_a = (void *) pa; 
    void *pVoid_b = (void *) pb; 

    int fin_Void = (*pVoid_a == *pVoid_b); 
} 

не работает.

Почему это проблема: Как я понимаю, в типе отбрасываемой

int (*pfunc)(void *, void *) = (int (*)(void *, void *)) comp; 

копию указателя «Комп» сделано, с тем исключением, что функция эта копия указывает принимает аргументы " void * ", а не" int * "и присваивается переменной" pfunc ". В противном случае pfunc и comp ведут себя одинаково. (Я думаю, что я, должно быть, ошибаюсь, но я не уверен, почему)

Когда в первой программе (void *) pa и (void *) pb передаются pfunc, я ожидаю две копии pa и pb, за исключением того, что они теперь имеют тип (void *) и назначаются другим именам. Эти копии посылаются через PCOMP, возвращенное значение печатается и т.д.

я попытался воссоздать этот процесс во второй программе, за исключением того, что не работает! По какой-то причине, в первой программе после pVoid_a и pVoid передаются в pfunc, они в конечном итоге ведут себя как «междунар *» 's, в теле функции, даже если она не кажется, что есть какая-либо причина для них , Почему pVoid_a и pVoid_b восстанавливают свое поведение «int» в первой программе, но не во втором?

+0

Используйте 'int main()'. – Levi

+4

«Копия указателя' comp' выполнена «не означает, что« копируется функция, на которую указывает точка ». Он по-прежнему вызывает исходную функцию, которая по-прежнему рассматривает ее аргументы как 'int *'. – DCoder

+1

Хотя это не причина вашей проблемы, и хотя она работает, это неопределенное поведение, чтобы использовать функцию, которая принимает аргументы int * для аргументов void *. –

ответ

2

поведение вы наблюдаете в первой программе происходит потому, что любая переменная типа void* неявно преобразуется в любой другой тип указателя. Во второй программе, вам нужно явно указать, какой тип указателя вы хотите конвертировать pVoid_a и pVoid_b, в противном случае вы разыменование void*, который не имеет никакого смысла. A fix:

int fin_Void = (*(int*)pVoid_a == *(int*)pVoid_b); 
Смежные вопросы