[英]confusion in passing a pointer to function in C
我試圖理解 C 中的指針並編寫了這段代碼
#include <stdio.h>
int swap(int *fa,int *fb){
int temp = *fa;
*fa = *fb;
*fb = temp;
}
int main(){
int a=5,b=7;
int *pa = &a;
int *pb = &b;
swap(pa,pb);
printf("%d\n",*pa);
printf("%d\n",*pb);
printf("%d\n",a);
printf("%d",b);
}
現在輸出(如預期)是
7
5
7
5
我對正在發生的事情有一點了解,但我有一個困惑
fa = pa // fa points to what pa points to which means a
fb = pb // fb points to what pb points to which means b
這是正在發生的事情嗎
或者是 fa 和 fb 首先影響 pa 和 pb,依次影響 a 和 b。
- 在我調用交換函數之后,就會發生這種情況
fa = pa // fa points to what pa points to which means a
fb = pb // fb points to what pb points to which means b
如果您的意思是在進入swap
之后,那么是。 那是正確的。 參數作為副本傳遞,這意味着在函數fa
和fb
內部從調用者那里獲取pa
和pb
的副本。
- 我們交換 fa 和 fb 的值,然后交換 a 和 b 的值,因為 pa 和 pb 指向 a 和 b,它們也指向這些新值。
號fa
和fb
根本沒有接觸。 它們被取消引用。 這意味着,它們指向的地址會受到影響。 您可以使用printf
打印這些指針變量的內容。 他們不會改變。 而是更改了a
和b
的內容。
順便說一句:你的printf
語句沒有多大意義。 您應該在函數調用之前和之后打印以查看任何效果。
對於初學者,請注意您的返回類型為int
函數swap
返回任何內容。
int swap(int *fa,int *fb){
返回類型int
沒有意義。
該函數可以聲明為
void swap(int *fa,int *fb);
函數 swap 不交換其參數的值。
int swap(int *fa,int *fb){
int temp = *fa;
*fa = *fb;
*fb = temp;
}
它交換參數對象所指向的對象,因為在函數中使用了取消引用指針的表達式,例如
*fa
或*fb
。
這是一個演示程序,它表明指針fa
和fb
的值沒有改變。
#include <stdio.h>
void swap(int *fa,int *fb){
printf( "fa = %p, fb = %p\n", ( void * )fa, ( void * )fb );
int temp = *fa;
*fa = *fb;
*fb = temp;
printf( "fa = %p, fb = %p\n", ( void * )fa, ( void * )fb );
}
int main(void)
{
int a=5,b=7;
int *pa = &a;
int *pb = &b;
swap(pa,pb);
return 0;
}
程序輸出可能看起來像
fa = 0x7ffff85444f0, fb = 0x7ffff85444f4
fa = 0x7ffff85444f0, fb = 0x7ffff85444f4
正如所見,指針在函數的開頭和結尾具有相同的值。 交換的是指向對象的值。
並且指針fa
和fb
不影響 main 中聲明的指針pa
和pb
。 因為作為函數局部變量的指針fa
和fb
獲得了存儲在指針pa
和pb
中的值的副本。
當您將指針傳遞給您的函數時,您傳遞了一個包含地址的變量。 當您取消引用 fa(或 fb)時,您將獲得該地址的實際值。 所以當你修改它時,你修改了兩個指針的值,因為它們指向同一個地址。
為了更好地理解指針,您可以使用實際的假地址。 假設變量“a”存儲在 RAM 中的地址 0x9000,變量“b”存儲在地址 0x10000。
#include <stdio.h>
int swap(int *fa,int *fb){ //fa and fb are variables of type pointer which contain 0x9000 and 0x10000 respectively
int temp = *fa; //temp contains the content of address 0x9000 (a)
*fa = *fb; //address 0x9000 contains content of address 0x10000 (b)
*fb = temp; //address 0x10000 contains content of temp (a)
}
int main(){
int a=5,b=7;
int* pa = &a; //pa is a variable of type pointer which contains 0x9000
int* pb = &b; //pb is a variable of type pointer which contains 0x10000
swap(pa,pb);
}
不要忘記 int* 是一個指向 int 的指針類型的變量。 這意味着該變量包含一個 int 類型變量的地址。 實際上它只是指向內存。 你可以寫類似的東西
int* a = 0x9000;
您將有一個 int 類型的指針指向地址 0x9000。 這將是有效的語法,但您的操作系統會抱怨您無權訪問該地址。 如果你寫
long* a = 0x9000;
唯一的區別是取消引用時獲得的字節數。 當您取消引用一個指針時,您將獲得該類型包含的字節數。 對於 int* 類型,當您取消引用時,您將獲得從地址 0x9000 開始的 4 個字節(32 位)。 使用 long* 類型,您將獲得從地址 0x9000 開始的 8 個字節(64 位)。
int* 或 long* 類型變量的大小是相同的,因為這僅取決於 CPU 的架構。 因此,使用這兩種方法,您將獲得一個大小相同的指針類型變量。 唯一的區別是取消引用時獲得的字節數。
我們交換 fa 和 fb 的值,然后交換 a 和 b 的值,因為 pa 和 pb 指向 a 和 b,它們現在指向這些新值。
不 - 你交換fa
和fb
指向的值,分別是a
和b
。 fa
和fb
的值(以及pa
和pb
)永遠不會改變。
我修改了你的代碼如下:
#include <stdio.h>
#include <stdlib.h>
void swap(int *fa,int *fb){
printf( "Entering swap: fa = %p, fb = %p, *fa = %d, *fb = %d\n", (void *) fa, (void *) fb, *fa, *fb );
int temp = *fa;
*fa = *fb;
*fb = temp;
printf( "Leaving swap: fa = %p, fb = %p, *fa = %d, *fb = %d\n", (void *) fa, (void *) fb, *fa, *fb );
}
int main(){
int a=5,b=7;
int *pa = &a;
int *pb = &b;
printf( "Before swap: a = %d, b = %d, pa = %p, &a = %p, pb = %p, &b = %p, *pa = %d, *pb = %d\n",
a, b, (void *) pa, (void *) &a, (void *) pb, (void *) &b, *pa, *pb );
swap(pa,pb);
printf( "After swap: a = %d, b = %d, pa = %p, &a = %p, pb = %p, &b = %p, *pa = %d, *pb = %d\n",
a, b, (void *) pa, (void *) &a, (void *) pb, (void *) &b, *pa, *pb );
return EXIT_SUCCESS;
}
運行時,它給出輸出1 :
Before swap: a = 5, b = 7, pa = 0x7ffee8f43a60, &a = 0x7ffee8f43a60, pb = 0x7ffee8f43a5c, &b = 0x7ffee8f43a5c, *pa = 5, *pb = 7
Entering swap: fa = 0x7ffee8f43a60, fb = 0x7ffee8f43a5c, *fa = 5, *fb = 7
Leaving swap: fa = 0x7ffee8f43a60, fb = 0x7ffee8f43a5c, *fa = 7, *fb = 5
After swap: a = 7, b = 5, pa = 0x7ffee8f43a60, &a = 0x7ffee8f43a60, pb = 0x7ffee8f43a5c, &b = 0x7ffee8f43a5c, *pa = 7, *pb = 5
所以,我們可以看到以下都是正確的:
fa == pa == &a
*fa == *pa == a == 5 // before swap, 7 after swap
fb == pb == &b
*fb == *pb == b == 7 // before swap, 5 after swap
fa
和pa
以及&a
都是相同的值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.