99精品伊人亚洲|最近国产中文炮友|九草在线视频支援|AV网站大全最新|美女黄片免费观看|国产精品资源视频|精彩无码视频一区|91大神在线后入|伊人终合在线播放|久草综合久久中文

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

一文揭秘C語(yǔ)言的void指針

工程師進(jìn)階筆記 ? 來(lái)源:小麥大叔 ? 2023-02-02 17:18 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1 不能動(dòng)的“地址”之 void指針

1.1 void指針初探

void *表示一個(gè)“不知道類型”的指針,也就不知道從這個(gè)指針地址開(kāi)始多少字節(jié)為一個(gè)數(shù)據(jù)。和用int表示指針異曲同工,只是更明確是“指針”。

因此void *只能表示一個(gè)地址,不能用來(lái)&取值,也不能++和--移動(dòng)指針,因此不知道多少字節(jié)是一個(gè)數(shù)據(jù)單位。

intnums[]={3,5,6,7,9};
void*ptr1=nums;
//inti=*ptr1;//對(duì)于void指針沒(méi)法直接取值
int*ptr2=(int*)nums;
printf("%d,%d
",ptr1,ptr2);
inti=*ptr2;
printf("%d
",i);

從輸出結(jié)果可以看出,無(wú)論是無(wú)類型的void指針還是int類型指針,指向的地址都是一樣的:

89ca1ff4-a2d8-11ed-bfe3-dac502259ad0.png

PS:void *就是一個(gè)不能動(dòng)的“地址”,在進(jìn)行&、移動(dòng)指針之前必須轉(zhuǎn)型為類型指針。

1.2 void指針的用途

89d7eaf8-a2d8-11ed-bfe3-dac502259ad0.png

這里我們看一下我們之前了解的memset函數(shù),其第一個(gè)參數(shù)就是一個(gè)void指針,它可以幫我們屏蔽各種不同類型指針的差異。 如下面代碼所示,我們既可以傳入一個(gè)int類型數(shù)組的指針,也可以傳入一個(gè)char類型數(shù)組的指針:

intnums[20];
memset(nums,0,sizeof(nums));
charchs[2];
memset(chs,0,sizeof(chs));

那么,我們也可以試著自己動(dòng)手模擬一下這個(gè)memset函數(shù),暫且命名為mymemset吧:

voidmymemset(void*data,intnum,intbyteSize)
{
//char就是一個(gè)字節(jié),而計(jì)算機(jī)中是以字節(jié)為單位存儲(chǔ)的
char*ptr=(char*)data;
inti;
for(i=0;i

在這個(gè)mymemset函數(shù)中,我們利用void指針接收不同類型的指針,利用char類型(一個(gè)字節(jié))逐個(gè)字節(jié)讀取內(nèi)存中的每一個(gè)字節(jié),最后依次填充指定的數(shù)字。

由于char類型是一個(gè)具體類型,所以可以使用++或者--進(jìn)行指針的移動(dòng)。

對(duì)于結(jié)構(gòu)體類型,也可以使用我們的mymemset函數(shù):

typedefstruct_Person
{
char*name;
intage;
}Person;

Personp1;
mymemset(&p1,0,sizeof(Person));
printf("p1.Age:%d
",p1.age);

最終的運(yùn)行結(jié)果如下圖所示:

89ec4638-a2d8-11ed-bfe3-dac502259ad0.png

void *的用途:在只知道內(nèi)存,但是不知道是什么類型的時(shí)候。

2 函數(shù)指針

2.1 指向函數(shù)的指針

我們可以在C中輕松地定義一個(gè)函數(shù)指針:

typedefvoid(*intFunc)(inti);

這里我們定義了一個(gè)無(wú)返回值的,只有一個(gè)int類型參數(shù)的函數(shù)指針intFunc。

我們可以在main函數(shù)中使用這個(gè)函數(shù)指針來(lái)指向一個(gè)具體的函數(shù)(這個(gè)具體的函數(shù)定義需要和函數(shù)指針的定義一致):

voidtest1(intage){

printf("test1:%d
",age);
}

intmain(void){

//聲明一個(gè)intFunc類型的函數(shù)指針
intFuncf1=test1;
//執(zhí)行f1函數(shù)指針?biāo)赶虻拇a區(qū)
f1(8);
return0;
}
最終運(yùn)行結(jié)果如下圖所示,執(zhí)行函數(shù)指針f1即執(zhí)行了其所指向的具體的函數(shù):

89fece66-a2d8-11ed-bfe3-dac502259ad0.png

2.2 函數(shù)指針的基本使用

這里我們通過(guò)一個(gè)小案例來(lái)對(duì)函數(shù)指針做一個(gè)基本的使用介紹。相信大部分的C#Java程序員都很熟悉foreach,那么我們就來(lái)模擬foreach對(duì)int數(shù)組中的值進(jìn)行不同的處理。具體體現(xiàn)為for循環(huán)的代碼是復(fù)用的,但是怎么處理這些數(shù)據(jù)不確定,因此把處理數(shù)據(jù)的邏輯由函數(shù)指針指定。

voidforeachNums(int*nums,intlen,intFuncfunc)
{
inti;
for(i=0;i
在foreachNums函數(shù)中,我們定義了一個(gè)intFunc函數(shù)指針,printNum函數(shù)是滿足intFunc定義的一個(gè)具體的函數(shù)。

下面我們?cè)趍ain函數(shù)中將printNum函數(shù)作為函數(shù)指針傳遞給foreachNums函數(shù)。

intnums[]={1,5,666,23423,223};
foreachNums(nums,sizeof(nums)/sizeof(int),printNum);
最終運(yùn)行的結(jié)果如下圖所示:

8a108c14-a2d8-11ed-bfe3-dac502259ad0.png

通過(guò)函數(shù)指針,我們可以屏蔽各種具體處理方法的不同,也就是將不確定的因素都依賴于抽象,這也是面向抽象或面向接口編程的精髓。

三、函數(shù)指針應(yīng)用案例

3.1 計(jì)算任意類型的最大值

(1)定義函數(shù)指針及getMax主體:

typedefint(*compareFunc)(void*data1,void*data2);
// getMax 函數(shù)參數(shù)說(shuō)明:
//data待比較數(shù)據(jù)數(shù)組的首地址,uniteSize單元字節(jié)個(gè)數(shù)
// length:數(shù)據(jù)的長(zhǎng)度。{1,3,5,6}:length=4
//比較data1和data2指向的數(shù)據(jù)做比較,
//如果data1>data2,則返回正數(shù)
void*getMax(void*data,intunitSize,intlength,compareFuncfunc)
{
inti;
char*ptr=(char*)data;
char*max=ptr;

for(i=1;i0)
{
max=item;
}
}

returnmax;
}
這里可以看到,在getMax中到底取幾個(gè)字節(jié)去比較都是由compareFunc所指向的函數(shù)去做,getMax根本不用關(guān)心。

(2)定義符合函數(shù)指針定義的不同類型的函數(shù):

intintDataCompare(void*data1,void*data2)
{
int*ptr1=(int*)data1;
int*ptr2=(int*)data2;

inti1=*ptr1;
inti2=*ptr2;

returni1-i2;
}

typedefstruct_Dog
{
char*name;
intage;
}Dog;

intdogDataCompare(void*data1,void*data2)
{
Dog*dog1=(Dog*)data1;
Dog*dog2=(Dog*)data2;

return(dog1->age)-(dog2->age);
}

(3)在main函數(shù)中針對(duì)int類型和結(jié)構(gòu)體類型進(jìn)行調(diào)用:

intmain(intargc,char*argv[])
{
//test1:int類型求最大值
intnums[]={3,5,8,7,6};
int*pMax=(int*)getMax(nums,sizeof(int),sizeof(nums)/sizeof(int),
intDataCompare);
intmax=*pMax;
printf("%d
",max);
//test2:結(jié)構(gòu)體類型求最大值
Dogdogs[]={{"沙皮",3},{"臘腸",10},{"哈士奇",5},
{"京巴",8},{"大狗",2}};
Dog*pDog=(Dog*)getMax(dogs,sizeof(Dog),
sizeof(dogs)/sizeof(Dog),dogDataCompare);
printf("%s=%d",pDog->name,pDog->age);

return0;
}

最終運(yùn)行結(jié)果如下圖所示:

8a221a42-a2d8-11ed-bfe3-dac502259ad0.png

3.2 C 中自帶的qsort函數(shù)—自定義排序

qsort包含在頭文件中,此函數(shù)根據(jù)你給的比較條件進(jìn)行快速排序,通過(guò)指針移動(dòng)實(shí)現(xiàn)排序。排序之后的結(jié)果仍然放在原數(shù)組中。

使用qsort函數(shù)必須自己寫(xiě)一個(gè)比較函數(shù)。我們可以看看qsort函數(shù)的原型:

voidqsort(void*base,size_tnum,size_tsize,int(*comparator)(constvoid*,constvoid*));
intnums[]={3,5,8,7,6};
qsort(nums,sizeof(nums)/sizeof(int),sizeof(int),intDataCompare);
inti;
for(i=0;i
那么,快速排序后是否有結(jié)果呢?答案是肯定的,我們可以傳入各種比較方法,可以升序排序也可以降序排序。

8a3678d4-a2d8-11ed-bfe3-dac502259ad0.png

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • C語(yǔ)言
    +關(guān)注

    關(guān)注

    180

    文章

    7632

    瀏覽量

    141826
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4381

    瀏覽量

    64926
  • 指針
    +關(guān)注

    關(guān)注

    1

    文章

    484

    瀏覽量

    71200
  • void
    +關(guān)注
  • 函數(shù)指針
    +關(guān)注

    關(guān)注

    2

    文章

    57

    瀏覽量

    3976

原文標(biāo)題:揭秘 C 語(yǔ)言的 void 指針

文章出處:【微信號(hào):工程師進(jìn)階筆記,微信公眾號(hào):工程師進(jìn)階筆記】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    C語(yǔ)言void指針的基本認(rèn)識(shí)及典型應(yīng)用

    C語(yǔ)言中,*類型就是指針類型,比如 int *p,double *q,雖然是不樣的指針,但是大小卻
    發(fā)表于 02-01 09:26 ?1378次閱讀

    c語(yǔ)言指針詳解

    。9、空指針 指向空,或者說(shuō)不指向任何東西。在C語(yǔ)言中,我們讓指針變量賦值為NULL表示個(gè)空指針
    發(fā)表于 03-26 09:51

    什么是void指針?void指針有何功能

    [導(dǎo)讀] 要比較靈活的使用C語(yǔ)言實(shí)現(xiàn)些高層級(jí)的框架時(shí),需要掌握些進(jìn)階編程技巧,這篇來(lái)談?wù)?b class='flag-5'>void指針
    發(fā)表于 02-21 06:01

    C語(yǔ)言voidvoid指針深層探索

    1.概述 本文將對(duì)void關(guān)鍵字的深刻含義進(jìn)行解說(shuō),并詳述voidvoid指針類型的使用方法與技巧。 2.void的含義
    發(fā)表于 09-21 11:36 ?166次下載

    C語(yǔ)言指針電子教程

    本資料是份不錯(cuò)的關(guān)于C語(yǔ)言指針的電子教程,希望對(duì)大家有所幫助... 指針簡(jiǎn)介 指針
    發(fā)表于 07-30 16:00 ?77次下載

    C語(yǔ)言的精髓——指針詳解

    C語(yǔ)言的精髓——指針詳解
    發(fā)表于 11-30 14:43 ?17次下載

    講通C語(yǔ)言指針資料下載

    電子發(fā)燒友網(wǎng)為你提供講通C語(yǔ)言指針資料下載的電子資料下載,更有其他相關(guān)的電路圖、源代碼、課件教程、中文資料、英文資料、參考設(shè)計(jì)、用戶指南
    發(fā)表于 04-24 08:44 ?10次下載
    <b class='flag-5'>一</b><b class='flag-5'>文</b>講通<b class='flag-5'>C</b><b class='flag-5'>語(yǔ)言</b><b class='flag-5'>指針</b>資料下載

    淺談void指針的高階用法

    要比較靈活的使用C語(yǔ)言實(shí)現(xiàn)些高層級(jí)的框架時(shí),需要掌握些進(jìn)階編程技巧,這篇來(lái)談?wù)?b class='flag-5'>void指針
    的頭像 發(fā)表于 08-09 15:54 ?1929次閱讀
    淺談<b class='flag-5'>void</b> 型<b class='flag-5'>指針</b>的高階用法

    STM32編程:void指針高階用法舉例,設(shè)計(jì)個(gè)通用掉電存儲(chǔ)子系統(tǒng)

    [導(dǎo)讀] 要比較靈活的使用C語(yǔ)言實(shí)現(xiàn)些高層級(jí)的框架時(shí),需要掌握些進(jìn)階編程技巧,這篇來(lái)談?wù)?b class='flag-5'>void指針
    發(fā)表于 12-27 18:47 ?10次下載
    STM32編程:<b class='flag-5'>void</b><b class='flag-5'>指針</b>高階用法舉例,設(shè)計(jì)<b class='flag-5'>一</b>個(gè)通用掉電存儲(chǔ)子系統(tǒng)

    STM32編程:void指針高階用法

    [導(dǎo)讀] 要比較靈活的使用C語(yǔ)言實(shí)現(xiàn)些高層級(jí)的框架時(shí),需要掌握些進(jìn)階編程技巧,這篇來(lái)談?wù)?b class='flag-5'>void指針
    發(fā)表于 02-07 11:14 ?2次下載
    STM32編程:<b class='flag-5'>void</b><b class='flag-5'>指針</b>高階用法

    C語(yǔ)言-指針定義與使用

    指針在很多書(shū)本上都是當(dāng)做重點(diǎn)來(lái)介紹,作為C語(yǔ)言的靈魂,項(xiàng)目里指針無(wú)處不在。 這篇文章介紹指針的基本用法。
    的頭像 發(fā)表于 08-14 10:02 ?1655次閱讀

    C語(yǔ)言-void類型作為萬(wàn)能指針類型

    空類型`。 void abc; //這是錯(cuò)誤的 但是`void`是可以定義指針的,`void*`表示萬(wàn)能型指針類型,可以與任何
    的頭像 發(fā)表于 08-14 10:04 ?2208次閱讀

    C語(yǔ)言進(jìn)階】C語(yǔ)言指針的高階用法

    C語(yǔ)言進(jìn)階】C語(yǔ)言指針的高階用法
    的頭像 發(fā)表于 08-31 13:24 ?2794次閱讀

    什么是void指針

    C語(yǔ)言中,*類型就是指針類型,比如 int *p,double *q,雖然是不樣的指針,但是大小卻
    的頭像 發(fā)表于 02-13 15:02 ?1692次閱讀

    什么是C語(yǔ)言void*)類型

    大家在C語(yǔ)言的學(xué)習(xí)過(guò)程中肯定見(jiàn)過(guò)各種指針符號(hào),如 int*, char* 等等等等。顧名思義,int*就是個(gè)指向整形的指針,而char*
    的頭像 發(fā)表于 02-24 14:31 ?3953次閱讀