我正在关注K& R第二版示例以学习C和编码,因为我认为这是正确的做事方式。无论如何,当我在编译后运行该程序时程序卡住了。我使用valgrind来执行编译脚本。
#include <ctype.h>
int atoi(char s[])
{
int i, n, sign;
for(i = 0; isspace(s[i]); i++)
;
sign = (s[i] == '-')? -1 : 1;
if (s[i] == '+'|| s[i] == '-')
i++;
for (int n = 0; isdigit(s[i]); n++)
n = 10 * n + (s[i]-'0');
return sign * n;
}
int main()
{
char input[] = " -12345";
atoi(input);
}
# vaibhavchauhan at startup001 in ~/Documents/Projects/K-R on git:master x [0:43:36]
$ valgrind ./atoi-general
==8075== Memcheck, a memory error detector
==8075== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==8075== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==8075== Command: ./atoi-general
==8075==
^C==8075==
答案 0 :(得分:3)
在第二个循环中,您正在迭代n
,但您使用i
进行计算和计算。这导致你观察到的无限循环。要解决此问题,请始终使用i
作为索引:
int atoi(char s[])
{
int i, sign, n;
for(i = 0; isspace(s[i]); i++)
;
sign = (s[i] == '-')? -1 : 1;
if (s[i] == '+'|| s[i] == '-')
i++;
for (n = 0; isdigit(s[i]); i++)
n = 10 * n + (s[i]-'0');
return sign * n;
}
请注意,索引应该具有类型size_t
,而不是int
,因为后者可能不足以索引每个数组。为此,类型int
的索引很好。
答案 1 :(得分:3)
注意到,第二个循环中的索引不正确。
for(int n = 0; isdigit(s[i]); n++)
n = 10 * n + (s[i]-'0');
这应该是 - 请注意你应该不要重新初始化第二个循环中的索引i
,因为它应该是第一个循环的剩余值(因为你已经跳过了白色)空间和标志)。
for( ; isdigit(s[i]); i++ )
n = 10 * n + (s[i]-'0');
答案 2 :(得分:3)
可以改进K&amp; R示例的可读性和性能。存在以下问题:
atoi
。size_t
应该用于迭代器,而不是int
。n
是迭代器的一个非常糟糕的名字!在C编程中,n
具有特殊含义,即描述容器中的项目数。-
两次。#include <ctype.h>
#include <stdbool.h>
int my_atoi (const char* str)
{
while(isspace(*str))
{
str++;
}
bool sign = false;
if(*str == '-')
{
sign = true;
str++;
}
else if(*str == '+')
{
str++;
}
int result = 0;
while(isdigit(*str))
{
result = 10*result + *str - '0';
str++;
}
if(sign)
{
result = -result;
}
return result;
}