2013-04-30 201 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; 
}