一、修改基本类型变量(short、int、long、char、float、double)
相信大家最开始学习函数的时候都遇到过这个经典问题:
x=2;
y=1;
void switch1(int x, int y)
{
int tmp;
tmp = x;
x = y;
y = tmp;
}
调用函数后在主函数中输出结果:
该函数的本意是通过函数交换两个数的值,可是在调用后函数的值并未发生改变,这是因为该函数参数的传递方式为值传递:
值传递(passl-by-value)过程中,被调函数的形式参数作为被调函数的局部变量处理,即在堆栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。
如果要通过函数调用而改变实参的值,则需要如下方法:
x=2;
y=1;
void switch2(int &x, int &y)
{
int tmp;
tmp = x;
x = y;
y = tmp;
}
该方法被成为引用传递
引用传递(pass-by-reference)过程中,被调函数的形式参数虽然也作为局部变量在堆栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过堆栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。
因数组的类型较为特殊 本篇不作详解 有兴趣请看下文博客
(34条消息) 为什么传递基本类型的参数,在函数中进行修改不会影响到调用者的值,而数组则会被影响?_小腿子的博客-CSDN博客
二、修改指针的值
因为在大一大二时学的不够细致,一直以为函数的形参如果是指针就可以通过函数改变实参的值,结果再刷数据结构书的时候
typedef struct Node
{
struct Node* next=NULL;
char data;
}Node,*NodeList;
int nodelength(Node *str)
{
int length=0;
while (str->next != NULL)
{
str = str->next;
length++;
}
return length;
}
这段代码让我陷入沉思,我以为当while循环中的str被不断改为他的next结点时,主函数中的str也会随之改变,自己验证一遍后发现
int main()
{
Node* str1 = new Node;
str1->data = 'L';
str1->next = new Node;
str1->next->data = 'o';
nodelength(str1);
cout<<str1->data;
}
看来结果不然,这是因为指针变量,其实也就是一个变量,但它的值是一块内存的地址。
函数调用时,你只是把实参指针变量的值,即一块内存的地址,赋(复制)给了形参,然后,你在函数内把形参指针指向别的内存空间地址,与实参指针就无关了,实参指针还是指向原来的那块内存空间。
另外,你把实参指针变量的值,赋(复制)给了形参,然后形参指针就能操纵这块内存了,可以改变这块内存的容。此时,实参指针指向的那块内存的内容也就改变了,但实参指针的值还是函数调用前的那块内存空间的地址。
那么如何改变指针的值呢?
既然指针也是一个变量,我要在函数内部改变它,那么就传递一个指向ptr的指针!也就是二级指针!
void change4(int** t, int* q)
{
*t = q;
}
int main()
{
int x = 2;
int y = 1;
int* q = &y;
int* p = &x;
int** t = &p;
cout << "change:" << endl;
if (p == q)
cout << "equal!";
else
cout << "not equal!";
return 0;
}
或者使用传引用的方式
void change3(int *&p, int* q)
{
p = q;
}
int main()
{
int x = 2;
int y = 1;
int* q = &y;
int* p = &x;
change3(p, q);
cout << "change:" << endl;
if (p == q)
cout << "equal!";
else
cout << "not equal!";
return 0;
}
希望能帮到大家!