0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C語言指針作為形參怎么改變其指向的地址

Q4MP_gh_c472c21 ? 來源:ERYUESANHI ? 作者:ERYUESANHI ? 2021-10-09 11:54 ? 次閱讀

就是一個(gè)函數(shù)的輸入參數(shù)是一個(gè)指針,該函數(shù)需要改變該指針指向的地址,如: 現(xiàn)在有一個(gè)全局?jǐn)?shù)組b,現(xiàn)在需要編寫一個(gè)函數(shù) 輸入?yún)?shù)是一個(gè)指針a,需要通過該函數(shù)將該指針a指向數(shù)組b,即:

intb[3]={1,2,3};

voidfcn(參數(shù));

voidmain()
{
int*a;
fcn(輸入?yún)?shù)a)

}

執(zhí)行完fcn后,使參數(shù)的地址改變,這個(gè)功能怎么來實(shí)現(xiàn)呢?

首先說明結(jié)論:使用二級指針。

為了更好的理解這個(gè)問題,我們首先來學(xué)習(xí)一下指針最經(jīng)典的例子,交換兩個(gè)數(shù)來說明函數(shù)的形參和實(shí)參之間的關(guān)系。

首先來探究以下實(shí)參和形參的關(guān)系是怎樣的。

形參為普通變量類型;

