程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言中函數和指針的參數傳遞

C語言中函數和指針的參數傳遞

編輯:關於C語言

C語言中函數和指針的參數傳遞


最近寫二叉樹的數據結構實驗,想用一個沒有返回值的函數來創建一個樹,發現這個樹就是建立不起來,那麼我就用這個例子討論一下c語言中指針作為形參的函數中傳遞中隱藏的東西。

大家知道C++中有引用的概念,兩個數據引用同一個數據,那麼更改任意的一個都相當於更改了本體,那麼另一個數據所對應的值也會改變,可是C中是沒有這個概念的。所以就產生了一些東西。和我們本來想的有差別。


一、明確C語言中函數的入口:

C語言中函數的形參負責接收外部數據,那麼數據究竟怎麼進入函數的呢,其實我們在函數體內操作的形參只是傳遞進來參數的一個副本,也就是說這兩個參數雖然名字一樣,對應的值一樣,但是他們兩個對應的內存地址是不一樣的,也就是說這就是兩個“看上去一模一樣”的完全不同的變量。

所以一定要知道,C語言中函數是值傳遞的,也就是說,C語言只能把值傳給函數,而不能把你想要傳遞的變量完全的放進函數內部。

二、指針傳遞給函數:

指針作為一個特殊的東西,他的強大之處就在於指針可以直接修改內存地址上的數據。雖然指針特別強大,但是他也難逃函數的限制,你傳遞給函數一個指針,因為是值傳遞,那麼你在函數體內的使用的形參指針也只是一個副本,只是一個指向的值和你傳進來的那個指針一樣的一個另外的一個變量。也就是說他和普通常量是沒有區別的。

三、我想要達到引用的效果怎麼實現

C語言中因為是值傳遞的,那麼我們就傳遞值,只要講想要傳遞進函數的東西的地址傳進函數,並且函數用一個指針接收,那麼就相當於把這個變量地址原封不動的傳遞給了函數,形參的指針指向的是外面傳進來的地址,有了地址不就好辦了嗎。

四、下面是我寫的一個二叉樹建立的一個無返回值的版本:

因為二叉樹是用遞歸建立的,就像建立鏈表一樣,一個節點一個節點建立,如果不獲得上一個節點的地址,你怎麼把鏈表連接起來呢,鏈表就散開了。

所以只能通過傳遞地址來達到找到已經建好的鏈表的前驅,才能把各個節點穿起來。

#include 
#include 

typedef struct tree {
    char t;
    struct tree *lchild;
    struct tree *rchild;
}Tree;

void initTree(Tree **T) {
    char ch;
    ch = getchar();
    if (ch == '#') {
        *T = NULL;
    }
    else {
        *T = (Tree *)malloc(sizeof(Tree));
        (*T)->t = ch;
        initTree(&(*T)->lchild);
        initTree(&(*T)->rchild);
    }
}

void qianT(Tree *T) {
    if (T) {
        printf("%c ",T->t);
        qianT(T->lchild);
        qianT(T->rchild);
    }
}

int main (void) {
    Tree *T;
    initTree(&T);
    qianT(T);
    return 0;
}



注意看樹的建立那個函數,我每次都是穿進去一個節點的地址,然後通過地址來找到已經建立好的樹,才能將樹建立起來。那麼有的人會問了?為什麼不是下面這個寫法呢?

void initTree(Tree *T) {
    char ch;
    ch = getchar();
    if (ch == '#') {
        T = NULL;
    }
    else {
        T = (Tree *)malloc(sizeof(Tree));
        T->t = ch;
        initTree(T->lchild);
        initTree(T->rchild);
    }
}
這種寫法,你每次傳進來的都是一個變量,說過,c語言是值傳遞的,那麼每次你申請的節點空間都是給副本申請的,然後遞歸的是副本的左右孩子,也就是說你的樹根本沒有建立起來,因為每次申請的內存都沒有連接上。
為什麼我的那個寫法可以呢,因為我是用一個指向指針的指針來存地址的,我給傳進來的地址申請了內存,也就相當於給穿進來的那個節點本身申請了內存,而不是給副本,所以二叉樹就順其自然建立起來了。
最後記住,c語言是值傳遞的,任何東西傳遞給函數的都只是值!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved