衡阳派盒市场营销有限公司

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

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

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

C語言函數(shù)中的傳值和傳指針到底有什么區(qū)別

strongerHuang ? 來源:未知 ? 作者:守望先生 ? 2019-09-08 10:14 ? 次閱讀

函數(shù)傳參有三種傳參方式:傳值、傳址、傳引用。

我們可能聽過C語言中的傳值和傳指針,在其他語言中,也有傳引用一說,那么他們到底有什么區(qū)別呢?如果你還不能準(zhǔn)確地分辨,就該好好了解一下了。

傳值

我們?cè)诔鯇W(xué)C語言的時(shí)候就被老師教過,下面的方式是無法交換a和b的值的:

#include voidswap(inta,intb) { inttemp=a; a=b; b=temp; printf("swapa=%d,b=%d ",a,b); } intmain(void) { inta=10; intb=20; printf("beforeswap:a=%d,b=%d ",a,b); swap(a,b); printf("afterswap:a=%d,b=%d ",a,b); return0; }

運(yùn)行結(jié)果如下:

beforeswap:a=10,b=20 internalswapa=20,b=10 afterswap:a=10,b=20

可以看到,a和b的值最終并沒有被交換。開始時(shí)a,b的值為10,20,而最終還是同樣的值。

為什么呢?因?yàn)楹瘮?shù)參數(shù)在傳遞的時(shí)候,都是傳原數(shù)據(jù)的副本,也就是說,swap內(nèi)部使用的a和b只是最初始a和b的一個(gè)副本而已,所以無論在swap函數(shù)內(nèi)部對(duì)a和b做任何改變,都不會(huì)影響初始的a和b的值。

正因如此,我們常常被告知,不要把直接把結(jié)構(gòu)體直接作為參數(shù),這樣效率會(huì)很低。由于結(jié)構(gòu)體本身占用字節(jié)數(shù)較大,如果直接作為參數(shù),那么將會(huì)產(chǎn)生一個(gè)較大的”副本“,如此一來,效率也就很低了。

我們?cè)俳Y(jié)合下面的圖來理解:

值傳遞

首先圖中方框中的上部分a和b代表了main函數(shù)中的a和b,即原始數(shù)據(jù),而方框中的下部分a和b代表了函數(shù)的參數(shù)a和b,即原始數(shù)據(jù)的“副本”。(后面的圖都是如此,上部分代表原始值,下部分代表函數(shù)參數(shù)值)。

調(diào)用swap函數(shù)前后的情形如下:

調(diào)用swap前后

由于在swap中永遠(yuǎn)只是對(duì)a和b的副本進(jìn)行操作,因此完全不影響原始的a和b的值。最終也不可能達(dá)到交換a和b的值的目的。

傳指針

那么為解決上面的問題,我們知道,需要傳指針。其代碼如下:

#include voidswap(int*a,int*b) { inttemp=*a; *a=*b; *b=temp; printf("swapa=%d,b=%d ",*a,*b); } intmain(void) { inta=10; intb=20; printf("beforeswap:a=%d,b=%d ",a,b); swap(&a,&b); printf("afterswap:a=%d,b=%d ",a,b); return0; }

運(yùn)行結(jié)果:

beforeswap:a=10,b=20 swapa=20,b=10 afterswap:a=20,b=10

可以看到在這種情況下,a,b的值才是真正交換了。

為什么又有傳值,又有傳指針

看到這里,不知道你是否會(huì)疑惑,為什么給函數(shù)傳遞參數(shù)的時(shí)候,一會(huì)是傳值,一會(huì)是傳指針呢?為什么傳指針就能改變參數(shù)的值呢?實(shí)際上,C語言里,參數(shù)傳遞都是值傳遞!也就是說,你認(rèn)為的傳指針也是傳值,只不過它的值是指針類型罷了。

我們?cè)偻ㄟ^圖來理解前面為什么傳指針就可以交換a,b的值:

從圖中可以看出,雖然傳遞給函數(shù)的是指向a和b的指針的副本,但是它的副本同樣也是指向a和b,因此雖然不能改變指針的指向,但是能改變參數(shù)a和b指向的內(nèi)容,即改變?cè)糰和b的值。

