群友的一道题
class TestIt
{
public static void main ( String[] args )
{
int[] myArray = {1, 2, 3, 4, 5};
ChangeIt.doIt( myArray );
for(int j=0; j<myArray.length; j++)
System.out.print( myArray[j] + " " );
}
}
class ChangeIt
{
static void doIt( int[] z )
{
z = null ;
}
}
其实它很简单,不知道当时为什么就是想不通,刚刚想了想,用这个水一篇好了。
我翻译成了C++来分析这道题。
#include <bits/stdc++.h>
using namespace std;
class changeit
{
public:
static void doit(int* z)
{
z = NULL;
}
};
class testit
{
public:
int array[5];
testit() {
for (int i = 0;i < 5;i++)
{
*(array + i) = i + 1;
}
}
void main()
{
changeit::doit(array);
for (int i = 0;i < 5;i++)
{
cout << *(array + i) << endl;
}
}
};
int main()
{
testit b;
b.main();
}
问题的关键其实就是形参变实参不变,我陷入了“传入函数的参数是指针,实参就会跟着形参一起变动”的习惯误区,这个函数既没有return,也没有像典型的swap问题一样,形参是指向待修改的变量的指针(对这个问题而言,我们想修改的值是指针,所以形参的形式应该是指针的指针),函数体中间用*取值修改。实参的值当然不会变。
这个函数的形参依旧只是实参的一个拷贝,打印一下形参和实参的地址便可以知道:
如果想要达成“实参跟着改变成NULL,程序什么都不输出”的效果,可以改成熟知的“swap”模式——对参数再取个地址,函数体中用*符号修改实参。
#include <bits/stdc++.h>
using namespace std;
class changeit
{
public:
static void doit(int** z)
{
*z = NULL;
}
};
class testit
{
public:
int array[5];
testit() {
for (int i = 0;i < 5;i++)
{
*(array + i) = i + 1;
}
}
void main()
{
int* A = array;
changeit::doit(&A);
for (int i = 0;i < 5;i++)
{
cout << *(A + i) << endl;
}
}
};
int main()
{
testit b;
b.main();
}
至于为什么要在main函数中定义一个指针A,和指针array指向相同的地方,然后参数选择A呢,
一方面,参数类型对不上,在changeit::doit(&array);
中会报错,“int (*)[5]” 类型的实参与 “int **” 类型的形参不兼容。
而且本身array指针指向哪里这件事就不能修改——array是不能修改的左值。