指針與函數(shù)傳參

一、普通變量作為函數(shù)形參

  • 普通變量作為函數(shù)形參時,形參和實參名字可以相同也可以不同。實際上都是用實參來替代相對應(yīng)的形參。
  • 在子函數(shù)內(nèi)部,形參的值等于實參。原因是函數(shù)調(diào)用時把實參的值復(fù)制給了形參。
  • 這就是很多書上寫的傳值調(diào)用。(相當(dāng)于實參做右值形參做左值)。
#include <stdio.h>
#include <string.h>
//&a和&b不同,說明a和b不是同一個變量 (內(nèi)存中a和b是獨立的兩個內(nèi)存空間)
//實際上a和b是有關(guān)聯(lián)的,a是b賦值得到的
void func1(int b)
{
//在 
        printf("b=%d.\n",b);
        printf("in func1 &b=%p.\n",&b);
}
int main(void)
{
        int a=4;
        printf("&a=%p.\n",&a);
        func1(a);    //把普通變量a傳入函數(shù)func1內(nèi)
        ruturn 0;
}

二、數(shù)組作為函數(shù)形參

  • 數(shù)組名作為形參傳遞時,實際傳遞的不是整個數(shù)組,而是數(shù)組的首元素的首地址(也就是整個數(shù)組的首地址。因為傳參時是傳值,所以這兩個沒區(qū)別。)所以在子函數(shù)內(nèi)部傳進(jìn)來的數(shù)組名就等于是一個指向數(shù)組首元素地址的指針。所以sizeof得到的是4。
  • 在子函數(shù)內(nèi)傳參得到的數(shù)組首元素首地址,和外面得到的數(shù)組首元素首地址的值是相同的。很多人把這個特性叫做“傳址調(diào)用”(調(diào)用子函數(shù)時傳了地址,也就是指針。此時可以通過傳進(jìn)去的地址可以訪問實參)。
  • 數(shù)組名作為形參時,[ ]里面是可有可無的。因為數(shù)組名做形參傳遞的實際只是個指針,根本沒有數(shù)組長度信息。
#include <stdio.h>
void func2(int a[])
{
        printf("sizeof(a)=%d.\n",sizeof(a));    //4
        printf("in func2 a=%p.\n",a);    //
}
int main(void)
{
        int a[5];
        func2(a);
        printf("a=%p.\n",a); 
}

三、指針作為函數(shù)形參

  • 和數(shù)組作為函數(shù)形參是一樣的。
  • 就好像指針方式訪問數(shù)組元素和數(shù)組方式訪問數(shù)組元素是一樣的。
#include <stdio.h>
void func3(int *a)
{
        printf("sizeof(a)=%d.\n",sizeof(a));  
        printf("in func2 a=%p.\n",a); 
}
int main(void)
{
        int a[5];
        func3(a);
        printf("a=%p.\n",a); 
}

四、結(jié)構(gòu)體變量作為函數(shù)形參

  • 結(jié)構(gòu)體變量作為函數(shù)形參時,實際上和普通變量傳參時表現(xiàn)是一模一樣的。結(jié)構(gòu)體變量實際也是普通變量。
  • 因為結(jié)構(gòu)體一般都很大,如果直接用結(jié)構(gòu)體變量進(jìn)行傳參,那么函數(shù)調(diào)用效率就會很低(因為函數(shù)傳參的時候需要將實參賦值給形參,所以當(dāng)傳參變量越大調(diào)用效率就會越低)。解決的方法就是傳遞結(jié)構(gòu)體的指針進(jìn)去。
  • 結(jié)構(gòu)體由于自身太大,所以傳參應(yīng)該由指針傳。(但是程序員可以自己決定傳遞整個結(jié)構(gòu)體變量)。為什么c語言數(shù)組默認(rèn)只能傳指針呢?c語言給數(shù)組做了決定。