再看傳指針

如果是為指針p申請(qǐng)一段內(nèi)存,下面的代碼能達(dá)到目的嗎?

#include #include voidgetMemery(int*p) { /*申請(qǐng)1024個(gè)int大小*/ p=malloc(sizeof(int)*1024); if(NULL==p) { printf("mallocfailed "); p=NULL; } } intmain(void) { int*p=NULL; getMemery(p); printf("addressofpis%p ",p); return0; }

通過前面的內(nèi)容分析,肯定是達(dá)不到預(yù)期效果的。
運(yùn)行結(jié)果:

addressofpis(nil)

這是為什么呢?我們還是利用前面所知來分析,由于傳遞給getMemory函數(shù)的參數(shù)都是一個(gè)副本,因此函數(shù)內(nèi)的p也是外部p的一個(gè)副本,因此即便在函數(shù)內(nèi)部,將p指向了一塊新申請(qǐng)的內(nèi)存,仍然不會(huì)改變外面p的值,即p還是指向NULL。

getMemory

如何修改呢?我們需要傳入p的地址,即指向int類型指針的指針。

#include #include voidgetMemery(int**p) { /*申請(qǐng)1024個(gè)int大小*/ *p=malloc(sizeof(int)*1024); if(NULL==*p) { printf("mallocfailed "); *p=NULL; } } intmain(void) { int*p=NULL; getMemery(&p); printf("addressofpis%p ",p); free(p); p=NULL; return0; }

運(yùn)行結(jié)果如下:

addressofpis0x144f010

從運(yùn)行結(jié)果可以看到,p的值被改變了,而不再是初始的NULL。

可配合下面的圖進(jìn)行理解:

getMemory

總結(jié)

本文總結(jié)如下:

函數(shù)的參數(shù)都是原數(shù)據(jù)的“副本”,因此在函數(shù)內(nèi)無法改變?cè)瓟?shù)據(jù)

函數(shù)中參數(shù)都是傳值,傳指針本質(zhì)上也是傳值

如果想要改變?nèi)雲(yún)?nèi)容,則需要傳該入?yún)⒌牡刂罚ㄖ羔樅鸵枚际穷愃频淖饔茫ㄟ^解引用修改其指向的內(nèi)容

以上結(jié)論不限于C語言

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

    關(guān)注

    180

    文章

    7614

    瀏覽量

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

    關(guān)注

    3

    文章

    4346

    瀏覽量

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

    關(guān)注

    1

    文章

    481

    瀏覽量

    70608

原文標(biāo)題:C語言函數(shù)參數(shù)的傳值和傳指針有什么區(qū)別?

