指针用作传出参数时,需要二级指针

转自: http://blog.csdn.net/david_xtd/article/details/7175962

要点:

1. 参数传递的原则是:形参传给实参,不能反向传递;

2. 一级指针可以在函数内部修改形参指针指向的内容;

如:

  1. void fun(char *p)   
  2. {   
  3.     p[2] = a;//由形参(实参)指向的函数外部的数组的内容就被改变了。  
  4. }   

如果我们想改变实参本身呢?也就是说,我们连指针值都要改变,如果使用:

  1. void GetMemory(int num, char *p)   
  2. {   
  3.     p = (char *)malloc(num * sizeof(char))  
  4.     //或C++中:p = new char[10];  
  5. }   

就不行了,因为在函数内部不能通过改变形参的值来改变实参


但是,可以通过二级指针来改变指针值。

  1. void GetMemory(char **p, int num)  
  2. {   
  3.     *p = new char[num];   
  4.     *p[2] = a;   
  5.     delete char[];  
  6. }   


关键是:

1. 编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是 _p,编译器使 _p = p。如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。这就是指针可以用作输出参数的原因。

在本例中,_p申请了新的内存,只是把 _p所指的内存地址改变了,但是p丝毫未变。所以函数GetMemory并不能输出任何东西。
如果非得要用指针参数去申请内存,那么应该改用“指向指针的指针”,
2. 变量作函数形参调用的时候都是要分配一个副本,不管是传值还是传址。传入后就和形参没有关系了,它不会改变形参的值。


注意指针所指向的内存是在函数内分配的还是在函数外分配的,以及是不是在堆上分配的。

你定义了一个指针,但是并没有分配指针指向对象所需的内存空间;当函数返回后,此函数栈中的内存会被释放掉,不要让指针指向此函数栈中的内存空间,要指向堆上或此函数外的内存空间。


代码范例:

  1. #include <stdio.h>  
  2. #include <string.h>  
  3.   
  4. char *f_void(void);  
  5. void f_1ptr(char *ret);  
  6. void f_1ptr_o(char *ret);  
  7. void f_2ptr(char **ret);  
  8.     
  9. int main()  
  10. {  
  11.     char havec[] = "this is abcdefghijklmnopqrstuvwxyz";  
  12.     char *tmp;  // Alloc memory for single indirection pointer  
  13.     char **ret; // Alloc memory for double indirection pointer  
  14.   
  15.     ret = &tmp; // this is important, why?  
  16.   
  17.     tmp = f_void();  
  18.     printf("f_void():%s\n",tmp); // Ok  
  19.   
  20.     printf("Before calling f_1ptr():havec = %s.\n",havec);  
  21.     f_1ptr(havec);  
  22.     printf("After calling f_1ptr():havec = %s.\n\n",havec);  
  23.    
  24.     printf("Now try to output argument using single indirection pointer!\n");  
  25.     f_1ptr_o(tmp);  
  26.     printf("The output result is:%s", tmp);  
  27.     f_2ptr(ret);  
  28.     printf("%s\n",tmp); // Ok  
  29.    
  30.     return 0;  
  31. }  
  32.    
  33. char *f_void(void// return a pointer, memory is alloced in global  
  34. {  
  35.     return "This function has no parameters.\n";  
  36. }  
  37.   
  38. void f_1ptr(char *ret)  
  39. {  
  40.     char *tmp;  
  41.       
  42.     printf("Search for the 1st 'f' character in '%s'.\n", ret);  
  43.     if((tmp = index(ret,'f')) ==NULL) // this is just a example  
  44.         return ;  
  45.     *(tmp+1) = '\0';  
  46. }  
  47.   
  48. void f_1ptr_o(char *ret) // Try to output argument using single indirection pointer  
  49. {  
  50.     char *t8;  
  51.   
  52.     static char aa[] = "Output argument test!\n"// 该处的static指定数组aa[]指向全局变量所在空间  
  53.     t8 = ret;  
  54.     // ret = aa;  
  55.     memcpy(t8, aa, sizeof(aa));  
  56. }  
  57.   
  58. void f_2ptr(char **ret) // output argument using double indirection pointer  
  59. {  
  60.     static char aa[] = "Output argument test!\n"// 该处的static指定数组aa[]指向全局变量所在空间  
  61.     *ret = aa;  
  62. }  

  1. 运行结果:<pre name="code" class="cpp">$ ./pointer2nd-test.exe  
  2. f_void():This function has no parameters.  
  3.   
  4. Before calling f_1ptr():havec = this is abcdefghijklmnopqrstuvwxyz.  
  5. Search for the 1st 'f' character in 'this is abcdefghijklmnopqrstuvwxyz'.  
  6. After calling f_1ptr():havec = this is abcdef.  
  7.   
  8. Now try to output argument using single indirection pointer!  
  9. The output result is:Output argument test!  
  10. Output argument test!</pre>  
  11. <pre></pre>  
  12. <p></p>  
  13. <pre></pre>  
  14. <p></p>  
  15. <p><span style="font-size:12px"><br>  
  16. </span></p>  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值