中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C語言中傳值與傳指針的區別是什么

發布時間:2021-08-11 14:29:45 來源:億速云 閱讀:127 作者:chen 欄目:編程語言

本篇內容介紹了“C語言中傳值與傳指針的區別是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

前言

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

傳值

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

#include<stdio.h>void swap(int a,int b){ int temp = a; a = b; b = temp; printf("swap a = %d,b = %d\n",a,b);}int main(void){ int a = 10; int b = 20; printf("before swap:a = %d,b = %d\n",a,b); swap(a,b); printf("after swap:a = %d,b = %d\n",a,b); return 0;}

運行結果如下:

before swap:a = 10,b = 20 internal swap a = 20,b = 10 after swap: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中永遠只是對a和b的副本進行操作,因此完全不影響原始的a和b的值。最終也不可能達到交換a和b的值的目的。

傳指針

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

#include<stdio.h>void swap(int *a,int *b){ int temp = *a; *a = *b; *b = temp; printf("swap a = %d,b = %d\n",*a,*b);}int main(void){ int a = 10; int b = 20; printf("before swap:a = %d,b = %d\n",a,b); swap(&a,&b); printf("after swap:a = %d,b = %d\n",a,b); return 0;}

運行結果:

before swap:a = 10,b = 20 swap a = 20,b = 10 after swap:a = 20,b = 10

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

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

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

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

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

再看傳指針

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

#include<stdio.h>#include<stdlib.h>void getMemery(int *p){ /*申請1024個int大小*/ p = malloc(sizeof(int)*1024); if(NULL == p) { printf("malloc failed\n"); p = NULL; }}int main(void){ int *p = NULL; getMemery(p); printf("address of p is %p\n",p); return 0;}

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

運行結果:

address of p is (nil)

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

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

#include<stdio.h>#include<stdlib.h>void getMemery(int **p){ /*申請1024個int大小*/ *p = malloc(sizeof(int)*1024); if(NULL == *p) { printf("malloc failed\n"); *p = NULL; }}int main(void){ int *p = NULL; getMemery(&p); printf("address of p is %p\n",p); free(p); p = NULL; return 0;}

運行結果如下:

address of p is 0x144f010

從運行結果可以看到,p的值被改變了。

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

總結

本文總結如下:

函數的形參都是原數據的“副本”,因此在函數內無法改變原數據  函數中參數都是傳值,傳指針本質上也是傳值  如果想要改變入參內容,則需要傳該入參的地址(指針和引用都是類似的作用),通過解引用修改其指向的內容  以上結論不限于C語言

“C語言中傳值與傳指針的區別是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

无极县| 隆子县| 清河县| 沾益县| 合作市| 康平县| 墨脱县| 新乡市| 额济纳旗| 济宁市| 平阳县| 贵港市| 井陉县| 淮安市| 永新县| 枣庄市| 治多县| 那坡县| 新野县| 新邵县| 井冈山市| 武强县| 朔州市| 平武县| 寻乌县| 孝义市| 千阳县| 揭阳市| 钟山县| 嵊泗县| 通海县| 扎赉特旗| 浏阳市| 丘北县| 侯马市| 灵璧县| 恩施市| 天全县| 花莲县| 张北县| 南华县|