我实现了atoi()函数!这是我的代码:
int my_atoi(char* pointer)
{
int result = 0;
char* pointer1;
multiplier = 1;
char sign = 1;
if(*pointer == '-')
sign =- 1;
pointer1 = pointer;
while(*pointer != '\0')
{
if(*pointer >= '0' && *pointer <= '9')
multiplier = multiplier * 10;
pointer = pointer + 1;
}
pointer = pointer1;
while(*pointer != '\0')
{
if(*pointer >= '0' && *pointer <= '9')
{
result = result + ( (*pointer%48) * multiplier);
multiplier = multiplier / 10;
}
pointer = pointer+1;
}
return (result * sign) / 10;
}我想知道是否有任何方法可以改善我的功能。我知道我的功能有问题。如果用户希望从char*转换为int这个字符串:"232-19“。那我该怎么办呢?任何建议都会很有帮助的!
发布于 2014-03-30 19:16:31
可以改进
的东西
multiplier?我假定,由于它不是在方法中声明的,所以它被声明为一个全局变量。尽量避免全局变量。全局变量的问题是,由于每个函数都可以访问这些变量,因此越来越难以确定哪些函数实际读取和写入了这些变量。要理解应用程序是如何工作的,您几乎必须考虑到修改全局状态的每个函数。这是可以做到的,但随着应用程序的发展,它将变得更加困难,几乎不可能(或者至少是完全浪费时间)。如果不依赖于全局变量,则可以根据需要在不同函数之间传递状态。这样,您就可以更好地理解每个函数所做的事情,因为您不需要考虑全局状态。因此,不要使用全局变量,而是在main()中初始化变量,并在必要时将它们作为参数传递给函数。在这种情况下,我认为根本不需要在函数之外使用multiplier,所以只需将其声明在函数中即可。sign应该是int,而不是char。isdigit()为您做艰苦的工作。这也将帮助您实现干原理。时间(*指针!= '\0') {if(*指针>= '0‘&& *指针<= '9')乘数=乘数* 10;指针=指针+ 1;}指针= pointer1;while(*指针!= '\0') {if(*指针>= '0’&& *指针<= '9') {结果+(指针%48)*乘法器;乘数=乘数/ 10;}指针= pointer+1;}看到两个循环是如何做几乎相同的事情的?下面是我如何通过使用isdigit()简化所有这些。而(等位数(*c )){值*= 10;值+= (int) (*c- '0');c++;}您循环遍历字符串中的字符,只要它们是数字。对于每个计数器,都要添加到要保留的计数器中--要添加的值是字符的整数值。这是通过从有关数字的ASCII值中减去'0'的ascii值来完成的。int),则结果是未定义的。修复非常简单,只需使用long long int来缓解这种情况。对于非常长的数字,我们仍然会遇到问题,但是修复这个问题,使函数按照预期的方式工作,会稍微复杂一些。char*修改到函数中。因此,将参数声明为常量。int my_atoi(const *指针)#include <stdio.h>
#include <assert.h>
#include <ctype.h>
long long int my_atoi(const char *c)
{
long long int value = 0;
int sign = 1;
if( *c == '+' || *c == '-' )
{
if( *c == '-' ) sign = -1;
c++;
}
while (isdigit(*c))
{
value *= 10;
value += (int) (*c-'0');
c++;
}
return (value * sign);
}
int main(void)
{
assert(5 == my_atoi("5"));
assert(-2 == my_atoi("-2"));
assert(-1098273980709871235 == my_atoi("-1098273980709871235"));
puts("All good."); // I reach this statement on my system
}发布于 2014-04-01 04:19:31
编辑
除了错误的行为外,atoi()等同于(int)strtol(nptr, (char **)NULL, 10)。strtol()接受前导空格。OP的my_atoi(char* pointer)没有。补救:
int my_atoi(const char* pointer) {
while (isspace((unsigned char) *pointer)) {
pointer++;
}
...下面描述了一种处理INT_MIN的好方法。
OTOH,[INT_MIN...INT_MAX]之外的处理值不是由C规范定义的,因此可以进行一些简化。看下面很远。
当字符串表示INT_MIN (假设32位int) (例如"-2147483648" )时,代码会遇到int溢出,试图计算2147483648。一个简单的方法来解决这一点,不是找到积极的价值,然后否定它,拥抱事物的消极方面。通过在INT_MIN到0范围内完成最大的数学运算,我们避免了UB。缺点:有些人认为这种方法更难遵循。
转到更宽的整数或unsigned,并不总是可能的,因为“text-> integer”例程的整数大小可能是最大的大小。严格地说,unsigned并不总是有一个比int更宽的积极范围。在任何情况下,所有的数学都可以按所需的有符号整数大小处理,而无需求助于其他类型。
#include <ctype.h>
#include <limits.h>
int my_atoi(const char* pointer) { // good idea to make the `const`
int result = 0;
while (isspace((unsigned char) *pointer)) {
pointer++;
}
char sign = *pointer;
if (*pointer == '-' || *pointer == '+') { // text could lead with a '+'
pointer++;
}
int ch;
// isdigit() expects an unsigned char or EOF, not char
while ((ch = (unsigned char)(*pointer)) != 0) {
if (!isdigit(ch)) break;
ch -= '0';
// Will overflow occur?
if ((result < INT_MIN/10) ||
(result == INT_MIN/10 && ch > -(INT_MIN%10))) Handle_Overflow();
result *= 10;
result -= ch; // - , not +
pointer++;
}
if (sign != '-') {
if (result < -INT_MAX) Handle_Overflow();
result = -result;
}
return result;
}备注:
pointer%48令人困惑。48有什么特别之处?如果您的意思是'0',那么使用pointer % '0'。
字符串:"232-19“。那我该怎么办?建议在" 232“处停止转换,并返回值232。可以设置errno,但是典型的atoi()函数不会做太多的错误处理。
在溢出时,可能会发生设置errno的情况,但同样,典型的atoi()函数不会执行太多错误处理。建议简单返回INT_MAX或INT_MIN。
如果您想要更好的错误处理,请更改为如下所示,并设置错误状态。
int my_atoi(const char *s, int *ErrorCode);或者事情结束的地点。如果这是好的,他们在'\0'结束。
int my_atoi(const char *s, const char **endptr); 编辑简化:删除超出范围的检测,因为C规范允许这样做.“如果不能表示结果的值,则未定义行为。
int my_atoi(const char* pointer) {
int result = 0;
while (isspace((unsigned char) *pointer)) {
pointer++;
}
char sign = *pointer;
if (*pointer == '-' || *pointer == '+') {
pointer++;
}
while (isdigit((unsigned char)*pointer)) {
result = result*10 - (*pointer++ - '0');
}
if (sign != '-') {
result = -result;
}
return result;
}发布于 2016-11-16 16:44:55
char sign = *pointer;
if (*pointer == '-' || *pointer == '+') {
pointer++;
}为什么不引用“指针”三次?一次就够了:
char sign = *pointer;
if (sign == '-' || sign == '+') {
pointer++;
}https://codereview.stackexchange.com/questions/45755
复制相似问题