由于C语言以按值调用的方式将变元传递给函数,因而被调用函数不能直接更改调用函数中的变量的值。
例如下面的swap函数就是错误的:
swap(a,b);
void swap(int x,int y)//错误的函数定义
{
int temp;
temp=y;
y=x;
x=temp;
}
由于按值调用,上swap函数将不会影响调用它的程序中的变元的值,只交换临时变量区中的对应的临时拷贝的值。若想得到预期的结果,应该将所要交换值得指针传递给被调用函数swap,即:
swap(&a,&b);
void swap(int *px,int *py)
{
int temp;
temp=*px;
*px=*py;
*py=temp;
}
对应的图形描述如下:
#include "stdio.h"
//#include "getint.c"
#include "ctype.h"//isdigit ispace
#define SIZE 10
main()
{
int n,array[SIZE],getint(int *);
for (n=0;n<SIZE&&getint(&array[n])!=EOF;n++)
;
// int i=0;
for (n=0; n<10; n++)
printf("%d\n", array[n]);
//return 0;
}
int getch(void);
void ungetch(int);
//get next integer from the input into *pn
int getint(int *pn)
{
int c,sign;
while(isspace(c=getch()))/*skip the white space*/
;
if(!isdigit(c)&&c!=EOF&&c!='+'&&c!='-'){/*it is not a number EOF + - */
ungetch(c);/*put character back on input */
return 0;
}
sign=(c=='-')?-1:1;/*positive or negative*/
if(c=='+'||c=='-')
c=getch();/*get the next character*/
for(*pn=0;isdigit(c);c=getch())
*pn=10**pn+(c-'0');
*pn *=sign;
if(c!=EOF)
ungetch(c);
return c;
}
#define BUFSIZE 100
char buf[BUFSIZE];
int bufp = 0;
int getch(void)
{
return (bufp > 0) ? buf[--bufp] : getchar();
}
void ungetch(int c)
{
if (bufp >= BUFSIZE)
printf("ungetch: too many characters\n");
else
buf[bufp++] = c;
}
这个版本的getintt函数当遇到文件结尾时返回E O F,当下一个输入不是一个数字时返回0,当在输入中包含一个有意义的数字时返回一个正数。
练习5-1 在上面的例子中,函数getint将后面不跟数字的一个+或-视为0的有效表达方式。通过将+或-写回输入流的方法来解决这个问题。
假如输入的为+d,则符号位sign=1;c=getch()后c=d,*pn=0,即getint函数返回0,然后将d压入输入堆栈,供下一次getint使用。
int getint(int *pn)
{
int c,d,sign;
while(isspace(c=getch()))/*skip the white space*/
;
if(!isdigit(c)&&c!=EOF&&c!='+'&&c!='-'){/*it is not a number EOF + - */
ungetch(c);/*put character back on input */
return 0;
}
sign=(c=='-')?-1:1;/*positive or negative*/
if(c=='+'||c=='-'){
d=c;
if(!isdigit(c=getch()))
{
if(c!=EOF)
ungetch(c);
ungetch(d);
return d;
}
}
c=getch();/*get the next character*/
for(*pn=0;isdigit(c);c=getch())
*pn=10**pn+(c-'0');
*pn *=sign;
if(c!=EOF)
ungetch(c);
return c;
}
思想是多取一位,判断是否为数字,如果不是数字后者输入结束EOF就将其压入输入堆栈,然后将符号压入输入堆栈,并将其值返回,从而结束getint调用。
练习5-2 模仿函数g e t i n t的实现方法,写一个浮点转换函数getfloat。getfloat函数返回值的类型是什么?
int float(float *pn)
{
int c sign;
float power;
while(isspace(c=getch()))/*skip the white space*/
;
if(!isdigit(c)&&c!=EOF&&c!='+'&&c!='-'){/*it is not a number EOF + - */
ungetch(c);/*put character back on input */
return 0;
}
sign=(c=='-')?-1:1;/*positive or negative*/
if(c=='+'||c=='-')
c=getch();/*get the next character*/
for(*pn=0.0;isdigit(c);c=getch())
*pn=10.0**pn+(c-'c'); //interger
if(c=='.')
c=getch();
for(power=1.0;isdigit(c);c=getch()) //fractional
{
*pn=10.0**pn+(c-'c');
power*=10.0;
}
*pn *=sign/power; //final number
if(c!=EOF)
ungetch(c);
return c;
}
返回值为int型,因为返回EOF或浮点数后边的字符的ASCII值,应该为int型。