C語言中函式呼叫,為什麼交換了地址,可是所指的值還是不變那

時間 2021-10-14 23:03:19

1樓:匿名使用者

#include

void swap(int *a,int *b)

int t=0;

t=*a;

*a=*b;

*b=t;

int main()

int x=3,y=5;

int *p=&x,*q=&y;

swap(p,q);

printf("%d %d\n",*p,*q);

printf("%d %d\n,a,b);  //看看是不是 a,b也改變了!~!

你那個錯誤,我的估計: 你可以用vc++單步調式一下.也可以完全理解的.

p=&x  就是把  x的地址儲存在 指標 p中.  *p 就是得到  值. *p=3.

q也差不多.

你下面  sqap(p,q) . 就是把地址傳過去了.

可是傳回來的值沒有改變,為什麼呢!

原因很簡單.

因為你的

int *t;

int*t;

t=a;a=b;b=t;

交換的是  a和b 的地址.

不要忘記了,當呼叫一個函式時.

os會為  swap 函式中的  int *a,int *b.開闢記憶體.

你改變的是swap開闢的記憶體.並沒有改變 main中的*p和*q記憶體區域.

我再說清楚點.

p 儲存的是 &a    q儲存的是  &b

swap函式   a 儲存的也是 &a    b儲存的也是&b

你用交換了 a和b的 地址.有什麼用.沒有改變原來的地方的地址.

只是改變了你自己的 a 和 b裡面的地址.   沒有改變那邊的 真正的  3 和 5.

如果用了

int t;

t=*a;

*a=*b;

*b=t;

就是間接去改變那邊的值.

通過裡面 &a,&b,的地址來找到  真是的 3,5  然後就改變了.

2樓:

你對函式呼叫和引數傳遞還不是很理解

1.首先函式呼叫的引數有形參和實參之分

swap(p,q);//p q為實參

void swap(int*a,int*b)//a b為形參

2.指標變數名錶示的是變數的值,這個值是其他變數的地址,而不是指標變數本身所在記憶體空間的地址

如:int a;//定義整型變數,假設其地址為0xaaaaaaaa

int *p;//定義一個指標變數p,肯定要為其分配記憶體,假設為0xffffffff,還沒初始化,裡面的資料是不確定的。

p=&a;//p表示的0xffffffff裡面的資料,是a的地址,執行後0xffffffff裡面的資料變成a的地址,即0xaaaaaaaa

*p=5;//往a裡寫入資料

3.形參跟實參是不同的變數,佔用不同的記憶體空間

所以a b已經是兩個跟p q不同的變數了。

只不過是值跟他們相等罷了。

就如int m,n;

m=n; 你能說m和n是同個變數麼?

4.既然形參和實參是不同的變數,

t=a;a=b;b=t;

交換a b的值(交換儲存在a b指標變數裡的資料,這個資料是地址,變成a跟q指向同一個物件,b q指向同一個物件)不會影響到p q的值

int t;

t=*a;*a=*b;*b=t;//交換a b指標變數裡的地址所指向的資料,這樣才能交換。

3樓:軍軍

你的程式是值傳遞方式,形參的改變不影響實參,即a、b值改變了但p、q的值並未變化。

4樓:匿名使用者

*p是一個不定的值,這個是將x的地址交給了p所指的值,*q也是一個不定的值,將y的地址交給我q所指的值。交換的只是p和q和地址,它們所指的值還是沒有變的啊

5樓:心千言

你呼叫子函式了,但是子函式沒有返回值,呼叫完就沒了,對主函式沒影響的

6樓:匿名使用者

完全不是那麼回事!!

你函式裡面應該是交換地址所指的內容,地址本身是個型參,你這樣做結果就跟你傳值是一樣的效果了

這樣改吧

void swap(int*a,int*b)如果你要修改指標 則應該傳入指標的地址 如下:

void swap(int**a,int**b)swap(&p, &q);

7樓:

*t=*a; *a=*b; *b=*t;

任何引數都是傳值 你那麼寫 區域性指標的地址交換了 但是不影響main裡的指標

8樓:

這說明你對函式呼叫,形參和實參這塊還是沒掌握好,函式呼叫只是你p,q作為形參傳了過去,也就是a,b首先得到了p,q地址,然後a,b地址交換。但是p,q本身沒變,這樣你主函式裡呼叫沒有返回值的swap()函式,結果讓輸出p,q當然沒變化了,

可以這樣修改:你把地址交換過程在主函式裡實現,不呼叫。這樣不需返回值直接能交換p,q。或是像一樓那樣改的,在裡面實現數值重新複製也行。

9樓:

main函式中

指標變數 p的值是 變數x的地址 ,即p指向x指標變數 q的值是 變數y的地址 ,即q指向ymain函式 呼叫swap函式傳入的引數 是 p 和q ,是以傳遞值的方式呼叫的

swap函式的形參 a和 b也是 指標變數 ,呼叫 是a的值等於 p的值 ,b的值等於 q的值即 a 指向main函式中的變數x

b 指向main函式中的變數y

swap函式 交換 a 與b的值

交換前 a指向x,b指向y;交換 後 a就指向了y,而b指向了xa b的交換 並沒有 改變 main函式中 p 和q的指向!

改為#include

void swap(int **a,int **b) //形參改為指向指標的指標

main()

10樓:匿名使用者

發生改變的只是a b的地址。。。

c語言中呼叫函式交換兩個變數的值需要傳遞地址,為什麼相加就可以直接用

11樓:知e自動化

舉個栗子:

有100個房間,從0到99編號,每個房間放在不同的食材。

交換兩個變數的值

只需要告訴你把a房間和b房間的東西調換,你不需要知道房間裡面放的是什麼。只需要知道ab的房間號;

加法:如果問你a房間和b房間裡的食材可以做什麼菜,你就需要知道ab房間分別放了什麼。不需要知道房間號。

c語言 寫一個函式交換兩個數的值,為什麼一定要用指標?

12樓:娛樂小八卦啊

運用**解釋指標運用的理解如下:

#include

using namespace std;

int fun1 (int a,int b)

int c;

c=a;a=b;b=c;

cout<<"a1:"

int *c;

c=a;a=b;b=c;

cout<<"a2:"<<*a<<";b2:"<<*b

int *c;

c=*a;*a=*b;*b=c;

cout<<"a3:"<<*a<<";b3:"<<*b

int c;

c=*a;*a=*b;*b=c;

cout<<"a4:"<<*a<<";b4:"<<*b

int c;

c=a;a=b;b=c;

cout<<"a5:"

int aa=1,bb=2;

fun1(aa,bb);

cout<<"aa1:"

cout<<"aa2:"

cout<<"aa3:"

cout<<"aa4:"

fun5(aa,bb);

cout<<"aa5:"

輸出結果為:

a1:2;b1:1

aa1:1;bb1:2

a2:2;b2:1

aa2:1;bb2:2

aa3:1;bb3:2

a4:2;b4:1

aa4:2;bb4:1

a5:2;b5:1

aa5:2;bb5:1

main中呼叫fun1()時,將實參a,b的值傳遞給了交換函式,如果此時在swap1中列印,可以看到結果是正確的,但是該過程其實是將aa和bb分別複製了一份給了函式,執行完fun1()之後,aa和bb的值沒有任何變化。

fun2(),看似的確使用了指標,但還是失敗,因為這裡是將aa和bb的地址給交換了,而並沒有交換aa和bb的值。在這裡由於未給c賦值,c中並沒有確定的值,c中的值是不可預見的。此時c可能指向一個未知的儲存單元。

而嚴重的情況是,該單元的資料可能是有用的,因此fun2()不但沒有實現兩個數的交換,反而給系統的穩定性帶來威脅。

fun3(),將int賦值給int *,編譯錯誤。

fun4()是正確的。為了在函式中改變了的變數能被其它函式呼叫,正確的辦法是用指標變數作為函式引數,在函式執行過程中使指標變數所指向的變數值發生變化。

函式呼叫結束後,哲別變數值的變化依然保留下來,這樣就實現了通過函式呼叫是變數的值發生變化,在其它函式中可以使用這些改變了的值的目的。

fun5()也是正確的,這是引用的重要應用之一。對於引用的操作實際上是作用在引用所因的物件上。

擴充套件資料

在函式中的引數,並不是呼叫者的變數,而是臨時申請的變數a和b存放main函式中變數a和b的值,並在函式中用來計算,在fun中給a和b賦值都是在操作這兩個臨時申請的變數,函式返回後,這兩個變數被捨棄,函式呼叫也沒有將這兩個臨時變數的值返回給main函式中呼叫使用的引數功能。

所以,在函式中要操作呼叫者申請的變數,需要給出它們的指標,函式中用指標來找到這些變數的位置和內容。

13樓:匿名使用者

void swap(int *xx,int *yy)上面這種才可以。

你的兩個方法中,第一種方法,雖然引數是指標,但是作為引數的指標也還是臨時複製的,你在方法裡互換操作的是臨時指標而不是指標指向的內容

第二種方法,引數是兩個int變數,但作為引數這兩個變數只是臨時複製了一份,操作這兩個複製的臨時值並不能改變本體。

14樓:

c語言轉換變數的值,並不是直接轉換,而是通過反覆賦值進行值的覆蓋;有三種轉換方式,傳值,傳址,傳引用。如果不用指標,將b值符給a後,a,b的值是一樣的,a值的儲存地址不變,輸出時還是a值;而用指標後,通過指標指向地址,可進行地址層面的轉換,輸出電腦以為的a時,其實是b的地址上的b值才將兩個變數的值完全交換,此為傳址轉換。

15樓:

因為給函式引數分配的空間是臨時的 用完就被**了。

c語言,在fun函式裡,if語句裡傳遞的不是指標陣列的地址嗎,並沒有改變指標陣列所指的值那為什麼錯了?

16樓:匿名使用者

指標陣列是一系列指標單元組成的陣列,每個指標單元存放了一個地址指向具體字串,if裡面把兩個指標單元的值(也就是具體字串的首地址)給交換了,你再引用這個指標的時候,它指向了另一個字串。

17樓:匿名使用者

改變值了啊,s[i] = s[j]就把i和j位置對於的字串換了位置,至於為什麼fun函式中改變了字元陣列值,會影響到了mian函式中的字元陣列值,就是因為指標傳的是地址,而不是原陣列的副本,傳地址就會影響到原來的值,傳原值的副本就不會影響到原值

c語言中如何函式的多次呼叫,c語言中如何乙個函式的多次呼叫

乙個函式只能有乙個返回值,指標可以返回多個,例如 void aaa int a,c int a,c a a c c a b c b 下面呼叫 a和 c.1.可以使用迴圈語句實現。例如while迴圈語句,計算機的一種基本迴圈模式。當滿足條件時進入迴圈,不滿足跳出。while語句的一般表示式為 whil...

請問C語言中函式定義,函式宣告和函式呼叫的區別

函式宣告指函式原型宣告,只有函式名,函式型別,引數個數和型別,無函式體。一般放在主函式前。逗號結尾。函式定義,除上述外,去掉結尾逗號,加函式體。可放在main函式後面,也可放在main函式前面。放在main函式前面則不要寫函式原型宣告。 雲澹楓卿 函式宣告格式如 int max int 函式呼叫是你...

關於c語言指標呼叫函式,關於C語言中指向函式的指標的呼叫問題

第一條紅線是定義乙個函式指標 第二條紅線起強轉作用,把0xd010f0強轉為對應的函式指標型別 我寫的這個程式可以幫你理解.常量位址被printab取代 劃紅線的是宣告了乙個函式指標,這個函式的兩個引數和返回值都是int,然後將0xd 的位址強制轉換為函式啊 同下面類似 typedef int fu...