文章出處:【微信號(hào):strongerHuang,微信公眾號(hào):strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    乘法器與調(diào)制器到底有什么區(qū)別

    乘法器與調(diào)制器到底有什么區(qū)別?調(diào)制函數(shù)的建模方法是什么?
    發(fā)表于 04-09 06:33

    USB 3.0和USB 2.0到底有什么區(qū)別呢?

    圖文講解USB 3.0和USB 2.0到底有什么區(qū)別呢?
    發(fā)表于 05-19 07:12

    KEIL、uVision、MDK、KEIL C51、RealView它們到底有什么區(qū)別

    KEIL、uVision、MDK、KEIL C51、RealView它們到底有什么區(qū)別,又有什么聯(lián)系?
    發(fā)表于 07-01 09:08

    ARM和DSP到底有什么區(qū)別

    現(xiàn)在在學(xué)ARM,想知道ARM和DSP到底有什么區(qū)別?為什么有些地方用DSP有些用ARM
    發(fā)表于 10-19 07:20

    C語言回調(diào)函數(shù)學(xué)習(xí)

    對(duì)指針的應(yīng)用是C語言編程的精髓所在,而回調(diào)函數(shù)就是C語言里面對(duì)
    發(fā)表于 05-27 09:44 ?7224次閱讀

    c語言函數(shù)指針定義,指針函數(shù)函數(shù)指針區(qū)別

     往往,我們一提到指針函數(shù)函數(shù)指針的時(shí)候,就有很多人弄不懂。下面就由小編詳細(xì)為大家介紹C語言
    發(fā)表于 11-16 15:18 ?3639次閱讀

    C語言函數(shù)參數(shù)關(guān)于指針什么區(qū)別

    C語言函數(shù)參數(shù)的指針
    的頭像 發(fā)表于 02-26 16:35 ?2286次閱讀

    CAN通訊摩托羅拉格式與英特爾格式到底有什么區(qū)別

    本文檔的主要內(nèi)容詳細(xì)介紹的是CAN通訊摩托羅拉格式與英特爾格式到底有什么區(qū)別
    發(fā)表于 03-03 08:00 ?23次下載
    CAN通訊<b class='flag-5'>中</b>摩托羅拉格式與英特爾格式<b class='flag-5'>到底有</b><b class='flag-5'>什么區(qū)別</b>

    址、引用的區(qū)別,哪個(gè)更高效?

    址、引用的區(qū)別,哪個(gè)更高效?
    的頭像 發(fā)表于 06-29 15:05 ?6463次閱讀

    智能照明和傳統(tǒng)照明的系統(tǒng)到底有什么區(qū)別

    電子發(fā)燒友網(wǎng)站提供智能照明和傳統(tǒng)照明的系統(tǒng)到底有什么區(qū)別資料免費(fèi)下載
    發(fā)表于 11-26 06:41 ?26次下載

    C語言指針和數(shù)組的區(qū)別

    C語言教程我們使用通過數(shù)組名通過偏移和指針偏移都可以遍歷數(shù)組,那么指針和數(shù)組到底有
    的頭像 發(fā)表于 07-18 16:29 ?1985次閱讀

    C語言-函數(shù)的定義、聲明、

    C語言函數(shù)是非常重要的知識(shí)點(diǎn),一個(gè)完整的C語言程序就是由主函數(shù)和各個(gè)子
    的頭像 發(fā)表于 08-14 09:57 ?2008次閱讀

    C語言-指針作為函數(shù)形參類型

    C語言函數(shù)里最常用就是指針參和返回地址,特別是字符串處理,經(jīng)常需要封裝各種功能
    的頭像 發(fā)表于 08-14 10:05 ?1949次閱讀

    FPC與傳統(tǒng)PCB到底有什么區(qū)別.zip

    FPC與傳統(tǒng)PCB到底有什么區(qū)別
    發(fā)表于 03-01 15:37 ?4次下載

    RTOS與Linux到底有什么區(qū)別

    很多做嵌入式開發(fā)的小伙伴都存在這樣的疑惑:RTOS與Linux到底有什么區(qū)別
    的頭像 發(fā)表于 10-29 09:53 ?585次閱讀
    百家乐技巧下载| 星港城百家乐官网娱乐城| 钱隆百家乐官网破解版| 百家乐网络游戏平台| 郴州市| 澳门百家乐赢钱秘| 静海县| 小孟百家乐的玩法技巧和规则| 百家乐官网平台哪个比较安全 | 百家乐官网最新分析仪| 丰合网上娱乐| 澳门百家乐玩大小| 西丰县| 电脑百家乐玩| 猪猪网百家乐官网软件| 大发888现金存款| 折式百家乐赌台| 百家乐官网园千术大全| 百家乐平一直压庄| 百家乐官网平注法到6| 北票市| 大发888娱乐场客户端下载| 百家乐官网又称什么| 百家乐官网使用技法| 太子百家乐娱乐城| 百家乐官网皇室百家乐官网的玩法技巧和规则 | 皇冠备用网址| 济州岛百家乐的玩法技巧和规则| 金沙百家乐官网的玩法技巧和规则| 皇冠足球网开户| 基础百家乐博牌| 无锡百家乐官网的玩法技巧和规则| 开阳县| 太阳城巧克力| 百家乐打法内容介绍| 澳门百家乐官网威尼斯| 棋牌游戏平台排行榜| 曼哈顿百家乐娱乐城| 南京百家乐官网的玩法技巧和规则| 百家乐官网赢钱lv| 大发888娱乐城34|