你有什么批评、纠正或改进吗?
我只需要读数字(这个数字可以是0到1000000)。
void fast_input(int* int_input)
{
*int_input=0;
char next_char=0;
while( next_char < '0' || next_char > '9' ){ // Skip non-digits
next_char = getchar();
}
while( next_char >= '0' && next_char <= '9' )
{
(*int_input) = ((*int_input)<<1) + ((*int_input)<<3) + next_char - '0';
next_char = getchar();
}
}发布于 2022-04-01 20:46:53
你有什么批评、纠正或改进吗?
在文件结束时,第一个while循环将永远循环.
更好的代码将永远防止循环,返回的不是void,而是成功的标志。
int诉chargetchar()返回一个int,通常是257个不同的值。保存在char中将丢失信息。保存在int中,以正确区分EOF和其他字符。
一个好的编译器会发出最优的代码。
// (*int_input) = ((*int_input)<<1) + ((*int_input)<<3) + next_char - '0';
*int_input = *int_input * 10 + + next_char - '0';输入/输出是时间的水槽。在那里有很大的时间改进,而不是试图使用<而不是*。
为了更好地处理其他例程,最后一次非数字读取( ungetc() )更常见.
签名的int溢出是未定义的行为(UB)。
是的,OP有“只需要读取数字(这个数字可以从0到1000000)",但是这个限制在代码中没有注释。所以下一个人会打开这个代码并运行到UB中。
注释代码中的重要限制。
更好的是,检测潜在的溢出。
int ch = getchar();
if (*int_input >= INT_MAX/10 &&
(*int_input > INT_MAX/10 || ch - '0' > INT_MAX%10)) {
// Overflow!
*int_input = INT_MAX;
} else {
*int_input = *int_input * 10 + + next_char - '0';
} int sum = 0;
... most of code
*int_input = sum;isdigit()考虑一下isdigit()而不是2比较。
未经测试--但至少给OP一个关于上述反馈的想法。
#include <ctype.h>
#include <limits.h>
// Return EOF on end-of-file or input error without reading an int.
// Return 0 on overflow. Value is capped.
// Return 1 on success.
// Save value read if int_input is not NULL
int fast_input_alt(int *int_input) {
int sum = 0;
int ch;
// Skip non-digits
while ((ch = getchar()) != EOF && !isdigit(ch)) {
;
}
if (ch == EOF) {
return EOF;
}
int retval = 1;
do {
ch -= '0';
if (sum >= INT_MAX / 10 && (sum > INT_MAX / 10 || ch > INT_MAX % 10)) {
sum = INT_MAX;
retval = 0; // Overflow
} else {
sum = sum * 10 + ch;
}
ch = getchar();
} while (isdigit(ch));
ungetc(ch, stdin);
if (int_input) {
*int_input = sum;
}
return retval;
}https://codereview.stackexchange.com/questions/275436
复制相似问题