从头学C(44)指针与函数参数

0

我们知道,C语言中函数调用是以传值的方式将参数值传递给被调函数的,也就是说传递的是变量的值,而不是变量本身,因此被调函数不能修改主调函数中的变量的值。

但现在我们有了指针,这便不是个问题了。

第五章 指针与数组 >> 5.2 指针与函数参数

先来看一个排序时,交换两个元素顺序的例子:

void swap(int x, int y)   /* Wrong!!! */
{
        int temp;

        temp = x;
        x = y;
        y = temp;
}

以上是个错误的例子,调用 swap(a, b) 并不能达到我们想要的结果,因为这个 swap() 函数仅仅只是交换了 a 和 b 的副本的值,并没有将主调函数中的 a 和 b 的值调换。

解决办法是,将 a 和 b 的地址(也就是指针)作为参数传递给 swap 函数:

void swap(int *px, int *py)  /* interchange *px and *py */
{
        int temp;

        temp = *px;
        *px = *py;
        *py = temp;
}

调用 swap(&a, &b) 来实现 a 和 b 的值调换,因为通过指向 a 和指向 b 的指针,我们是间接地访问 a 和 b 的内存存储单元。通过下面这个图,可以看出实际变量与指针参数的关系:

C语言_指针与函数参数

指针参数使得被调函数能够访问和修改主调函数中对象的值。

再来看一个 getint 函数的例子。getint() 接受自由格式的输入,并执行转换,将输入的字符流分解成整数,且每次调用得到一个整数。而且 getint() 需要返回转换后得到的整数,且在到达输入结尾时要返回文件结束标记。

设计思路是:将标识是否到达文件结尾的状态作为 getint 函数的返回值,同时,利用一个指针参数存储转换后得到的整数,并传回给主调函数。

具体代码如下,这个版本的 getint 函数在到达文件结尾时返回EOF,当下一个输入不是数字时返回0,当输入中包含一个有意义的数字时返回一个正值:

#include <ctype.h>

int getch(void);
void ungetch(int);

/* getint: get next integer from input into *pn */
int getint(int *pn)
{
        int c, sign;

        while(isspace(c = getch()))   /* skip white space */
                ;   
        if(!isdigit(c) && c != EOF && c != '+' && c != '-') {
                ungetch(c);     /* it is not a number */
                return 0;
        }   
        sign = (c == '-') ? -1 : 1;
        if(c == '+' || c == '-')
                c = getch();
        for(*pn = 0; isdigit(c); c = getch())
                *pn = 10 * *pn + (c - '0');
        *pn *= sign;
        if(c != EOF)
                ungetch(c);
        return c;
}

*pn 始终作为一个普通的整型变量使用。其中还利用 getch 和 ungetch 函数,保证 getint 能确定读到的是一个完整整数且不影响下一次整数的读取。

这时,我们利用下面的循环语句调用 getint 函数,来给一个 int 类型 数组赋值:

int n, array[SIZE], getint(int *);

for(n = 0; n < SIZE && getint(&array[n]) != EOF; n++) ;

这里必须将 array[n]的地址传递给函数 getint,否则 getint() 将无法把转换得到的整数传回给主调函数。

Leave A Reply