簡體   English   中英

我們可以使用數組的空指針

[英]Can we use void pointer of arrays

我只是在研究一個自由函數,在其中我們為學生和書定義了自己的數據類型。我必須編寫一個代碼,通過id和id來查找學生,這是兩個函數。 在這個函數中,我傳遞的指針是不同的,但是邏輯是相同的,所以我明白了為什么我們不能編寫一個函數並傳遞想要的東西。 我的意思是,當我們通過學生名單時,它將返回學生的索引;當我們通過書目列表時,它將返回該書的書籍索引。 我們可以為此使用空指針嗎??? 謝謝大家!!!

int findBookId(Book* booklist,int* bcount,unsigned int* tbid)
{
    int i;
    for (i=0; i<*bcount; i++)
    {
        if (booklist[i].id==*tbid)
        {
            return i;
        }
    }
    return NOT_FOUND;
}

int findStuId(Student* stulist,int* scount,unsigned int* tsid)
{
    int i;
    for (i=0; i<*scount; i++)
    {
        if (stulist[i].id==*tsid)
        {
            return i;
        }
    }
    return NOT_FOUND;
}   

假設您有一個student結構:

struct student {
    int id;
    char name[20];
};

您可以模仿qsort()函數,設計一個參數以接收回調函數,並在需要使用void *接收每個元素的大小和大小。

int find_ele(void *base, size_t num, size_t width,
    int (*equal)(const void *, const void *),
    void *param)
{
    int i;

    for (i = 0; i < num; ++i) {
        if (equal((char *) base + i * width, param)) {
            return i;
        }
    }

    return -1;
}

然后,定義一個“測試器”:

int student_tester(const void *p1, const void *p2)
{
    struct student *sp = (struct student *) p1;
    int id = *(int *) p2;
    return sp->id == id;
}

main()函數中:

int main(void)
{
    struct student student_list[] = {
        0, "A",
        1, "B",
        2, "C"
    };

    int id = 2;
    int index = find_ele(student_list, sizeof student_list,
        sizeof(struct student), student_tester, &id);
    if (index != -1) {
        printf("find_ele(id=2) = student_list[%d]; name = %s. \n",
            index, student_list[index].name);
    } else {
        printf("Not found. \n");
    }

    return 0;
}

這有點復雜。 如果您不在意,可以創建宏來簡化它。

find_ele重命名為_find_ele ,然后創建一個宏:

#define find_ele(base, num, compare, param) _find_ele(base, \
    num / sizeof base[0], \
    sizeof base[0], \
    compare, param)

並創建另一個宏來定義“測試器”:

#define define_tester(name, type, type_to_find, code) \
    int name(const void *_p, const void *param) { \
        type *p = (type *) _p; \
        type_to_find value = *(type_to_find *) param; \
        return (code); \
    }

現在您可以定義一個“測試器”,如下所示:

define_tester(student_tester, struct student, int,
    p->id == value);

完整的代碼:

#include <stdio.h>

int _find_ele(void *base, size_t num, size_t width,
    int (*equal)(const void *, const void *),
    void *param)
{
    int i;

    for (i = 0; i < num; ++i) {
        if (equal((char *) base + i * width, param)) {
            return i;
        }
    }

    return -1;
}

#define find_ele(base, num, compare, param) _find_ele(base, \
    num / sizeof base[0], \
    sizeof base[0], \
    compare, param)

#define define_tester(name, type, type_to_find, code) \
    int name(const void *_p, const void *param) { \
        type *p = (type *) _p; \
        type_to_find value = *(type_to_find *) param; \
        return (code); \
    }

struct student {
    int id;
    char name[20];
};

define_tester(student_tester, struct student, int,
    p->id == value);

int main(void)
{
    struct student student_list[] = {
        0, "A",
        1, "B",
        2, "C"
    };

    int id = 2;
    int index = find_ele(student_list, sizeof student_list, student_tester, &id);
    if (index != -1) {
        printf("find_ele(id=2) = student_list[%d]; name = %s. \n",
            index, student_list[index].name);
    } else {
        printf("Not found. \n");
    }

    return 0;
}

是的,如果您試圖存儲數組的地址,則可以使用void指針。您的數組可能包含整數類型或其他存儲的數據類型,這並不重要,但是在取消引用void指針時進行正確的類型轉換很重要。

是的,您可以使用void* ,但是在取消引用時,您應該知道指針的確切type
因此,當您可以使用函數時,請添加另一個參數:

type = 0 for Books
     = 1 for students 

然后您的函數變為:

int findId(void* list,int* count,unsigned int* tbid, int type)
{
    Book* booklist=NULL;
    Student* stulist=NULL;
    int i;
    if(type===0)
         booklist = (Book*) list;
    else if(type==1)
         stulist = (Student*) list;
    else
         // Handle this undefined case

    // And now use the same type variable to decide which pointer to use to match the values
    . . . . 
}

我認為您不能在這些函數中使用void*

如果將功能更改為一個,並創建如下內容:

int findObjId(void* objlist,int* count, unsigned int* objid)
{
    int i;
    for (i=0; i<*scount; i++)
    {
        if (objlist[i].id==*objid)
        {
            return i;
        }
    }
    return NOT_FOUND;
}   

您將無法從objlist提取數據。 *objlistobjlist[i]objlist[i]引用來評估對象。 編譯器肯定會阻止您使用任何此類語句。

如果可以選擇,請切換到C ++。 使用模板,您可以不費吹灰之力即可實現目標。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM