37.指针与函数参数

由于C语言是以传值的方式将参数值传递给被调用函数,因此,被调用函数不能直接修改主调函数中变量的值。例如,排序函数可能会使用一个名为swap的函数来交换两个次序颠倒的元素。但是,如果将swap函数定义为下列形式:

void swap(int x,int y)  /*  错误定义的函数  */
{
     int temp;

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

则下列语句无法达到该目的。

swap(a,b);

这是因为,由于参数传递采用传值的方式,因此上述的swap函数不会影响到调用它的例程中的参数a和b的值。该函数仅仅交换了a和b的副本的值。

由于一元运算符&用来取变量的地址,这样&a就是一个指向变量a的指针。swap函数的所有参数都声明为指针,并且通过这些指针来间接访问它们指向的操作数。

void swap(int *p,int *py)    /*  交换*px和*py  */
{
     int temp;

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

指针参数使得被调用函数能够访问和修改主调函数中对象的值。我们来看这样一个例子,函数getint接受自由格式的输入,并执行转换,将输入的字符流分解成整数,且每次调用得到一个整数。getint需要返回转换后得到的整数,并且,在达到输入结尾时要返回文件结束标记。这些值必须通过不同的方式返回。EOF(文件结束标记)可以用任何值表示,当然也可一个输入的整数表示。

该版本的getline函数在到达文件结尾时返回EOF,当下一个输入不是数字时返回0,当输入中包含一个有意义的数字时返回一个正值。

#include 

int grtch(void);
void ungetch(int);
{
      int c,sign;

      while (isspace (c = getch()))    /*  跳过空白符  */
           ;
      if (lisdigit(c) && c != EOF && c != '+' && c != '-'){
          ungetch(c);    /*  输入不是一个数字  */
          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;
}

在getint函数中,*pn始终作为一个普通的整型变量使用。其中还使用了getch和ungetch两个函数。借助这两个函数,函数getint必须读入的一个多余字符就可以重新写回到输入中。

练习5-1:

#include 
#include 
 
int getch(void);
void ungetch(int);
 
/* getint: get next integer from input into *pn             */
int getint(int *pn)
{
    int c, d, sign;
    while(isspace(c = getch())); /*skip white space         */
    if(!isdigit(c) && c != EOF && c != '+' && c != '-')
    {
        ungetch(c);             /* it's not a number        */
        return 0;
    }
    sign = (c == '-') ? -1 : 1;
    if(c == '+' || c == '-')
    {
        d = c;              /* remember sign char           */
        if(!isdigit(c = getch()))
        {
            if(c != EOF)
                ungetch(c); /* push back non-digit          */
            ungetch(d);     /* push back sign char          */
            return d;       /* return sign char             */
        }
    }
    for(*pn = 0; isdigit(c); c = getch())
        *pn = 10 * *pn + c - '0';
    *pn *= sign;
    if(c != EOF)
        ungetch(c);
    return c;
    printf("%d\n",c);
}

练习5-2:

#include 
#include 
 
#define SIZE 10
#define BUFSIZE 10
 
int getch();
void ungetch(int c);
int getfloat(float *pn);
 
char buffer[BUFSIZE];
int bufp;
 
int main()
{
	int n;
	float array[SIZE];
	
	for (n = 0; n < SIZE; array[n++] = 0)
		;
	for (n = 0; n < SIZE && getfloat(&array[n]) != EOF; n++)
		;
	for (n = 0; n < SIZE; printf("%.2f ", array[n++]))
		;
 
	return 1;
}
 
 
int getfloat(float *pn) {
	
	int c, temp, sign;
 
	while (isspace(c = getch()))
		;
	if (!isdigit(c) && c != EOF && c != '+' && c != '-')
		return 0;
	sign = (c == '-') ? -1 : 1;
	if (c == '+' || c == '-') {
		if (!isdigit(temp = getch())) {    //如果‘+’,‘-’后面跟的不是数则出错
			while (!isdigit(c = getch()) && c != '-' && c != '+' && c != EOF)
				;    //如果后面跟的不是数的话直接定位到下一个数或者正负号
			ungetch(c);    //返回刚刚读取的数或符号等到下一次调用getfloat的时候使用
			return 0;
		}
		else
			c = temp;    //如果'-','+'后面紧跟的是数,则把刚刚因为判断而读取的值赋值给准备开始为数组赋值。c原来的值为'-'或者'+',此时已被赋值给了sign。
	}
	for (*pn = 0; isdigit(c); c = getch()) {
		*pn = 10 * *pn + (c - '0');
	}
	if (c == '.') {
		c = getch();
		for (; isdigit(c); c = getch())
			*pn += 0.1 * (c - '0');
	}
	*pn *= sign;
	if (c != EOF)
		ungetch(c);
 
	return c;
}
 
int getch()
{
	return (bufp > 0) ? buffer[--bufp] : getchar();
}
 
void ungetch(int c)
{
	if (bufp >= BUFSIZE)
		printf("oversized...\n");
	else
		buffer[bufp++] = c;
 
	return;
}
 

37.指针与函数参数_第1张图片

 

函数的返回值依然是int类型。

你可能感兴趣的:(c语言,c++)