指標形參,C程式設計必須懂的東西

love_gg發表於2012-09-14

函式的傳遞的引數是原引數的副本

       使用C語言程式設計,不可能不用到函式,但是函式的引數傳遞,我們是否真的清楚了呢。本文主要介紹C語言中函式傳遞的引數。。

       函式的引數通常分為兩種,普通變數,指標變數。這些引數,將會被函式體呼叫,當讓,也可以傳入一些永遠不被函式呼叫的引數,就像你宣告瞭一些變數,卻永遠不用一樣,在語法上是沒有問題的。

       那麼,函式體內呼叫的傳遞過來的引數,與原來的引數有什麼關係呢?

 

       函式體內接收到的引數,是原引數的副本。

 

1. 普通變數在函式中的傳遞

       首先我們來看普通變數,函式體內的引數為該普通變數的拷貝副本。下面是一個例子的源程式:

 

#include <stdio.h>

#include <stdlib.h>

 

int test(int t1, int t2);

 

int main(int argc, char *argv[])

{

    int t1 = 10;

    int t2 = 0;

 

    printf("[main]t1: %d/tt1:%x/n", t1, &t1);

    printf("[main]t2: %d/tt2:%x/n", t2, &t2);

 

    test(t1, t2);

   

    printf("[main]t1: %d/tt1:%x/n", t1, &t1);

    printf("[main]t2: %d/tt2:%x/n", t2, &t2);   

 

  system("PAUSE"); 

  return 0;

}

 

int test(int t1, int t2)

{

    printf("in func..../n");

   

    printf("[test]t1: %d/tt1:%x/n", t1, &t1);

    printf("[test]t2: %d/tt2:%x/n", t2, &t2);

    t2 = t1;

    printf("[test]after t2 = t1/n");

    printf("[test]t1: %d/tt1:%x/n", t1, &t1);

    printf("[test]t2: %d/tt2:%x/n", t2, &t2);

    printf("in func over..../n");

    return 1;

}

 

       執行結果為:

 

[main]t1: 10    t1:22ff7c

[main]t2: 0     t2:22ff78

in func....

[test]t1: 10    t1:22ff60

[test]t2: 0     t2:22ff64

[test]after t2 = t1

[test]t1: 10    t1:22ff60

[test]t2: 10    t2:22ff64

in func over....

[main]t1: 10    t1:22ff7c

[main]t2: 0     t2:22ff78

 

(列印的地址值可能與我獲得的結果不同。)

       可以看到,t1t2,在被test函式呼叫前後,其值和地址都未變化。而在test函式中,t1t2的地址與main函式中並不相同,其只是原來的t1t2的拷貝副本。對副本作的一切操作,都不會影響到test函式外的原來的引數。

2. 指標變數在函式中的傳遞

       指標作為變數在函式傳遞中,有些特殊,對於普通變數,函式傳遞的是對其的一份拷貝的副本,而對於指標,函式傳遞的是對其存放地址的一份拷貝,該拷貝存放的地址與原來的指標所存的地址一致。

       我們來看看例子程式:

 

#include <stdio.h>

#include <stdlib.h>

 

int test(char *t1, char *t2);

 

int main(int argc, char *argv[])

{

    char t1[] = "kdsfkasdfkdsf";

    char *t2 = NULL;

    printf("[main]t1: %s/tt1:%x/t&t1:%x/n", t1, t1, &t1);

    printf("[main]t2: %s/tt2:%x/t/t&t2:%x/n", t2, t2, &t2);

    test(t1, t2);

    printf("[main]t1: %s/tt1:%x/t&t1:%x/n", t1, t1, &t1);

    printf("[main]t2: %s/tt2:%x/t/t&t2:%x/n", t2, t2, &t2);   

 

  system("PAUSE"); 

  return 0;

}

 

int test(char *t1, char *t2)

{

    printf("in func..../n");

    printf("[test]t1: %s/tt1:%x/t&t1:%x/n", t1, t1, &t1);

    printf("[test]t2: %s/tt2:%x/t/t&t2:%x/n", t2, t2, &t2);

    t2 = t1;

    printf("[test]after t2 = t1/n");

    printf("[test]t1: %s/tt1:%x/t&t1:%x/n", t1, t1, &t1);

    printf("[test]t2: %s/tt2:%x/t&t2:%x/n", t2, t2, &t2);

    printf("in func over..../n");

    return 1;

}

 

輸出結果為:

 

[main]t1: kdsfkasdfkdsf t1:22ff68       &t1:22ff68

[main]t2: (null)        t2:0            &t2:22ff64

in func....

[test]t1: kdsfkasdfkdsf t1:22ff68       &t1:22ff40

[test]t2: (null)        t2:0            &t2:22ff44

[test]after t2 = t1

[test]t1: kdsfkasdfkdsf t1:22ff68       &t1:22ff40

[test]t2: kdsfkasdfkdsf t2:22ff68       &t2:22ff44

in func over....

[main]t1: kdsfkasdfkdsf t1:22ff68       &t1:22ff68

[main]t2: (null)        t2:0            &t2:22ff64

 

(列印的地址值可能與我獲得的結果不同。)

       可以看到,在main函式中,t1t2所存放的地址,以及該地址對應的字串的值,與test函式中傳遞的t1t2完全一樣,但t1t2的地址卻完全不同,

l         故指標在函式中傳遞的是其地址的一份拷貝,可以在函式體內,修改指標存放的地址對應的值,其修改在函式體外對原引數同樣有效,因為原引數也指向該地址。

l         指標在函式體內可修改其所存放的地址,但其修改對函式體外原指標引數無效,因為其只是原指標引數的地址副本,原指標依然指向原來的地址。

3. 使用指標的指標在函式體內修改指標所指物件

       如果一定要修改指標引數所指的地址,應該怎麼作呢?這時,我們需要用到指標的指標了。請看例子程式:

 

#include <stdio.h>

#include <stdlib.h>

 

int test(char **t1, char **t2);

 

int main(int argc, char *argv[])

{

    char *t1 = "tttt";

    char *t2 = NULL;

 

    printf("[main]t1: %s/tt1:%x/t&t1:%x/n", t1, t1, &t1);

    printf("[main]t2: %s/tt2:%x/t&t2:%x/n", t2, t2, &t2);

 

    test(&t1, &t2);

   

    printf("[main]t1: %s/tt1:%x/t&t1:%x/n", t1, t1, &t1);

    printf("[main]t2: %s/tt2:%x/t&t2:%x/n", t2, t2, &t2);   

    //printf("[main]t2: %s/n", t2);

 

  system("PAUSE"); 

  return 0;

}

 

int test(char **t1, char **t2)

{

    printf("[test]in func..../n"); 

    printf("[test]*t1: %s/tt1:%x/n", *t1, t1);

    printf("[test]*t2: %s/tt2:%x/n", *t2, t2);   

    *t2 = *t1;

    printf("[test]after *t2 = *t1/n");

    printf("[test]*t1: %s/tt1:%x/n", *t1, t1);

    printf("[test]*t2: %s/tt2:%x/n", *t2, t2);

   

    printf("[test]in func over..../n");

    return 1;

}


轉自:http://blog.csdn.net/kunp/article/details/400277,thks

 

相關文章