為了弄明白加了_ _Block之后,為什么局部變量就可以在Block內部修改了的問題,先要明白值傳遞,地址傳遞和引用傳遞,才能清楚問題所在。這篇文章就是為了說明白這幾種傳遞到底是怎么回事的。
我們新建一個控制臺應用程序,如下圖:
image.png
為了使用取地址符號,我們把main函數的后綴名改了,改成main.mm,這樣編譯就不會報錯了。
int test1(int a); 值傳遞
int test2(int *a); 地址傳遞
int test3(int &a);引用傳遞
先看源碼:
//
// main.c
// BlockDTest
//
// Created by wenhuanhuan on 2020/7/4.
// Copyright ? 2020 weiman. All rights reserved.
//
#include <stdio.h>
int test1(int a);
int test2(int *a);
int test3(int &a);
int main(int argc, const char * argv[]) {
int num1 = 10;
printf("傳遞前:num1地址: %p\n", &num1);
int r1 = test1(num1);
printf("r1 = %d num1 = %d\n\n", r1, num1);
int num2 = 10;
printf("傳遞前:num2地址: %p\n", &num2);
int r2 = test2(&num2);
printf("r2 = %d num2 = %d\n\n", r2, num2);
int num3 = 10;
printf("傳遞前:num3地址: %p\n", &num3);
int r3 = test3(num3);
printf("r3 = %d num3 = %d\n\n", r3, num3);
return 0;
}
//值傳遞
int test1(int a) {
printf("test1 參數地址a = %p\n", &a);
a = 20;
return a;
}
//地址傳遞
int test2(int *a) {
printf("test2 參數地址a = %p, *a = %p\n", &a, &(*a));
*a = 20;
return *a;
}
//引用傳遞
int test3(int &a) {
printf("test3 參數地址a = %p\n", &a);
a = 20;
return a;
}
看看打印結果:
image.png
通過比較傳遞前后,參數與原來變量的地址,我們發現如下結果:
- 值傳遞:參數與原來地址不一致,參數值的更改不影響原來值。
- 地址傳遞:參數是傳遞的地址,此地址與原來值的地址一致,參數的修改會影響原來的值。
- 引用傳遞:參數傳遞的就是原來值的地址,修改地址中的值,會對原來的變量造成影響。
如果你覺得代碼看起來費勁,闡述看起來費眼,好的,我們再來畫張圖。
image.png
image.png
上圖中,a是一個指針,指向num2的地址。
&a和*a有什么不同呢?
*a是一個指向某個地址的指針。
&a是一個引用,引用就是指針,兩者沒有區別。我們可以把引用想象成一個不需要" * "就可以訪問變量的指針。
image.png
引用傳遞,參數的地址與原來變量的地址是一樣的,所以更改參數的值,變量的值也會跟著改變。