指针

对于初学C语言的朋友,除了觉得指针有点神秘之外,最大的问题之一可能是理解指针到底是用来干什么的。


我会回答说:“指针绝对是必不可少的,我们会一直使用,请相信我”,你可能会丢我砖头(说不定还有西红柿和鸡蛋) :P ,因为我说了等于没说。


好吧,我会给你一个问题,你会发现假如不用指针是不能解决的。这个问题有点类似我们这一课的引子。在这一课的结尾我们还会重新来谈这个问题,并看一下用我们马上要学到的知识如何解决。


问题是这样:

我要写一个函数,它返回两个值。


“这不可能!” 你会理直气壮地说。


确实啊,之前我们学过:一个函数只能通过return返回一个值:


int function()

{

return value;

}


如上,我们将函数的返回值类型定为int,那么就用return返回一个int类型的值。


我们也可以不返回任何值,只要把函数的返回值类型定为void:


void function()

{

}


你会说:“是啊,要一个函数一次返回两个值,不可能啊,我们不能写两个return啊。臣妾做不到啊...”


假设我要写的这个函数是这样:

我们给它输入的参数是一个分钟数,它返回给我们两个值:小时数和分钟数。例如:

传给函数30,它返回0小时30分钟

传给函数60,它返回1小时0分钟

传给函数90,它返回1小时30分钟


我们可以试着来写一下这个函数:


#include <stdio.h>


/* 我把函数原型放在开头了,并没有用到.h头文件,因为程序实在太小了。当然在正常情况下,一般是用.h头文件比较好 */

void transformMinutes(int hours, int minutes);


int main(int argc, char *argv[])

{

int hours = 0, minutes = 90;


/* 我们的分钟数是 90。我想要在调用transformMinutes函数后,小时数变为1,分钟数变为30 */

transformMinutes(hours, minutes);


printf("%d 小时 : %d 分钟\n", hours, minutes);


return 0;

}


void transformMinutes(int hours, int minutes)

{

hours = minutes / 60;   // 90 / 60 = 1

minutes = minutes % 60;  // 90 % 60 = 30

}


看上去还不错对么?我们来运行一下这个程序。输出:


0 hours and 90 minutes


不对,不对,这个函数没有按照我们所想的来运行嘛!


到底这里发生了什么呢?

事实上,C语言的函数参数默认是传值调用的,就是说当我们传给函数的参数一个变量时,事实上传递的是这个变量的一份拷贝,并不是这个变量本身!程序会先对这个要传递给函数的变量做一份拷贝,然后把这份拷贝传给函数使用。


所以说:上面我们main函数里的hours变量和实际传给transformMinutes函数的hours,是不一样的,传给transformMinutes函数的只是hours变量的一个拷贝而已。就好比用复印机复印了一份纸张,内容是一样,但是一个是原件,一个是复印件。


当然了,我们的函数transformMinutes很乖很呆萌,你叫它干的活它肯定出色完成:在函数内部,它把参数hours和minutes的值通过计算转换成了1和30。


但是,注意了,因为transformMinutes拿到的两个参数hours和minutes的值本身只是实际的变量hours和minutes的一份拷贝。而且我们之前学过,在函数结束时,它里面的非static变量都会销毁,所以hours和minutes这两个拷贝就都会被删除了。


所以函数transformMinutes勤勤恳恳地工作之后,把程序交还给main函数继续执行,但是hours和minutes这两个main函数里的变量的值并没有被改变,还是0和90。可惜啊!


注意:函数的参数的名字和要传给它的变量的名字不需要是一样的,上例中我们为了清楚表示含义,才把main函数里的两个变量和函数transformMinutes的两个参数都命名为hours和minutes,其实你大可以把函数的参数写成随便什么名字,例如


void transformMinutes(int h, int m)


简而言之,问题还是在那里。


这里我们需要用函数来改变两个变量的值,我们不能用return,因为一个函数只能return一个返回值;也不能用全局变量,虽然全局变量行得通,但是我们之前的课已经说了,尽量不用这种不安全的变量。


那么指针到底能怎样来解决我们的难题呢?我们慢慢道来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值