#include <stdio.h>
struct A
{
        char a;
        int b;
};
void func4(struct A a1)
{
        printf("sizeof(a1)=%d.\n",sizeof(a1));
        printf("&a1=%d.\n",&a1);
        printf("a1.b=%d.\n",a1.b);
}
int main(void)
{
        struct A a=
{
        .a=A,
        .b=555,
};    //給結(jié)構(gòu)體賦初值
        printf("sizeof(a)=%d.\n",sizeof(a));
        printf("&a=%d.\n",&a);
        printf("a.b=%d.\n",a.b);
        func4(a);
}
#include <stdio.h>
struct A
{
        char a;
        int b;
};
void func5(struct A *a1)
{
        printf("sizeof(a1)=%d.\n",sizeof(a1));    //4
        printf("&a1=%d.\n",a1);
        printf("&a1=%d.\n",&a1);
        printf("a1.b=%d.\n",a1->b);  //訪問結(jié)構(gòu)體是變量是.是指針時用箭頭
}
int main(void)
{
        struct A a=
{
        .a=A,
        .b=555,
};    //給結(jié)構(gòu)體賦初值
        printf("&a=%d.\n",&a);
        printf("a.b=%d.\n",a.b); 
        func5(&a);
}

五、傳值調(diào)用與傳址調(diào)用

  • 傳值調(diào)用指的是:x,y作為實參,自己真身并沒有進(jìn)入swap1函數(shù)內(nèi)部,而只是拷貝了一份自己的副本,但是是不同的變量,進(jìn)入了子函數(shù)是swap1中交換的實際只是副本而不是真身。內(nèi)部確實交換了,外部x,y卻沒有影響。
  • 在swap2中真的被改變了。(但是x,y真身也沒有被改變。而是swap2函數(shù)內(nèi)部跑出來把外面的x和y真身改變了。)實際上實參永遠(yuǎn)無法進(jìn)入子函數(shù)內(nèi)部,但是在swap2實參的地址傳遞給子函數(shù)。于是子函數(shù)內(nèi)可以通過指針解引用的方法從函數(shù)內(nèi)部訪問到外部x和y的真身,從而改變x,y。
  • 結(jié)論:c語言函數(shù)調(diào)用一直是傳值的,只是傳的值可以是變量名,也可以是指針。
#include <stdio.h>
void swap1(int a, int b)
{
        int tmp;
        tmp=a;
        a=b;
        b=tmp;
        printf("a=%d,b=%d.\n",a,b);
}
int main(void)
{
        int x=3,y=5;
        swap1(x,y);
        printf("x=%d,y=%d.\n",x,y);    //沒有交換
}
#include <stdio.h>
void swap2(int *a, int *b)
{
        int tmp;
        tmp=*a;
        a=*b;
        *b=tmp;
        printf("*a=%d,*b=%d.\n",*a,*b);
}
int main(void)
{
        int x=3,y=5;
        swap1(&x,&y);
        printf("x=%d,y=%d.\n",x,y);    //交換成功
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 指針是C語言中廣泛使用的一種數(shù)據(jù)類型。 運用指針編程是C語言最主要的風(fēng)格之一。利用指針變量可以表示各種數(shù)據(jù)結(jié)構(gòu); ...
    朱森閱讀 3,615評論 3 44
  • 第十章 指針 1. 地址指針的基本概念: 在計算機(jī)中,所有的數(shù)據(jù)都是存放在存儲器中的。一般把存儲器中的一個字節(jié)稱為...
    堅持到底v2閱讀 1,168評論 2 3
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,680評論 1 51
  • 1.語言中變量的實質(zhì) 要理解C指針,我認(rèn)為一定要理解C中“變量”的存儲實質(zhì), 所以我就從“變量”這個東西開始講起吧...
    金巴多閱讀 1,979評論 0 9
  • 原文地址:C語言函數(shù)調(diào)用棧(一)C語言函數(shù)調(diào)用棧(二) 0 引言 程序的執(zhí)行過程可看作連續(xù)的函數(shù)調(diào)用。當(dāng)一個函數(shù)執(zhí)...
    小豬啊嗚閱讀 4,972評論 1 19

友情鏈接更多精彩內(nèi)容