文章目錄
本文涉及到的代碼是C寫的,但是在C++上一樣適用
0.背景知識–堆和棧的理解
堆和棧的學習:https://blog.csdn.net/pt666/article/details/70876410
個人理解:(可能有不準確的地方,歡迎指正)
1.當我們在程序中初始化一個變量的時候,首先在棧內存裏面建立一個叫age的變量,存儲下來
2.系統然後在堆內存中,開闢一塊空間,存儲具體的值19,例如內存地址爲:0fxx02
3.然後棧內存變量age的值即爲ofxx02這個地址值
4.程序如果想調用age的時候,直接先找個變量的地址,然後再去這個地址找對應的值
1.C中對變量賦值的理解
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
int main(void)
{
int age = 20;
printf("age = %d\n", age);
printf("age的地址:%p\n", &age);
age = 30;
printf("age = %d\n", age);
printf("age的地址:%p\n", &age);
}
// 如上的結果爲:
age = 20
age的地址:006FFD04 #
age = 30
age的地址:006FFD04
以上代碼解析:
-
1.最初的時候,age存儲的情況
-
2.後續程序對變量重新賦值,相當於把之前存20值的內存地址006FFD04,重新存儲爲30.(隱藏的含義是內存地址不變,值改變了!)
2.指針和內存地址的理解
指針,是C語言中的一個重要概念及其特點,也是掌握C語言比較困難的部分。指針也就是內存地址,指針變量是用來存放內存地址的變量,不同類型的指針變量所佔用的存儲單元長度是相同的,而存放數據的變量因數據的類型不同,所佔用的存儲空間長度也不同.
- &用來取一個變量的地址
- * 用來取一個地址(指針)的值
1.case1:獲取變量的地址和指針的值
#include <stdio.h>
int main(void)
{
int age = 19;
int* p_age = &age;
printf("age 的地址爲: %p\n", &age);
printf("* p_age 指針的值:%d\n", *p_age);
}
age 的地址爲: 008FFE98
* p_age 指針的值:19
2.case2:對指針的值重新賦值
#include <stdio.h>
int main(void)
{
int age = 19;
int* p_age = &age;
printf("age 的地址爲: %p\n", &age);
printf("* p_age 指針的值:%d\n", *p_age);
*p_age = 20;
printf("age 的地址爲: %p\n", &age);
printf("* p_age 指針的值:%d\n", *p_age);
printf("age的值爲:%d\n", age);
}
age 的地址爲: 009FF898
* p_age 指針的值:19
age 的地址爲: 009FF898
* p_age 指針的值:20
age的值爲:20
難理解的是,爲什麼第二次打印*p_age是20:
1.因爲p_age指針已經指向了age變量的內存地址,即int p_age = &age
2.所以 p_age相當於是堆內存的地址,*p_age = 20 ,就是上面講到的賦值的原理過程。
3.三種參數傳遞方式:
參考:https://blog.csdn.net/cocohufei/article/details/6143476
1.按值傳遞參數(不推薦)
按值傳遞的過程爲:首先計算出實參表達式的值,接着給對應的形參變量分配一個存儲空間,該空間的大小等於該形參類型的,然後把以求出的實參表達式的值一一存入到形參變量分配的存儲空間中,成爲形參變量的初值,供被調用函數執行時使用。這種傳遞是把實參表達式的值傳送給對應的形參變量,故稱這種傳遞方式爲“按值傳遞”。(我讀了好幾遍,是不是感覺有點拗口,其實就是我上面說的賦值的過程)
#include <stdio.h>
void swap(int i, int n)
{
int t;
t = i;
i = n;
n = t;
printf("%d %d\n", i, n);
printf("%p %p\n", &i, &n);
}
int main()
{
int i = 20, n = 30;
printf("%p %p\n", &i, &n);
printf("===================\n");
swap(i, n);
printf("===================\n");
printf("%d %d\n", i, n);
return 0;
}
// 結果如下:
006FF958 006FF94C
===================
30 20
006FF874 006FF878
===================
20 30
- 調用swap函數本身沒有對原始實參進行操作,只有原始實參對應的地址或對應的值變動了,纔算對原始實參操作了。
- 雖然在swap函數中形參i, n發生了變化,但對swap函數執行完回收了形參i,n,main函數的實參i,n仍爲調用前的值
2.按地址傳遞參數(感覺很NB,但不實用,特殊場合除外)
#include <stdio.h>
void swap(int*, int*); # 定義的2個變量是,需要傳遞的爲指針,即地址的值
int main()
{
int a = 20, b = 30;
printf("a = %d ,b=%d \n", a, b);
swap(&a, &b);
printf("a = %d ,b=%d \n", a, b);
system("pause");
return 0;
}
void swap(int* x, int* y)
{
int t = *x;
*x = *y;
*y = t;
}
a = 20 ,b=30
a = 30 ,b=20
3.引用傳遞參數(C++專享,C不支持)
有關這個,請移步我的另一篇博文:
https://blog.csdn.net/chenmozhe22/article/details/106116120
學習文章:https://www.cnblogs.com/lulipro/p/7460206.html#commentform