在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

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

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

3天內不再提示

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

黃工的嵌入式技術圈 ? 來源:編程珠璣 ? 作者:守望先生 ? 2020-02-26 16:35 ? 次閱讀

前言

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

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

傳值

我們在初學C語言的時候就被老師教過,下面的方式是無法交換a和b的值的:

#include voidswap(inta,intb) { inttemp=a; a=b; b=temp; printf("swapa=%d,b=%d\n",a,b); } intmain(void) { inta=10; intb=20; printf("beforeswap:a=%d,b=%d\n",a,b); swap(a,b); printf("afterswap:a=%d,b=%d\n",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\n",*a,*b); } intmain(void) { inta=10; intb=20; printf("beforeswap:a=%d,b=%d\n",a,b); swap(&a,&b); printf("afterswap:a=%d,b=%d\n",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\n"); p=NULL; } } intmain(void) { int*p=NULL; getMemery(p); printf("addressofpis%p\n",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\n"); *p=NULL; } } intmain(void) { int*p=NULL; getMemery(&p); printf("addressofpis%p\n",p); free(p); p=NULL; return0; }

運行結果如下:

addressofpis0x144f010

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

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

getMemory

總結

本文總結如下:

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

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

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

以上結論不限于C語言

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

    關注

    180

    文章

    7626

    瀏覽量

    139538
  • SWAP
    +關注

    關注

    0

    文章

    51

    瀏覽量

    13091
  • 函數
    +關注

    關注

    3

    文章

    4363

    瀏覽量

    63725
收藏 人收藏

    評論

    相關推薦

    GD32與STM32什么區別

    電子發燒友網站提供《GD32與STM32什么區別.docx》資料免費下載
    發表于 04-03 17:27 ?0次下載

    關于STM32 CAN通信發送函數HAL_CAN_AddTxMessage()的最后一個參數填0和定義一個變量取地址的問題求解

    問題: 關于STM32 CAN通信 發送函數 HAL_CAN_AddTxMessage()的最后一個參數填0和定義一個變量取地址的問題,如果直接0,我實驗發現 STM32F103
    發表于 03-11 08:22

    同樣是函數,在CC++中有什么區別

    同樣是函數,在 CC++ 中有什么區別? 第一個返回C
    的頭像 發表于 11-29 10:25 ?690次閱讀

    C語言程序設計教程第4版第8講:指針

    C語言指針講解
    發表于 11-20 14:10 ?5次下載

    C語言指針學習筆記

    本文從底層內存分析,徹底讓讀者明白C語言指針的本質。
    的頭像 發表于 11-05 17:40 ?507次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>指針</b>學習筆記

    C語言C++中結構體的區別

    同樣是結構體,看看在C語言C++中有什么區別
    的頭像 發表于 10-30 15:11 ?570次閱讀

    C語言指針運算符詳解

    C語言中,當你一個指向數組中某個元素的指針時,你可以對該指針執行某些算術運算,例如加法或減法。這些運算可以用來遍歷數組中的元素,如ptr
    的頭像 發表于 10-30 11:16 ?530次閱讀

    C語言指針詳細解析

    可以對數據本身,也可以對存儲數據的變量地址進行操作。 指針是一個占據存儲空間的實體在這一段空間起始位置的相對距離。在C/C++語言中,
    發表于 09-14 10:03

    面試常考+1:函數指針指針函數、數組指針指針數組

    函數是指返回指針函數。語法:返回類型*函數名(參數
    的頭像 發表于 08-10 08:11 ?1195次閱讀
    面試常考+1:<b class='flag-5'>函數</b><b class='flag-5'>指針</b>與<b class='flag-5'>指針</b><b class='flag-5'>函數</b>、數組<b class='flag-5'>指針</b>與<b class='flag-5'>指針</b>數組

    網絡透和非透什么區別是什么

    :適用簡易、立即的數據傳輸,留意數據的完整性和低延遲。非透:適用必須進行數據解決優化的狀況,提供良好的可靠性和效果。 在挑選傳輸技術時,務必根據實際的業務需求、數據種類、安全規定和傳輸效率等要素開展考量。
    的頭像 發表于 08-07 16:19 ?1343次閱讀

    創建Trigger時設置的url可以參數嗎?

    創建Trigger時設置的url可以參數嗎?設置url參數的話沒有效果啊。默認url會傳遞參數嗎?在api文檔上沒有看到說明哦。
    發表于 07-15 07:30

    面試中的高頻問題:指針函數函數指針,你能完美應對嗎?

    一直覺得C語言較其他語言最偉大的地方就是C語言中的指針,有些人認為
    的頭像 發表于 06-22 08:11 ?2091次閱讀
    面試中的高頻問題:<b class='flag-5'>指針</b><b class='flag-5'>函數</b>與<b class='flag-5'>函數</b><b class='flag-5'>指針</b>,你能完美應對嗎?

    輕松搞懂透和非透區別

    和非透是數據通信中的兩種不同模式,各自有其適用場景和優勢。透模式簡單、高效,適用于數據完整性要求高的場景;非透模式則通過數據處理提供安全性和可靠性,適用于復雜通信需求的場景。
    的頭像 發表于 06-05 12:03 ?1.2w次閱讀
    輕松搞懂透<b class='flag-5'>傳</b>和非透<b class='flag-5'>傳</b>的<b class='flag-5'>區別</b>

    提高C代碼可讀性的編寫技巧與策略

    指針C 語言的靈魂,是 C 比其他語言更靈活,更強大的地方。所以學習 C
    發表于 04-23 18:25 ?693次閱讀

    C語言函數指針六大應用場景詳解

    函數指針是一種非常強大的編程工具,它可以讓我們以更加靈活的方式編寫程序。在本文中,我們將介紹 6 個函數指針的高級應用場景,并貼出相應的代碼案例和解釋。
    的頭像 發表于 04-23 18:19 ?1207次閱讀
    主站蜘蛛池模板: 两性色午夜视频免费网 | 亚洲欧美成人综合久久久 | 免费一级e一片在线播放 | 中国一级做a爰片久久毛片 中韩日欧美电影免费看 | 国产簧片 | 午夜影音 | 欧美性白人极品1819hd高清 | 欧美亚洲h在线一区二区 | 欧美日韩国产成人精品 | 伊人天伊人天天网综合视频 | 久久15| 婷婷综合久久 | 亚洲伊人tv综合网色 | 久久精品国产福利国产琪琪 | 国产69久久精品成人看 | 亚洲成人高清在线 | 五月激情五月婷婷 | 777奇米影视笫四色88me久久综合 | 国模鲍鱼| 男人操女人视频在线观看 | 色欲情狂| 亚洲欧美色鬼久久综合 | 黄网站在线观看视频 | 国产一级免费视频 | 白浆喷射 | 波多野结衣在线观看一区二区 | 狠狠躁夜夜躁人人爽天天段 | 色综合久久中文字幕网 | 欧美一级片在线免费观看 | 色综合视频一区二区三区 | 色视频欧美 | 激情婷婷综合久久久久 | 521色香蕉网在线观看免费 | 国产福利午夜 | 久久sese| 日本爱爱片 | 91色蝌蚪| 精品久久久久久国产免费了 | 久久99精品国产麻豆宅宅 | 性欧美高清 | 午夜操 |