voidtest1(inta,intb)
{
printf(">>formaladdra:%d,formaladdrb:%d
",&a,&b);//打印形參地址
printf(">>formalvaluea:%d,formalvalueb:%d
",a,b);//打印形參值
}

intmain()
{
inta=1,b=2;

printf(">>actualaddra:%d,actualaddrb:%d
",&a,&b);
printf(">>actualvaluea:%d,actualvalueb:%d
",a,b);
test1(a,b);

return0;
}

下面是執(zhí)行結(jié)果:

>>actualaddra:6422300,actualaddrb:6422296
>>actualvaluea:1,actualvalueb:2
>>formaladdra:6422272,formaladdrb:6422276
>>formalvaluea:1,formalvalueb:2

可以看到形參和實(shí)參的值雖然相同,但是他們的地址卻不相同,所以函數(shù)在被調(diào)用的時(shí)候傳入的參數(shù)(實(shí)參)實(shí)際上是被復(fù)制到另一個(gè)地址(形參地址)中去了,函數(shù)中對傳入?yún)?shù)的操作實(shí)際上是對形參地址中的數(shù)進(jìn)行操作,而與實(shí)參無關(guān)。所以下面的函數(shù)不能實(shí)現(xiàn)交換兩個(gè)數(shù)的功能。

voidswap_1(inta,intb)
{
inttemp;
temp=a;
a=b;
b=temp;
printf(">>formaladdra:%d,formaladdrb:%d
",&a,&b);
printf(">>formalvaluea:%d,formalvalueb:%d
",a,b);
}

intmain()
{
 int a = 1, b = 2;
swap_1(a,b);
printf(">>actualaddra:%d,actualaddrb:%d
",&a,&b);
printf(">>actualvaluea:%d,actualvalueb:%d
",a,b);
return0;
}

輸出如下:

>>formaladdra:6422272,formaladdrb:6422276
>>formalvaluea:2,formalvalueb:1
>>actualaddra:6422300,actualaddrb:6422296
>>actualvaluea:1,actualvalueb:2

可以看到在swap_1函數(shù)中a,b兩個(gè)數(shù)的值是被調(diào)換了的,但是函數(shù)中的a,b的地址和主函數(shù)中a,b的地址根本不是同一個(gè),主函數(shù)中a,b還是原來的數(shù),所以這個(gè)函數(shù)起不到交換兩個(gè)數(shù)功能。

既然形參和實(shí)參的關(guān)系是地址不同而值相同那么我們將實(shí)參的地址當(dāng)作參數(shù)傳給形參,然后在函數(shù)中對形參所指向的地址中的值(該地址就是實(shí)參的地址)進(jìn)行改變是否就可以完成兩個(gè)數(shù)的交換了?

OK!下面我們來編寫函數(shù)測試以下:

voidswap_2(int*a,int*b)
{
inttemp;
printf(">>formaladdra:%d,formaladdrb:%d
",&a,&b);//打印形參地址
printf(">>formalvaluea:%d,formalvalueb:%d
",a,b);//打印形參的值
printf(">>formaladdrvaluea:%d,formaladdrvalueb:%d
",*a,*b);//打印以形參值為地址的值
temp=*a;
*a=*b;
*b=temp;
printf(">>formaladdra:%d,formaladdrb:%d
",&a,&b);
printf(">>formalvaluea:%d,formalvalueb:%d
",a,b);
printf(">>formaladdrvaluea:%d,formaladdrvalueb:%d
",*a,*b);
}

intmain()
{
inta=1,b=2;
swap_2(&a,&b);
printf(">>actualaddra:%d,actualaddrb:%d
",&a,&b);
printf(">>actualvaluea:%d,actualvalueb:%d
",a,b);
return0;
}

結(jié)果如下:

>>formaladdra:6422272,formaladdrb:6422276
>>formalvaluea:6422300,formalvalueb:6422296
>>formaladdrvaluea:1,formaladdrvalueb:2
>>formaladdra:6422272,formaladdrb:6422276
>>formalvaluea:6422300,formalvalueb:6422296
>>formaladdrvaluea:2,formaladdrvalueb:1
>>actualaddra:6422300,actualaddrb:6422296
>>actualvaluea:2,actualvalueb:1

從結(jié)果可以看出,這個(gè)函數(shù)可以交換輸入?yún)?shù)的值。下面我們來分析一下為什么這個(gè)函數(shù)能夠?qū)崿F(xiàn)交換功能。

以變量a為例,首先,從結(jié)果的第一行可以看出,傳入函數(shù)的參數(shù)是地址(即實(shí)參a的地址:6420300),這個(gè)地址作為一個(gè)值存放在形參a(地址:6422272)中,然后定義一個(gè)int型變量來存放地址6422272(形參a的地址)中的值6422300(實(shí)參a的地址),然后將指向6422296(實(shí)參b的地址)地址中的值 賦給 指向6422300(實(shí)參a的地址),開始地址6422300地址中的值為2,現(xiàn)在該地址的值變?yōu)?,同理,在執(zhí)行函數(shù)之后地址6422296中的值變?yōu)?,從而實(shí)現(xiàn)了兩個(gè)數(shù)的交換。

在這個(gè)過程中,是函數(shù)調(diào)用a,b兩個(gè)值的地址,并在函數(shù)中改變這兩地址中的值。與上一個(gè)函數(shù)的本質(zhì)區(qū)別就是:上一個(gè)函數(shù)swap1只是將a,b的值給復(fù)制到兩個(gè)新的地址當(dāng)中,并改變新的地址中的值,與a,b地址無關(guān)。而swap_2則是直接操作a,b地址中的值,進(jìn)而可以實(shí)現(xiàn)交換兩個(gè)數(shù)的功能。

注意:實(shí)參和形參是在兩個(gè)不同地址,雖然起的名字是一樣的,當(dāng)然這個(gè)名字可以自己隨意起。為了更加清楚的說明實(shí)參和形參是兩個(gè)東西,下面我將形參的變量名給改一下:

voidswap_2(int*formal_a,int*formal_b)
{
inttemp;
printf(">>formaladdra:%d,formaladdrb:%d
",&a,&b);
printf(">>formalvaluea:%d,formalvalueb:%d
",a,b);
printf(">>formaladdrvaluea:%d,formaladdrvalueb:%d
",*a,*b);
temp=*formal_a;
*formal_a=*formal_b;
*formal_b=temp;
printf(">>formaladdra:%d,formaladdrb:%d
",&a,&b);
printf(">>formalvaluea:%d,formalvalueb:%d
",a,b);
printf(">>formaladdrvaluea:%d,formaladdrvalueb:%d
",*a,*b);
}

intmain()
{
inta=1,b=2;
swap_2(&a,&b);
printf(">>actualaddra:%d,actualaddrb:%d
",&a,&b);
printf(">>actualvaluea:%d,actualvalueb:%d
",a,b);
return0;
}

結(jié)果如下:

>>formaladdra:6422272,formaladdrb:6422276
>>formalvaluea:6422300,formalvalueb:6422296
>>formaladdrvaluea:1,formaladdrvalueb:2
>>formaladdra:6422272,formaladdrb:6422276
>>formalvaluea:6422300,formalvalueb:6422296
>>formaladdrvaluea:2,formaladdrvalueb:1
>>actualaddra:6422300,actualaddrb:6422296
>>actualvaluea:2,actualvalueb:1

和之前的結(jié)果一樣,可以知道,函數(shù)在執(zhí)行的時(shí)候其實(shí)是不管你名字怎么起的,而是關(guān)心地址,而你起的名字實(shí)際也只是那個(gè)地址的代號而已。

通過上面的例子已經(jīng)清楚了函數(shù)的形參與實(shí)參的區(qū)別,那么現(xiàn)在就來解決文章開頭提出的問題

如何通過函數(shù)改變一個(gè)傳入指針作為實(shí)參的地址,其實(shí)在理解上面的關(guān)于函數(shù)的形參和實(shí)參就非常容易懂了。

首先我們來看下面一個(gè)例子

intb[3]={1,2,3};

voidfcn(int**a)
{
*a=b;
}

intmain()
{
unsignedinti=0;
int*a;

for(i=0;i<3;i++)
?????{
?????????printf(">>%d
",a[i]);
}

fcn(&a);

for(i=0;i<3;i++)
?????{
?????????printf(">>%d
",a[i]);
}
}

函數(shù)輸出為:

>>0
>>-1
>>4194304
>>1
>>2
>>3

主函數(shù)中,我們定義了一個(gè)指針a,并且沒有初始化它,之后我們是不能夠直接對它指向的地址進(jìn)行賦值,因?yàn)楝F(xiàn)在它的地址是隨機(jī)的,對該地址進(jìn)行操作后有可能會導(dǎo)致程序崩潰。我們想要用它就只能夠?qū)λ约旱闹狄簿褪撬赶虻牡刂愤M(jìn)行操作。函數(shù)fcn通過形參來改變輸入實(shí)參的值是怎么做到的呢?

首先看函數(shù)的形參(int **a),表示什么意思呢?就是說傳入的一個(gè)二級指針,指向指針的指針,這又是什么意思呢?比如你有一張藏寶圖,它說寶藏在a地,你到a地之后也只得到一張藏寶圖,該藏寶圖說寶藏在b地,你只有到達(dá)b地才能夠得到寶藏。這就是一個(gè)二級指針,第一個(gè)指向的地址是a,a的內(nèi)容也是一個(gè)指針,指向b,b地址下才是真正的內(nèi)容。

我們在主函數(shù)中定義了一個(gè)指針a,讓它傳入函數(shù)fcn,我們分析一下這個(gè)過程:

函數(shù)開辟一個(gè)形參的地址,該地址中的內(nèi)容為指向傳入?yún)?shù)地址的值,那么函數(shù)中我們將數(shù)組b的首地址賦給該地址,也就是將實(shí)參的地址更改成了數(shù)組b的首地址。

文章確實(shí)太繞了,個(gè)人覺得最主要的點(diǎn)就是弄清楚指針與地址以及該地址的值的關(guān)系,還有就是形參與實(shí)參的關(guān)系。

編輯:jq
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7575

    瀏覽量

    134153
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4237

    瀏覽量

    61973
  • 指針
    +關(guān)注

    關(guān)注

    1

    文章

    475

    瀏覽量

    70459

原文標(biāo)題:C語言指針作為形參如何改變其指向的地址?

文章出處:【微信號:gh_c472c2199c88,微信公眾號:嵌入式微處理器】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    c語言指針

    1:指針是一個(gè)地址,指向的是個(gè)類型:我們知道,c語言中的類型有int,char,bool(這個(gè)不常用),一般我們使用int,char就可以滿
    發(fā)表于 09-19 00:12

    函數(shù)指針指針函數(shù)

    ) ([列表]); 注1:“返回值類型”說明函數(shù)的返回類型,“(指針變量名 )”中的括號不能省,括號改變了運(yùn)算符的優(yōu)先級。若省略整體則成為一個(gè)函數(shù)說明,說明了一個(gè)返回的數(shù)據(jù)類型是
    發(fā)表于 01-22 19:28

    C語言入門教程-指向同一地址

    指向同一地址 C語言的一個(gè)優(yōu)點(diǎn)是:任意多個(gè)指針可以指向同一內(nèi)存
    發(fā)表于 07-29 11:45 ?1060次閱讀

    C語言入門教程-指向結(jié)構(gòu)體的指針

    指向結(jié)構(gòu)體的指針C語言中幾乎可以創(chuàng)建指向任何類型的指針,包括用戶自定義的類型。創(chuàng)建結(jié)構(gòu)體
    發(fā)表于 07-29 12:04 ?3122次閱讀

    C語言入門教程-指向指針指針

    指向指針指針 創(chuàng)建一個(gè)指針,使它指向另一個(gè)指針,這是可能的,而且常常也是必要的。這一技術(shù)有時(shí)
    發(fā)表于 07-29 12:10 ?1075次閱讀

    C語言教程之函數(shù)指針變量與指針函數(shù)的區(qū)別(下篇)

    z=(*pfun)(x,y); //調(diào)用函數(shù)指針變量,實(shí)參x和y的值傳遞給a和b printf(“max=%dn”,z); //a
    發(fā)表于 05-22 07:30 ?1913次閱讀

    C語言初識指針

    目錄1. 指針是什么?2. 指針指針類型3.野指針3.1 野指針成因3.2 如何規(guī)避野指針4.
    發(fā)表于 12-31 19:57 ?26次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>初識<b class='flag-5'>指針</b>

    C語言指針的理解使用

    C語言指針的理解使用指針變量的聲明給普通變量的賦值對比給指針變量的賦值代*的指針的使用說明
    發(fā)表于 01-13 13:42 ?3次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>指針</b>的理解使用

    C語言中的指針(重點(diǎn))超詳細(xì)

    - 指針4.3、指針的運(yùn)算關(guān)系5、指針和數(shù)組6、二級指針7、指針數(shù)組1、指針是什么??在計(jì)算機(jī)
    發(fā)表于 01-13 14:10 ?11次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>中的<b class='flag-5'>指針</b>(重點(diǎn))超詳細(xì)

    C語言-函數(shù)的可變形(不定形)

    這篇文章介紹C語言函數(shù)的不定參數(shù)、可變參數(shù) ,實(shí)現(xiàn)printf一樣的傳效果。
    的頭像 發(fā)表于 08-14 09:58 ?2410次閱讀

    C語言-指針作為函數(shù)類型

    C語言函數(shù)里最常用就是指針和返回地址,特別是字符串處理中,經(jīng)常需要封裝各種功能函數(shù)完成數(shù)據(jù)處理。
    的頭像 發(fā)表于 08-14 10:05 ?1690次閱讀

    指針進(jìn)階第五站:函數(shù)指針!

    定義一個(gè)函數(shù)指針指向的函數(shù)有兩個(gè)int并且返回一個(gè)函數(shù)指針,返回的指針
    發(fā)表于 08-17 15:58 ?480次閱讀

    C語言指針詳細(xì)解析

    可以對數(shù)據(jù)本身,也可以對存儲數(shù)據(jù)的變量地址進(jìn)行操作。 指針是一個(gè)占據(jù)存儲空間的實(shí)體在這一段空間起始位置的相對距離值。在C/C++語言中,
    的頭像 發(fā)表于 11-14 16:53 ?2078次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>指針</b>詳細(xì)解析

    C語言怎樣引用指針變量

    指針C語言中的一個(gè)重要概念,也是C語言的一個(gè)重要特色。正確而靈活地運(yùn)用它,可以使程序簡潔、緊湊、高校。 由于通過
    的頭像 發(fā)表于 03-10 14:43 ?935次閱讀

    C語言數(shù)組元素的指針

    C語言調(diào)用函數(shù)時(shí)虛實(shí)結(jié)合的方法都是采用“值傳遞”方式,當(dāng)用變量名作為函數(shù)參數(shù)時(shí)傳遞的是變量的值,當(dāng)用數(shù)組名作為函數(shù)參數(shù)時(shí)。 由于數(shù)組名代表的是數(shù)組元素
    的頭像 發(fā)表于 03-10 14:45 ?753次閱讀