c++指针与函数参数传递---小结

来源:互联网 发布:java中的迭代器 编辑:程序博客网 时间:2024/06/04 23:25

1.函数参数传递的语义与初始化的语义完全一致,即可以将参数传递理解为一个初始化的等式


2.指针变量存储的是所指对象的地址,称为指针变量的值。


3.当用一个指针A初始化指针B时,指针B存储的是指针A所指对象的地址。

char *a = new char(10);char *b = a;


由于指针变量a,b指向同一个对象,那么它们都能改变所指对象的值。

<pre name="code" class="cpp"><pre name="code" class="cpp">a[0] = 'a';b[0] = 'b';cout<<b<<endl;//输出 ab


但是如果改变指针变量的值,也就改变指针所指的对象。那么a,b就没有联系。

a[0] = 'a';b[0] = 'b';a = "hello";cout<<a<<endl;//输出 hellocout<<b<<endl;//输出 ab

因此,想用指针操控一个变量,就需要持有该变量的地址,即指向该对象。


4.从指针变量的声明,如何知道该指针存储的是何种变量的地址?

(在C++ primer中有详细描述,从右往左阅读,变量名 是 一个指针,指向某变量---该变量的描述继续递归运用以上规则)

char*   a;//存储一个字符变量的地址

char** a;//存储一个指向字符变量的指针所在的地址


5.我的一个思维误区:混淆实参与形参。

形式参数是指在函数被调用时生成的临时变量,作用域在这个函数体内。

指针作为形式参数时,可以修改函数体的变量的值,但是该指针变量本身依然只是函数体作用域内的局部变量。

形参与实参的正确关系应当理解为:使用实参来初始化形参


6.当指针作为参数时,试图用指针对实参变量进行修改。

(1)需要想明白指针所指的对象是谁?

(2)想要修改实参变量,就要传递实参变量的地址,形参应当是指向实参变量的指针。

例子:

//字符串拼接

int main(){char *str1 = "hello";char *str2 = "world";char *str3 = 0;//没有给str3赋值cat(str1,str2,str3);cout<<str3<<endl;    //str3能输出吗?}void cat(char* str1,char* str2,char* str){char *p = str1;char *q = str2;str = new char(strlen(str1)+strlen(str2)+1);   //想在函数体中给str3分配新的内存空间,实际结果呢?char* s =*str; while (*p!='\0'){*s = *p;s++;p++;}while(*q!='\0'){*s =*q;s++;q++;}*s ='\0';<pre class="cpp" name="code">cout<<str<<endl;  //成功输出了拼接字符串}

在上面的例子中,我试图将str1和str2拼接成str3.
我的想法是将str3传入cat函数,然后在函数内给str3申请大小适当的空间,然后改变str3所指向地址的值。

然而这个想法不够仔细,是我错误的根源。我没想明白,究竟是将str3的什么传入函数中?str3的地址,还是str3所指的对象。

在上面的代码中,我只是将str3所指的对象传递给了函数调用时生成的临时变量,也就是是临时变量和str3指向了同一个地址,然后在函数体内改变这个临时变量的值,从此和外部的str3指向不同的地址。

当然,如果这个临时变量不更换地址,使用它确实可以改变str3所指对象的值,但是它不能改变str3的值。(因此可以现在函数外部分配适当空间,在传递str3所指的对象,那么程序便可以正确。)

所以,根据我的想法,对于cat的第三个参数,应当传入str3的地址,使得在函数内部可以改变str3的值。

因为str3是 char* 的变量,所以形参str的类型应当是 char** 。

正确的函数为:  

void cat(char* str1,char* str2,char** str3)

传递参数时,应当传递str3的地址,即&str3 。

等价的初始化式:

char**  str =&(str3)

在函数内部使用  *str 就可以获取str3的地址了。


7.总结

指针是用来操作变量的值的工具。指针变量自身的值就是所指对象的地址。

涉及到指针变量的时候,应当想清楚到底想要利用该指针变量操纵什么,指针应当指向什么。




1 0
原创粉丝点击