程序员编程C语言指针答疑:值传递 PK 址传递

2019-12-23 19:12发布

给你下述C程序代码:

void exchange1(int para1,int para2)
{
 int temp;
 temp = para1;
 para1 = para2;
 para2 = temp;
}
void exchange2(int *pInt1,int *pInt2)
{
 int *temp = NULL;
 *temp = *pInt1;
 *pInt1 = *pInt2;
 *pInt2 = *temp;
}
void exchange3(int *pInt1,int *pInt2)
{
 int *temp;
 temp = pInt1;
 pInt1 = pInt2;
 pInt2 = temp;
}
void exchange4(int *pInt1,int *pInt2)
{
 int temp;
 temp = *pInt1;
 *pInt1 = *pInt2;
 *pInt2 = temp;
}
int main(void)
{
 int para1 = 1, para2 = 2;
 exchange1(para1, para2);
 exchange2(¶1, ¶2);
 exchange3(¶1, ¶2);
 exchange4(¶1, ¶2);
}

这几个函数里,哪几个函数可以实现main函数中的para1和para2的交换?

1、“己他”概念和“星指组合”概念来解题

这道C语言指针题看上去让人“眼花缭乱”,其实使用我提出的C语言指针“己他”概念和“星指组合”来解这道题是很简单的。有关C语言指针的“己他”概念和“星指组合”概念在我的专栏:

的第九章和第十章有详细的阐述,有兴趣的同学可以阅读这两章:

这道C语言指针试题就会用到“己他”概念中的“己值”、“他值”和“星指组合”的概念!

简单来说,这些概念的意思分别如下:

1.1 “己X”概念

“己X”分为己型、己址和己值。

“己型”:就是C语言指针自己的类型;

“己址”:就是C语言指针自己的地址;

“己值”:就是C语言指针自己的数据值;

1.2 “他X”概念

“他X”概念分为他型、他址和他值。

“他型”:就是C语言指针指向的对象的类型;

“他址”:就是C语言指针指向的对象的地址;

“他值”:就是C语言指针指向的对象的数据值;

1.3 “星指组合”概念

“星指组合”就是“星号”+“指针变量”的组合,这种组合的意思就是获取指针变量的他值!

2、C程序代码

我来把这道C语言指针题扩展成一段C程序代码,如下:

111

C函数定义

222

C程序

有四个函数,分别试图交换main函数中的两个参数,我们来看看运行结果:

333

C程序运行结果

3、C程序代码分析

3.1 分析1

在C程序代码的exchange2函数中,参数指针变量pInt1的己值是int变量para1的地址,参数指针变量pInt2的己值是int变量para2的地址。我们来看13行到15行:

第13行:*temp = *pInt1;
第14行: *pInt1 = *pInt2;
第15行: *pInt2 = *temp;

第13行,我们通过“星指组合”拿到了指针变量pInt1的他值和指针变量temp的他值,并且试图把pInt1的他值给temp的他值!

要知道指针变量temp刚开始的己值是NULL,这是空值的意思,请问此时temp的他值是什么呢?答案是:内存地址是NULL的这块地皮上的数据值,至于是什么数据值,没人知道,也许是一个非常重要的数据值。那么你想用pInt1的他值来覆盖掉这个数据值,操作系统会答应吗?当然不会,所以在运行的时候会给你一个大大的“运行时”错误!

第14行代码没问题的,这是通过“星指组合”拿到了指针变量pInt2的他值和指针变量pInt1的他值,并且试图把pInt2的他值给pInt1的他值,这是可以的!

第15行代码没问题的,这是通过“星指组合”拿到了指针变量temp的他值和指针变量pInt2的他值,并且试图把temp的他值给pInt2的他值,这是可以的!

你看,在main函数中我也把exchange2函数给注释掉了,因为运行时这个函数肯定运行报错!

3.2 分析2

在C程序代码的exchange3函数中,参数指针变量pInt1的己值是int变量para1的地址,参数指针变量pInt2的己值是int变量para2的地址。我们来看20行到22行:

第20行:temp = pInt1;
第21行: pInt1 = pInt2;
第22行: pInt2 = temp;

1)、第20行,我们把指针变量pInt1的己值给了指针变量temp的己值,此时pInt1的己值和temp的己值都是para1的地址;

2)、第21行,我们把指针变量pInt2的己值给了指针变量pInt1的己值,此时pInt1的己值和pInt2的己值都是para2的地址;

3)、第22行,我们把指针变量temp的己值给了指针变量pInt2的己值,此时pInt2的己值和temp的己值都是para1的地址;

经过这三步,最后的结果就是参数指针变量pInt1的己值变成了para2的地址,而参数指针变量pInt2的己值变成了para2的地址,仅仅是pInt1和pInt2的己值发生交换,而para1和para2的值并没有发生交换。而要实现main函数中para1和para2的交换,必须得是pInt1和pInt2的他值发生交换才行

3.3 分析3

在C程序代码的exchange4函数中,参数指针变量pInt1的己值是int变量para1的地址,参数指针变量pInt2的己值是int变量para2的地址。我们来看27行到29行:

第27行:temp = *pInt1;
第28行: *pInt1 = *pInt2;
第29行: *pInt2 = temp;

1)、第27行,我们通过“星指组合”拿到了指针变量pInt1的他值,也就是para1的值:1,并且给了int变量temp。此时指针变量pInt1的他值是1,temp的值也是1;

2)、第28行,我们通过“星指组合”拿到了指针变量pInt1的他值,也就是para1的值:1,pInt2的他值,也就是para2的值:2,并且把pInt2的他值“2”给了pInt1的他值,此时指针变量pInt1的他值,也就是para1的值就变成了2,pInt2的他值,也就是para2的值还是2;

3)、第29行,我们把temp的值1给了通过“星指组合”拿到的指针变量pInt2的他值,也就是para2的值,此时指针变量pInt2的他值就变成1,也就是para2的值变成1;

所以你看exchange4函数中,pInt1和pInt2的他值发生交换,才实现了main函数中para1和para2的交换。而在exchange2和exchange3中均未做到这一点。

这道C语言指针试题看上去难,其实也是绕不开我提出的“己他”概念和“星指组合”概念,所以我一直跟同学们说“C语言指针就是个纸老虎”!