C語言值傳遞和地址傳遞詳解
一. 值傳遞
我們舉一個例子:
寫一個函數(shù)找出兩個整數(shù)中的最大值。
#include<stdio.h>
//get_max函數(shù)
int get_max(int x,int y)
{
return (x>y)?x:y;
}
int main()
{
int num1 = 10;
int num2 = 20;
int max = get_max(num1,num2);
printf("max = %d\n",max);
return 0;
}
運行結(jié)果是:
max = 20
我們來分析一下這個函數(shù)調(diào)用過程:
num1,num2作為實參傳入get_max()函數(shù),形參x,y被實例化(分配內(nèi)存單元),num1和num2的值按照函數(shù)形參表順序?qū)?yīng)地傳給了x和y,也就是x=10,y=20,然后函數(shù)將x和y中較大的一個的值返回。函數(shù)調(diào)用完畢,x和y被自動銷毀。
我們看一下函數(shù)的特征,如果函數(shù)的形參和實參一致,這就是值傳遞。
二.地址傳遞
再舉一個例子:
寫一個函數(shù)交換兩個整形變量的內(nèi)容。
很多初學(xué)者一看覺得太簡單了,按照值傳遞我們來寫一遍。
#include <stdio.h>
//值傳遞
void Swap1(int x, int y) {
int tmp = 0;
tmp = x;
x = y;
y = tmp;
}
int main()
{
int num1 = 1;
int num2 = 2;
printf("交換前::num1 = %d num2 = %d\n",num1,num2);
Swap1(num1, num2);
printf("swap1::num1 = %d num2 = %d\n", num1, num2);
return 0;
}
但此時的結(jié)果是什么呢?
![[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-SPPXxlHu-1642493097747)(../source/images/image-20220118152647618.png)]](http://img.jbzj.com/file_images/article/202201/202201190855479.png)
num1,num2值并沒有變啊,并沒有交換啊,為什么呢?
因為當實參傳給形參的時候,形參是實參的一份臨時拷貝,對形參的修改不會影響實參
我們來打印一下各變量的地址
![[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-AnfGU4Nm-1642493097749)(../source/images/image-20220118153528486.png)]](http://img.jbzj.com/file_images/article/202201/2022011908554710.png)
可以看到,實參有自己的地址,形參也有自己的地址,實參只把自己的值傳給了形參,地址各有各的,實參的地址上放的值并沒有變啊,并且形參在函數(shù)調(diào)用完后就自動銷毀了,也就是說函數(shù)內(nèi)與函數(shù)外的變量并沒有建立真正的實質(zhì)的聯(lián)系。就想象你copy了一個自己的仿生人,他吃了東西,進你的胃了嗎?肯定他吃他飽,跟你毫無相關(guān)是吧(狗頭
那么這個問題怎么解決呢?地址傳遞
#include <stdio.h>
//值傳遞
void Swap1(int x, int y) {
int tmp = 0;
tmp = x;
x = y;
y = tmp;
}
int main()
{
int num1 = 1;
int num2 = 2;
printf("交換前::num1 = %d num2 = %d\n",num1,num2);
Swap1(num1, num2);
printf("swap1::num1 = %d num2 = %d\n", num1, num2);
return 0;
}
? 我們來看一下結(jié)果

地址傳遞做了什么?
做地址傳遞時 函數(shù)參數(shù)是指針變量,指針變量里面裝著的就是地址嘛,所以實參直接就把自己的地址傳過去了,px里放的num1地址,py里放的num2地址, *px就是num1本身, *py就是num2本身,實參本身進行了賦值交換,這次不是你的仿生人了,就是你自己體驗人生。
我們看一下函數(shù)特征:如果傳入的實參是形參的指針,那就是地址傳遞。
其實有一個問題我好久才想明白:
為什么上一個例子(返回兩數(shù)中較大的一個)沒有用地址傳遞也成功了呢?這兩種方式使用的界限是什么呢?
后來這個疑問終于被解答了:
因為第一個例子里num1,num2的值并不需要改變,函數(shù)中x,y比較后如果返回x,x的值和a的值是一樣的,這個對結(jié)果是不影響的,也就是說,這種問題不需要改變實參的值,形參和實參不需要建立那么實質(zhì)的聯(lián)系
但要搞清楚的是,函數(shù)返回的是num1本身嗎?是num1地址上的值嗎?不,只是num1的拷貝x地址上的值。
綜上,在需要改變實參的值時一定要使用地址傳遞才行。
總結(jié)
到此這篇關(guān)于C語言值傳遞和地址傳遞詳解的文章就介紹到這了,更多相關(guān)C語言值傳遞 地址傳遞內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Linux下C語言的幾道經(jīng)典面試題小結(jié)(分享)
下面小編就為大家?guī)硪黄狶inux下C語言的幾道經(jīng)典面試題小結(jié)(分享)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-05-05
c++利用stl set_difference對車輛進出區(qū)域進行判定
這篇文章主要介紹了set_difference,用于求兩個集合的差集,結(jié)果集合中包含所有屬于第一個集合但不屬于第二個集合的元素,需要的朋友可以參考下2017-03-03
C語言中socket相關(guān)網(wǎng)絡(luò)編程函數(shù)小結(jié)
這篇文章主要介紹了C語言中socket相關(guān)網(wǎng)絡(luò)編程函數(shù)小結(jié),是C語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-09-09
C++基于遞歸和非遞歸算法判定兩個二叉樹結(jié)構(gòu)是否完全相同(結(jié)構(gòu)和數(shù)據(jù)都相同)
這篇文章主要介紹了C++基于遞歸和非遞歸算法判定兩個二叉樹結(jié)構(gòu)是否完全相同,若判斷二叉樹的結(jié)構(gòu)和數(shù)據(jù)都相同則為完全相同.涉及C++二叉樹的創(chuàng)建、遍歷、比較等相關(guān)操作技巧,需要的朋友可以參考下2017-05-05
Linux網(wǎng)絡(luò)編程之基于UDP實現(xiàn)可靠的文件傳輸示例
這篇文章主要介紹了Linux網(wǎng)絡(luò)編程之基于UDP實現(xiàn)可靠的文件傳輸示例,是很實用的技巧,需要的朋友可以參考下2014-08-08

