<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

C語言函數中的傳值和傳指針到底有什么區別

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

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

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

傳值

我們在初學C語言的時候就被老師教過,下面的方式是無法交換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; }

運行結果如下:

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

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

為什么呢?因為函數參數在傳遞的時候,都是傳原數據的副本,也就是說,swap內部使用的a和b只是最初始a和b的一個副本而已,所以無論在swap函數內部對a和b做任何改變,都不會影響初始的a和b的值。

正因如此,我們常常被告知,不要把直接把結構體直接作為參數,這樣效率會很低。由于結構體本身占用字節數較大,如果直接作為參數,那么將會產生一個較大的”副本“,如此一來,效率也就很低了。

我們再結合下面的圖來理解:

值傳遞

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

調用swap函數前后的情形如下:

調用swap前后

由于在swap中永遠只是對a和b的副本進行操作,因此完全不影響原始的a和b的值。最終也不可能達到交換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; }

運行結果:

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

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

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

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

我們再通過圖來理解前面為什么傳指針就可以交換a,b的值:

從圖中可以看出,雖然傳遞給函數的是指向a和b的指針的副本,但是它的副本同樣也是指向a和b,因此雖然不能改變指針的指向,但是能改變參數a和b指向的內容,即改變原始a和b的值。

再看傳指針

如果是為指針p申請一段內存,下面的代碼能達到目的嗎?

#include #include voidgetMemery(int*p) { /*申請1024個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; }

通過前面的內容分析,肯定是達不到預期效果的。
運行結果:

addressofpis(nil)

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

getMemory

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

#include #include voidgetMemery(int**p) { /*申請1024個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; }

運行結果如下:

addressofpis0x144f010

從運行結果可以看到,p的值被改變了,而不再是初始的NULL。

可配合下面的圖進行理解:

getMemory

總結

本文總結如下:

函數的參數都是原數據的“副本”,因此在函數內無法改變原數據

函數中參數都是傳值,傳指針本質上也是傳值

如果想要改變入參內容,則需要傳該入參的地址(指針和引用都是類似的作用),通過解引用修改其指向的內容

以上結論不限于C語言

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    180

    文章

    7542

    瀏覽量

    131058
  • 函數
    +關注

    關注

    3

    文章

    4114

    瀏覽量

    61426
  • 指針
    +關注

    關注

    1

    文章

    474

    瀏覽量

    70386

原文標題:C語言函數參數的傳值和傳指針有什么區別?

文章出處:【微信號:strongerHuang,微信公眾號:strongerHuang】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    ARM Cortex-M0與Cortex-M0+到底有什么區別

    ARM Cortex-M0與Cortex-M0+到底有什么區別
    發表于 01-04 23:15

    同時DSP2812的源文件,命名不同,到底有什么區別?

    同時DSP2812的源文件,命名不同,到底有什么區別?新建DSP工程時,到底用那種文件呢?講究嗎?
    發表于 04-07 12:57

    請問ESP8266 wifi模塊透與普通模式什么區別?

    請問這個wifi模塊 透與普通模式什么區別,什么叫透模式,謝謝??!
    發表于 06-03 23:32

    請問不同編程語言區別到底在哪里?

    不同編程語言區別到底在哪里??C語言、python、ruby、java...撇開前端開發語言不談,但論這些后端
    發表于 06-02 06:44

    LED恒壓電源和恒流電源到底有什么區別?

    LED恒壓電源和恒流電源到底有什么區別?
    發表于 12-07 14:53

    乘法器與調制器到底有什么區別?

    乘法器與調制器到底有什么區別?調制函數的建模方法是什么?
    發表于 04-09 06:33

    USB 3.0和USB 2.0到底有什么區別呢?

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

    KEIL、uVision、MDK、KEIL C51、RealView它們到底有什么區別?

    KEIL、uVision、MDK、KEIL C51、RealView它們到底有什么區別,又有什么聯系?
    發表于 07-01 09:08

    嵌入式開發與C++開發到底有什么區別

    我們常聽到嵌入式開發與C++開發,那么他們到底有什么區別呢?今天主要從概念以及技術應用領域的不同來介紹。一、概念區別
    發表于 11-05 08:27

    FPGA和CPLD到底有什么區別?求具體例子說明

    FPGA和CPLD到底有什么區別,還有VHDL,一直分不清他們什么差別。求具體例子說明
    發表于 04-23 11:49

    ARM和DSP到底有什么區別?

    現在在學ARM,想知道ARM和DSP到底有什么區別?為什么有些地方用DSP有些用ARM
    發表于 10-19 07:20

    c語言函數指針定義,指針函數函數指針區別

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

    C語言函數參數關于傳值和傳指針什么區別?

    C語言函數參數的傳值和傳指針什么區別?
    的頭像 發表于 02-26 16:35 ?1982次閱讀

    C語言指針和數組的區別

    在C語言教程中我們使用通過數組名通過偏移和指針偏移都可以遍歷數組,那么指針和數組到底有什么區別??
    的頭像 發表于 07-18 16:29 ?1585次閱讀

    FPC與傳統PCB到底有什么區別.zip

    FPC與傳統PCB到底有什么區別
    發表于 03-01 15:37 ?4次下載
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>