網站首頁 編程語言 正文
一. 值傳遞
我們舉一個例子:
寫一個函數找出兩個整數中的最大值。
#include<stdio.h> //get_max函數 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; }
運行結果是:
max = 20
我們來分析一下這個函數調用過程:
num1,num2作為實參傳入get_max()函數,形參x,y被實例化(分配內存單元),num1和num2的值按照函數形參表順序對應地傳給了x和y,也就是x=10,y=20,然后函數將x和y中較大的一個的值返回。函數調用完畢,x和y被自動銷毀。
我們看一下函數的特征,如果函數的形參和實參一致,這就是值傳遞。
二.地址傳遞
再舉一個例子:
寫一個函數交換兩個整形變量的內容。
很多初學者一看覺得太簡單了,按照值傳遞我們來寫一遍。
#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; }
但此時的結果是什么呢?
num1,num2值并沒有變啊,并沒有交換啊,為什么呢?
因為當實參傳給形參的時候,形參是實參的一份臨時拷貝,對形參的修改不會影響實參
我們來打印一下各變量的地址
可以看到,實參有自己的地址,形參也有自己的地址,實參只把自己的值傳給了形參,地址各有各的,實參的地址上放的值并沒有變啊,并且形參在函數調用完后就自動銷毀了,也就是說函數內與函數外的變量并沒有建立真正的實質的聯系。就想象你copy了一個自己的仿生人,他吃了東西,進你的胃了嗎?肯定他吃他飽,跟你毫無相關是吧(狗頭
那么這個問題怎么解決呢?地址傳遞
#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; }
? 我們來看一下結果
地址傳遞做了什么?
做地址傳遞時 函數參數是指針變量,指針變量里面裝著的就是地址嘛,所以實參直接就把自己的地址傳過去了,px里放的num1地址,py里放的num2地址, *px就是num1本身, *py就是num2本身,實參本身進行了賦值交換,這次不是你的仿生人了,就是你自己體驗人生。
我們看一下函數特征:如果傳入的實參是形參的指針,那就是地址傳遞。
其實有一個問題我好久才想明白:
為什么上一個例子(返回兩數中較大的一個)沒有用地址傳遞也成功了呢?這兩種方式使用的界限是什么呢?
后來這個疑問終于被解答了:
因為第一個例子里num1,num2的值并不需要改變,函數中x,y比較后如果返回x,x的值和a的值是一樣的,這個對結果是不影響的,也就是說,這種問題不需要改變實參的值,形參和實參不需要建立那么實質的聯系
但要搞清楚的是,函數返回的是num1本身嗎?是num1地址上的值嗎?不,只是num1的拷貝x地址上的值。
綜上,在需要改變實參的值時一定要使用地址傳遞才行。
總結
原文鏈接:https://blog.csdn.net/qq_52150515/article/details/122562195
- 上一篇:C#實現學生檔案查詢_C#教程
- 下一篇:C語言運算符的重載詳解_C 語言
相關推薦
- 2022-11-07 關于react?父子組件的執行順序_React
- 2022-12-09 C++中利用cout和fstream采用非科學計數法輸出_C 語言
- 2022-02-23 在項目中全局自動加載默認圖的技巧
- 2021-12-12 linux縮減XFS分區格式的根目錄_Linux
- 2022-09-26 go使用makefile腳本編譯應用的方法小結_Golang
- 2022-04-28 WPF使用WrapPanel環繞面板布局_實用技巧
- 2023-11-22 Linux下設置環境變量
- 2022-07-28 XML基本概念XPath、XSLT與XQuery函數介紹_XML/RSS
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支