對 “C語言指標變數作為函式引數” 的個人理解
此文為自己的一些理解和看法,如有錯誤,請各位大佬指出。
C指標
C中每個變數都有一個記憶體空間,每一個記憶體空間都有自己的地址,我們可以對變數使用 & 來獲取變數地址,如下所示:
//執行程式碼
#include<stdio.h>
int main() {
int num = 1;
float fnum = 2.1f;
char letter = 'a';
printf("num 的地址為 %p\n", &num);
printf("fnum 的地址為 %p\n", &fnum);
printf("letter 的地址為 %p\n", &letter);
return 0;
}
//執行結果
num 的地址為 000000CE34B6FB54
fnum 的地址為 000000CE34B6FB74
letter 的地址為 000000CE34B6FB94
何為指標
指標是一個變數,它的值為另一個變數的地址,即,記憶體空間的直接地址。我們在使用指標儲存其他變數地址之前,先進行宣告。
DataType *ptr;
//DataType為變數型別,ptr為指標名稱
int *iptr; /*整型指標*/
float *fptr; /*float型指標*/
char *cptr; /*字元型指標*/
所有資料型別對應指標的值的型別都是一樣的,都是一個代表記憶體地址的十六進位制數。
不同資料型別的指標之間唯一的不同是,指標所指向的變數或常量的資料型別不同。
指標的使用
建立一個指標iptr儲存num的地址。其中對指標使用星號*獲取指標指向的值。
#include<stdio.h>
int main() {
int num = 1;
int* iptr = #
printf("變數 num 的值為 %d\n", num);
printf("指標 iptr 所指向的值為 %d\n", *iptr);
printf("變數 num 的地址為 %p\n", &num);
printf("指標 iptr 所儲存的地址為 %p\n", iptr);
return 0;
}
變數 num 的值為 1
指標 iptr 所指向的值為 1
變數 num 的地址為 000000A1E514F594
指標 iptr 所儲存的地址為 000000A1E514F594
函式引數
當呼叫函式時,把實參的值複製給形參,然後函式用形參來進行相關操作。在函式內形參的值變化並不會影響實參的值變化。
#include<stdio.h>
void test(int num) {
printf("test中 num的值為%d 地址為%p\n", num, &num);
}
int main() {
int num = 1;
printf("main中 num的值為%d 地址為%p\n", num, &num);
test(num);
return 0;
}
main中 num的值為1 地址為000000D6EA4FFC24
test中 num的值為1 地址為000000D6EA4FFC00
可以看出當函式呼叫時,形參只是複製了實參的值,它們的記憶體地址是不一樣的。
所以當形參改變自己的值時,相應的實參是不會變化的。
#include<stdio.h>
void test(int num) {
printf("test中 num的值為%d 地址為%p\n", num, &num);
num = 2;
printf("test中 num的值為%d 地址為%p\n", num, &num);
}
int main() {
int num = 1;
printf("main中 num的值為%d 地址為%p\n", num, &num);
test(num);
printf("main中 num的值為%d 地址為%p\n", num, &num);
return 0;
}
main中 num的值為1 地址為000000062894FA04
test中 num的值為1 地址為000000062894F9E0
test中 num的值為2 地址為000000062894F9E0
main中 num的值為1 地址為000000062894FA04
test函式內改變num的值時,是對形參num操作,因此實參num的值仍為1。
指標作為函式引數
為何函式需要指標作為引數呢?
從上面可以看出,當我們想用test函式對main中的num值進行修改時,其實main中的num是沒有變化的。如果我們想要通過函式操作改變main中num值時,該怎麼操作呢?這就需要指標來進行相關的操作,從而實現我們的需求(ps:當然我們也可以通過return返回我們需要的值)。
為什麼通過指標能修改實參值
我們通過下面的一個例子來說明
#include<stdio.h>
void test(int *num_ptr) {
printf("test中 num_ptr儲存的地址為%p 所指向的值為%d\n", num_ptr, *num_ptr);
*num_ptr = 2;
printf("test中 num_ptr儲存的地址為%p 所指向的值為%d\n", num_ptr, *num_ptr);
}
int main() {
int num = 1;
printf("main中 num的地址為%p 值為%d\n", &num, num);
test(&num);
printf("main中 num的地址為%p 值為%d\n", &num, num);
return 0;
}
main中 num的地址為000000943AB2F6B4 值為1
test中 num_ptr儲存的地址為000000943AB2F6B4 所指向的值為1
test中 num_ptr儲存的地址為000000943AB2F6B4 所指向的值為2
main中 num的地址為000000943AB2F6B4 值為2
此時test的實參為num的地址,形參num_ptr複製的是num的地址。雖然在函式中對形參的值進行改變時,實參不會受到影響。但有趣的是,num_ptr的值是地址,當我們通過修改此指標指向的內容時,num_ptr還是儲存的是num的地址,num的地址沒有收到影響但num值已經改變。
舉個例子,把實參當一把鑰匙,形參當做另外配的鑰匙。
在函式內你重新改造形參鑰匙(即更改內容),實參鑰匙沒有影響。
如果這時候有一個房間,實參是房間的鑰匙(指標為鑰匙,指向的記憶體為房間),由於形參鑰匙與實參鑰匙一樣,故通過形參鑰匙可以修改房間的佈局(修改指向的記憶體內容)。當函式執行完後,形參鑰匙被丟棄,房間佈局已改變。
如果拿到形參鑰匙,對鑰匙進行改造,形參鑰匙就只能開另外一個房間。而原房間不受影響。
一句話
形參只是複製實參的值,形參如何變化不管實參的事。但形參通過指標修改指向的內容,就會影響實參所指向的內容,雖然此時形參和實參的值一樣。
相關文章
- C語言_結構體變數指標做函式引數的使用案例C語言結構體變數指標函式
- 關於C++引用做為函式引數和指標作為函式引數C++函式指標
- C語言函式傳遞指標引數的問題詳解C語言函式指標
- C語言指標(二) 指標變數 ----by xhxhC語言指標變數
- GO語言————6.7 將函式作為引數Go函式
- Go語言Slice作為函式引數詳解Go函式
- C語言 函式指標C語言函式指標
- C語言 將函式(有參、無參)作為引數傳遞C語言函式
- C/C++—— 寫一個函式,它的引數為指向函式的指標,返回型別也為指向函式的指標C++函式指標型別
- C++智慧指標作為成員變數C++指標變數
- C語言函式指標基礎C語言函式指標
- 【C語言】函式的概念和函式的呼叫(引數傳遞)C語言函式
- C語言第九周作業(指標變數,記憶體訪問,取址,空指標)C語言指標變數記憶體
- 物聯網學習教程— 字元指標作函式引數字元指標函式
- C語言函式指標與回撥用函式C語言函式指標
- C++ 函式的可變引數C++函式
- C語言關於指標,gets()和gets_s()函式的理解C語言指標函式
- 函式作為引數傳遞函式
- 物件,函式作為一個函式的引數物件函式
- 巨集_變數_函式_指標_標頭檔案變數函式指標
- C語言用二維陣列作為函式入口引數的小結C語言陣列函式
- C#的Replace函式,使用函式作為的引數需要注意C#函式
- C語言可變引數詳解C語言
- python高階函式和C語言函式指標Python函式C語言指標
- C語言putenv()函式:改變或增加環境變數C語言函式變數
- [ASM C/C++] C語言函式的可選性自變數ASMC++C語言函式變數
- 使用java模擬scala函數語言程式設計將函式作為引數傳入方法中Java函數程式設計函式
- C語言_指標變數的賦值與運算,很詳細C語言指標變數賦值
- C可變引數函式 實現函式
- 我對函數語言程式設計的理解函數程式設計
- C語言getenv()函式:取得環境變數內容C語言函式變數
- C語言函式指標與回撥函式使用方法C語言函式指標
- 函式不能返回區域性指標變數函式指標變數
- js函式作為函式的引數程式碼例項JS函式
- C語言中的 static變數、static函式C語言變數函式
- Swift 1.1語言函式引數的特殊情況本地引數名外部引數名Swift函式
- 傳遞指標引數(函式內部給指標賦值)示例指標函式賦值
- C語言函式手冊:c語言庫函式大全|C語言標準函式庫|c語言常用函式查詢C語言函式