转自: http://blog.csdn.net/david_xtd/article/details/7175962
要点:
1. 参数传递的原则是:形参传给实参,不能反向传递;
2. 一级指针可以在函数内部修改形参指针指向的内容;
如:
- void fun(char *p)
- {
- p[2] = a;
- }
如果我们想改变实参本身呢?也就是说,我们连指针值都要改变,如果使用:
- void GetMemory(int num, char *p)
- {
- p = (char *)malloc(num * sizeof(char))
-
- }
就不行了,因为在函数内部不能通过改变形参的值来改变实参。
但是,可以通过二级指针来改变指针值。
- void GetMemory(char **p, int num)
- {
- *p = new char[num];
- *p[2] = a;
- delete char[];
- }
关键是:
1. 编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是 _p,编译器使 _p = p。如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。这就是指针可以用作输出参数的原因。
在本例中,_p申请了新的内存,只是把 _p所指的内存地址改变了,但是p丝毫未变。所以函数GetMemory并不能输出任何东西。
如果非得要用指针参数去申请内存,那么应该改用“指向指针的指针”,
2. 变量作函数形参调用的时候都是要分配一个副本,不管是传值还是传址。传入后就和形参没有关系了,它不会改变形参的值。
注意指针所指向的内存是在函数内分配的还是在函数外分配的,以及是不是在堆上分配的。
你定义了一个指针,但是并没有分配指针指向对象所需的内存空间;当函数返回后,此函数栈中的内存会被释放掉,不要让指针指向此函数栈中的内存空间,要指向堆上或此函数外的内存空间。
代码范例:
- #include <stdio.h>
- #include <string.h>
-
- char *f_void(void);
- void f_1ptr(char *ret);
- void f_1ptr_o(char *ret);
- void f_2ptr(char **ret);
-
- int main()
- {
- char havec[] = "this is abcdefghijklmnopqrstuvwxyz";
- char *tmp;
- char **ret;
-
- ret = &tmp;
-
- tmp = f_void();
- printf("f_void():%s\n",tmp);
-
- printf("Before calling f_1ptr():havec = %s.\n",havec);
- f_1ptr(havec);
- printf("After calling f_1ptr():havec = %s.\n\n",havec);
-
- printf("Now try to output argument using single indirection pointer!\n");
- f_1ptr_o(tmp);
- printf("The output result is:%s", tmp);
- f_2ptr(ret);
- printf("%s\n",tmp);
-
- return 0;
- }
-
- char *f_void(void)
- {
- return "This function has no parameters.\n";
- }
-
- void f_1ptr(char *ret)
- {
- char *tmp;
-
- printf("Search for the 1st 'f' character in '%s'.\n", ret);
- if((tmp = index(ret,'f')) ==NULL)
- return ;
- *(tmp+1) = '\0';
- }
-
- void f_1ptr_o(char *ret)
- {
- char *t8;
-
- static char aa[] = "Output argument test!\n";
- t8 = ret;
-
- memcpy(t8, aa, sizeof(aa));
- }
-
- void f_2ptr(char **ret)
- {
- static char aa[] = "Output argument test!\n";
- *ret = aa;
- }
- 运行结果:<pre name="code" class="cpp">$ ./pointer2nd-test.exe
- f_void():This function has no parameters.
-
- Before calling f_1ptr():havec = this is abcdefghijklmnopqrstuvwxyz.
- Search for the 1st 'f' character in 'this is abcdefghijklmnopqrstuvwxyz'.
- After calling f_1ptr():havec = this is abcdef.
-
- Now try to output argument using single indirection pointer!
- The output result is:Output argument test!
- Output argument test!</pre>
- <pre></pre>
- <p></p>
- <pre></pre>
- <p></p>
- <p><span style="font-size:12px"><br>
- </span></p>