读书人

C缺陷与圈套最后一个例子的疑问

发布时间: 2012-11-14 10:12:19 作者: rapoo

C缺陷与陷阱最后一个例子的疑问
代码如下

C/C++ code
voidprintnum (long n, void (*p) ()){     if (n < 0) {          (*p) ('-');          printneg(n, p);       }else          printneg(-n, p);}void printneg (long n, void (*p)()){    long q;    int r;       q = n / 10;    r = n % 10;    if (r > 0) {           r - = 10;           q++;       }      if (n <= -10)          printneg (q, p);       (*p)("0123456789"[-r]);}


程序例子说明 上面的程序接收两个参数: 一个long型整数和一个函数指针。这段程序的作用是把给出的long型整数转换为其10进制表示,并且对10进制表示中的每一个字符都调用函数指针所指向的函数。

问题如下

当n为负数时,取余运算n%10可能会得到一个正数。所有有这段代码
if (r > 0) {
r - = 10;
q++;
}
不明白的就是
r - = 10;
q++;
分别是什么意思。

我试着把n代入-13.
发现运算后,如何r是一个正数的话。
那么q = -1 r = 3
代入上面代码后
r 会是 -7
q++ 会是 0 了

这块怎么理解,难道和补码什么的有关吗?请高人指点下,基础知识比较薄弱。那两句代码什么意思,为什么这样处理会得到最后的正确结果返回 '-' '1' '3' 这样的字符。

[解决办法]
如你假设:
n=-13;

case1:
C/C++ code
void printneg (long n, void (*p)()){    long q;    int r;       q = n / 10;       // q = -13 / 10 = -1    r = n % 10;       // r = -13 % 10 = -3    if (r > 0) {      // if不成立           r - = 10;           q++;       }      if (n <= -10)          printneg (q, p);       (*p)("0123456789"[-r]);}
[解决办法]
负数除法和取余运算每种语言实现都不一样。
所以一般写这种函数一般都假设只处理非负整数。
[解决办法]
首先
(*p)("0123456789"[-r]);
这个p是个函数指针指向你要调用的函数,而【-r】表示你要取得这个字符串的第几个数,这题因为r为负数所以前面加上-号。

程序例子说明 上面的程序接收两个参数: 一个long型整数和一个函数指针。这段程序的作用是把给出的long型整数转换为其10进制表示,并且对10进制表示中的每一个字符都调用函数指针所指向的函数。

如输入138978890这个数则通过这个函数可以输出1,3,8,9,7,8,8,9,0

void
printnum (long n, void (*p) ())
{
if (n < 0) {//若为负数前面输出对符号进行所指向的函数p的调用
(*p) ('-');
printneg(n, p);
}else
printneg(-n, p);//若为正数,则将看成他的相反数即负数,因为没有进行负号调用所以无影响
}

void printneg (long n, void (*p)())//数的按位输出
{
long q;
int r;

q = n / 10;
r = n % 10;
if (r > 0) {/*这个部分应该是不同的编译系统处理不同吧,在vc6.0上,你将他注释掉也能得出正确结果*/
r - = 10;
q++;
}
if (n <= -10)//看是否为最后一位数,否则经行递归调用
printneg (q, p);
(*p)("0123456789"[-r]);//输出这个位的数
}

附上我测试的代码:
#include<stdio.h>

void f(char c)
{
printf("%c\n",c);
}


void printneg (long n, void (*p)(char));

void
printnum (long n, void (*p) (char))
{
if (n < 0) {
(*p) ('-');
printneg(n, p);
}else
printneg(-n, p);
}

void printneg (long n, void (*p)(char))
{
long q;
int r;

q = n / 10;
r = n % 10;
/*if (r > 0) {
r -=10;
q++;
}*/
if (n <= -10)
printneg (q, p);
(*p)("0123456789"[-r]);
}

void main()
{
printnum(-13,f);


}

读书人网 >C语言

热点推荐