int main(){
void fuzhi(int *,int);
int *t,k;
//t=(int *)malloc(3*sizeof(int));
scanf("%d",&k);
fuzhi(t,k);
printf("%d\t%d\t%d\n",*t,*(t+1),*(t+2));
return 0;
}
void fuzhi(int *t,int k){
t=(int *)malloc(3*sizeof(int));
*t=k;
*(t+1)=k+1;
*(t+2)=k+2;
}
这段代码的编译不会报错,0错误0警告,但是执行的时候就是有问题。原因在于对于指针函数的理解没有到位,指针函数会指针变量作为函数,我们知道通过指针函数就可以直接对元素据进行操控没有了形参和实参的传值。但是真的是这样吗?其实不是,还是会有形参和实参的传值发生的。指针变量的形参和实参法发生了传值。我们把指针作为函数变量的时候,其实是这样的:函数体在知道它的形参里有一个是指针变量,它不管指着指针指向哪,它都会按照我们安排好的模式对这个指针指向的地址里面的内容进行操控。那么它怎么知道这个这正指向哪里呢?就是在函数被调用的时候我们告诉它的。所以还是发生了了一个指针值传递的过程。我们可以通过指针取消我们想要操控的内容在函数调用是值传递过程,代价是发生一次指针变量的值传递。所以但我们想要操控的对象是指针自身的时候,上面的代码就有问题了。我们上面代码中,main函数中的t指针,没有初始化,函数体里面的t指针是一个auto的局部变量,在函数调用的过程中,这个局部指针变量t被复制了,但是main函数里面的t没变啊,发生的其实是这样的事情:t2=t1;t2=(。。。)malloc(。。。);t1表示main中的t,t2表示函数体里面的t,我们可以看到在函数被调用的时候就有问题了,t1的值被赋予t2,而t1本身自己都没有被初始化。但是t2在后面的malloc中又被赋予了一个合法值。不过这都无关紧要,因为函数调用结束的时候,t2就消失了。从头到尾,t1就没有被赋值过。而后面的打印语句实际上就是在试图使用一个没有初始化的指针,程序会发生运行时错误。所以我们可以把代码改成这样:
int main(){
void fuzhi(int *,int);
int *t,k;
t=(int *)malloc(3*sizeof(int));
scanf("%d",&k);
fuzhi(t,k);
printf("%d\t%d\t%d\n",*t,*(t+1),*(t+2));
return 0;
}
void fuzhi(int *t,int k){
//t=(int *)malloc(3*sizeof(int));
*t=k;
*(t+1)=k+1;
*(t+2)=k+2;
}
这时候是这样的,在main中指针t1被初始化了,指向一个六个字节的空间的首地址。加入是123456把,在函数被调用的时候,这个被调用的函数占据一个别的空间,在这个空间里面有一个指针变量t2,main函数和这个被调用函数发生一个指针变量的值传递,t2=t1,t2也等于123456了。然后t=k,就是让空间123456~123457存被穿过来的k的值,t就等价于12345和123459这两个字节的空间,存放k+1这个值。剩下的就是一样的过程了。然后函数结束,t2这个变量消失,这个函数所占用的空间也被释放。main函数里面的指针t的值也没变,还是哪个6个字节的空间的首地址。不多对这块空间上的操作实实在在发生了,用t,(t+1),*(t+2)打印出来的就是我们输入的值K,K+1,K+2了。
我觉得使用指向指针的指针应该也是可以解决这个问题的。具体的还没想好,又思路的评论区见。