C ++中的一元操作

时间:2012-12-04 01:38:35

标签: c++ function variable-assignment unary-operator

我遇到了一个编程问题,我只知道答案的一部分。

int f( char *p )
{
int n = 0 ;
while ( *p != 0 )
n = 10*n + *p++ - '0' ;
return n ;
}

这就是我认为该计划正在做的事情。 p是一个指针而while循环是DE-refrencing指针的值,直到它等于0.但是我不明白n赋值行,'0'在做什么?我假设p的值最初是负的,这是增量后它达到0的唯一方法。

4 个答案:

答案 0 :(得分:3)

您将数字零(无,无)与字符0(一个圆圈,可能带有斜线)混淆。请注意,零位于刻度线中,因此它是字符“0”,而不是数字零。

'0' - '0'= 0
'1' - '0'= 1
'2' - '0'= 2
......

因此,通过从数字中减去字符零,您将获得与该数字对应的数字。

所以,假设你有这个数字序列:'4','2','1'。你怎么从那里得到这个数字441?你将'4'变为四。然后你乘以十。现在你有四十岁了。将'2'转换为两个并添加它。现在你有四十二岁。乘以十。将“1”转换为一个,然后添加,现在你有一百二十一个。

这就是将数字序列转换为数字的方法。

答案 1 :(得分:2)

n局部变量累积在字符串中传递给此函数的十进制数的值。这是atoi的实现,没有有效性检查。

以下是循环体的工作原理:

n = 10*n + *p++ - ‘0';

n的先前值乘以10加上指针n的当前字符代码减去零代码的结果分配给p;在解除引用后增加p

由于数字字符是按顺序编码的,因此*p-'0'表达式表示数字的十进制值。

假设您正在解析字符串"987"。当你完成循环时,n从零开始;然后它被赋予以下值:

n = 10*0 + 9;  // That's 9
n = 10*9 + 8;  // That's 98
n = 10*98 + 7; // That's 987

答案 2 :(得分:1)

至少可以这么写。

0)使用格式化!:

int f(char* p)
{
    int n = 0;

    while (*p != 0)
        n = 10*n + *p++ - ‘0?;

    return n;
}

1)?语法无效。它应该是一个',如chris所述(你现有的也是错误的,但这可能是因为你从网站而不是源文件中复制了它),给出了:

int f(char* p)
{
    int n = 0;

    while (*p != 0)
        n = 10 * n + *p++ - '0';

    return n;
}

2)参数类型不应该像它应该的那样。因为*p永远不会被修改(根据我们的目标),我们应该强制执行以确保我们不犯任何错误:

int f(const char* p)
{
    int n = 0;

    while (*p != 0)
        n = 10 * n + *p++ - '0';

    return n;
}

3)原始程序员显然对可读代码过敏。让我们分开我们的行动:

int f(const char* p)
{
    int n = 0;

    for (; *p != 0; ++p)
    {
        const int digit = *p - '0';
        n = 10 * n + digit;
    }

    return n;
}

4)现在操作更加明显,我们可以看到这个函数中嵌入了一些独立的功能;这应该被分解出来(这称为反应)到一个单独的函数中。

即,我们看到converting a character to a digit

的操作
int todigit(const char c)
{
    // this works because the literals '0', '1', '2', etc. are
    // all guaranteed to be in order. Ergo '0' - '0' will be 0,
    // '1' - '0' will be 1, '2' - '0' will be 2, and so on.

    return c - '0';
}

int f(const char* p)
{
    int n = 0;

    for (; *p != 0; ++p)
        n = 10 * n + todigit(*p);

    return n;
}

5)现在很明显,该函数逐个字符地读取字符串,并逐位生成一个数字。此功能已exists under the name atoi, and this function is an unsafe implementation

int todigit(const char c)
{
    // this works because the literals '0', '1', '2', etc. are
    // all guaranteed to be in order. Ergo '0' - '0' will be 0,
    // '1' - '0' will be 1, '2' - '0' will be 2, and so on.

    return c - '0';
}

int atoi_unsafe(const char* p)
{
    int n = 0;

    for (; *p != 0; ++p)
        n = 10 * n + todigit(*p);

    return n;
}

它作为练习留给读取检查溢出,无效字符(那些不是数字),等等。但是这应该让正在发生的事情变得更加清晰,并且首先应该如何编写这样的函数。

答案 3 :(得分:1)

这是一个字符串到数字转换功能。与atoi类似。

字符串是一系列字符。所以内存中的“123”将是: '1', '2', '3',NULL

p指向它。

现在,根据ASCII,digits are encoded from '0' to '9'。 '0'被赋值48,'9'被赋值57.因此,'1','2','3',内存中的NULL实际上是:49,50,51,0

如果要将字符“0”转换为整数0,则必须从内存中的值中减去48。你知道这是怎么回事吗?

现在,不是减去数字48,而是减去'0',这使得代码更容易阅读。