程序员

指针释疑:函数参数之指针的地址

2015-12-24  本文已影响63人  小城大麦

假设我们希望通过一个函数修改指针p所指的内容,那么我们通常需要是传递p的地址。
这样函数的签名通常需要为 void** p
下面代码:

void fail(int* arr,int * d){
    printf("param addr:%p param value:%p \n",&d,d);
    d = &arr[0];
}

void success(int* arr, int** d){
    printf("param addr:%p param value:%p \n",&d,d);
    *d = &arr[0];
}

int main(int argc, const char * argv[]) {
    using namespace std;
    int arr[2]={4,5};
    int value = 10;
    int* p = &value;
    
    printf("value addr:%p, value:%d\n",&value,value);
    
    //指针的地址,指针值,指针所指的值
    printf("p addr:%p p:%p value:%d\n",&p,p,*p);
    
    fail(arr,p);//无法修改p所指向的值
    printf("p addr:%p p:%p value:%d\n",&p,p,*p);
    
    success(arr,&p);//可以修改
    printf("p addr:%p p:%p value:%d\n",&p,p,*p);
    
    return 0;
}

输出结果

value addr:0xf7ac, value:10
p addr:0xf7a0 p:0xf7ac value:10
param addr:0xf770 param value:0xf7ac 
p addr:0xf7a0 p:0xf7ac value:10
param addr:0xf770 param value:0xf7a0 
p addr:0xf7a0 p:0xf7c0 value:4

如果希望d的结果执行arr[0]的第一个元素,函数f无法达到要求,f2可以。
对于fail函数,进入函数后,系统给d分配了空间,其地址为0xf770,参数传递时,0xf770上所存储的值修改为p的值,然后执行d=&arr[0],这样又修改oxf770上的值为&arr[0],而p的值根本没有影响。
显然不得到p的地址,即p的实际存储空间,如何修改得了p呢。所以必须使用p,即指向指针的指针来保存p的地址并传递给函数。
success传得p的地址,此时0xf770上存储的值为p的地址。通过
d可以修改p存储的值,
d=arr[0]成功修改了p的值。

C语言中地址仅仅代表存储位置,使用指针p表示地址,*p对地址内容查询和修改,结合sizeof获得地址内容大小。只需要牢固掌握这一点就可以比较好的理解指针的运用。

C语言中函数本质都是传值,只是当我们传得是地址值时,就可以通过地址值修改地址的内容。
而C语言中指针的值本质上是地址值,但是修改指针的值就必须传指针的本身地址值,而不是指针的值。

上一篇下一篇

猜你喜欢

热点阅读