2013-04-30 262 views
9

我誤解了C中指針的基本概念,這應該很簡單,但搜索不會引起任何結果。我不明白以下代碼的行爲;C將指針指向NULL

#include <stdlib.h> 
#include <stdio.h> 

void my_function(char *); 

int main(int argc, char *argv[]) { 
    char *ptr; 
    ptr = malloc(10); 

    if(ptr != NULL) printf("FIRST TEST: ptr is not null\n"); 
    else printf("FIRST TEST: ptr is null\n"); 

    my_function(ptr); 

    if(ptr != NULL) printf("SECOND TEST: ptr is not null\n"); 
    else printf("SECOND TEST: ptr is null\n"); 
} 

void my_function(char *a) { 
    a = NULL; 
} 

其中輸出;

FIRST TEST: ptr is not null 
SECOND TEST: ptr is not null 

爲什麼第二個測試仍然看到指針爲非NULL?我試圖使用NULL指針賦值作爲一種「返回標誌」來指示函數的某種失敗。但之後測試指針時,它似乎不是NULL。

回答

25

這是因爲指針是通過值而不是通過引用傳遞的。如果你想改變函數內部的指針,你需要在實際的指針即指針傳遞爲指針,以指針:

void my_function(char **a) 
{ 
    *a = NULL; 
} 

使用運營商&地址,當你調用該函數來獲取指針的地址:

my_function(&ptr); 
+0

在你回答之前,它突然讓我感到非常啞,我需要一個指向指針的指針才能分配外部指針! – lynks 2013-04-30 12:03:01

1

你的功能應該採取char** a如果你想修改它指向。這是因爲指針被複製爲作爲函數的參數,這意味着您對其所做的任何更改都不會在函數外部看到,因爲它修改了副本。

如果你想改變它並在功能範圍外看到它,你需要添加另一個間接尋址。

0

將指針傳遞給函數時,指針被複制到函數作用域中。如果你想做這樣的事情,你需要使用指針的指針。一個指針基本上只有一個整數/長度的函數調用

1

在C中,像foo(a)這樣的函數調用永遠不會改變a的值。

0

你的問題是,my_pointer獲取不寫入指針「ptr」,但它的副本「* a」。

你需要傳遞「ptr」的地址做你想要的。

5

你的陳述a=NULLmy_function()確實設置的aNULL價值,但a是您在main()通過ptrmy_function()該功能。當一個局部變量的ptr的值複製到a。我想你的整個在my_function()的定義中的a之前使用的*產生了混淆。

當我們想從被調用的函數中操縱那些指針指向的原始值時,通常會將指針傳遞給函數,並且這些由來自被調用函數的指針完成。在這種情況下,是否使用了這個:

*a= blah blah; 

它會體現在價值的地址指向ptrmain()。但既然你想改變的ptr本身的價值,你需要能夠有辦法manipulatemy_function()。爲此,您使用pointer-to-pointer,即char**型的。你通過這樣一個char**作爲參數來my_function((),並用它來改變ptr。這裏的變化對你的代碼的價值會爲你做它:

#include <stdlib.h> 
#include <stdio.h> 

void my_function(char **); // Change char* to char** 

int main(int argc, char *argv[]) { 
    char *ptr; 
    ptr = malloc(10); 

    if(ptr != NULL) printf("FIRST TEST: ptr is not null\n"); 
    else printf("FIRST TEST: ptr is null\n"); 

    my_function(&ptr); //You pass a char** 

    if(ptr != NULL) printf("SECOND TEST: ptr is not null\n"); 
    else printf("SECOND TEST: ptr is null\n"); 
} 

void my_function(char **a) { //Change char* to char** here 
    *a = NULL; 
}