无符号long long的C ++代码中的奇怪数据损坏

时间:2015-08-30 10:29:27

标签: c++

我正在编写一个非常简单的测试程序来反转输入数字的数字并将其提升到相反的位置。我在所有操作中使用无符号long long来打印结果输出中的所有数字。以下是代码的头文件:

#include <iostream>
#include <cstdlib>
#include <cmath>

class userinput{

        public:
                userinput(unsigned long long);
                ~userinput();
                unsigned long long reverse ();
                unsigned long long raise_to_reverse ();

        private:
                userinput();
                userinput(const userinput&);
                void operator=(const userinput&);

        private:
                unsigned long long value;
                unsigned int numDigits;
                unsigned long long revValue;
                unsigned long long result;

        private:
                void calc_numDigits();
                unsigned long long iPow ();


};

以下是.cpp文件,包含所有函数定义:

#include "program.h"


userinput::userinput(unsigned long long value){

        this->value = value;
        this->revValue = 1ULL;
        this->result = 1ULL;
        calc_numDigits();
}


userinput::~userinput(){

}


unsigned long long userinput::reverse (){ 

        if(1 < this->numDigits){
                unsigned long long number = this->value;


                for( ; number!= 0 ; ){

                        this->revValue = this->revValue * 10; 
                        this->revValue = this->revValue + number%10;
                        number = number/10;
                }
        }
        else{

                this->revValue = this->value;
        }

        return this->revValue;
}


void userinput::calc_numDigits(){

        this->numDigits = (unsigned int) std::log10 (this->value) + 1 ; 
}



unsigned long long userinput::iPow(){

        while(this->revValue)
    if (this->revValue & 1ULL)
                {
                        this->result *= this->value;
                }
                this->revValue >>= 1;
                this->value *= this->value;
        }
        return this->result;
}



unsigned long long userinput::raise_to_reverse(){

        return iPow();
}
`                                

以下是main.cpp中的代码:

   #include "program.h"


int main (){ 

        unsigned long long input;
        unsigned long long maxValue = 99999;

START:
        std::cout << "Enter a number between 0 and 99999 (exlusive):" << std::endl;
        std::cin >> input;

        if(input <= 0 || input >= maxValue){

                std::cerr << "Inadmissible value entered. Please try again." << std::endl;
                goto START;
        }   

        userinput number(input);

        std::cout << "Raising " << input << " to " << number.reverse() << " gives " << number.raise_to_reverse() << std::endl;

        return 0;
}

现在我遇到的问题是,当我使用命令行的输入值构造一个对象时,该值被复制而没有任何问题到成员变量&#34; value&#34;构造函数中的userinput类对象。这是相同的gdb输出:

    Enter a number between 0 and 99999 (exlusive):
1234

Breakpoint 1, userinput::userinput (this=0x7fffffffde00, value=1234) at program.cpp:6
6       this->value = value;
Missing separate debuginfos, use: debuginfo-install glibc-2.15-56.fc17.x86_64 libgcc-4.7.0-5.fc17.x86_64 libstdc++-4.7.0-5.fc17.x86_64
(gdb) n
7       this->revValue = 1ULL;
(gdb) p this->value
$1 = 1234
(gdb) n
8       this->result = 1ULL;
(gdb) n
9       calc_numDigits();
(gdb) p this->value
$2 = 1234
(gdb) n

但是当作为下一步的一部分从main()调用函数userinput :: reverse()时,先前存储的数量在变量&#34; value&#34;在代码中没有明显原因被另一个数量覆盖。这是gdb输出:

 Enter a number between 0 and 99999 (exlusive):
1234

Breakpoint 1, userinput::reverse (this=0x7fffffffde00) at program.cpp:20
20      if(1 < this->numDigits){
Missing separate debuginfos, use: debuginfo-install glibc-2.15-56.fc17.x86_64 libgcc-4.7.0-5.fc17.x86_64 libstdc++-4.7.0-5.fc17.x86_64
(gdb) p this->value
$1 = 1522756
(gdb) 

如输出中所示,1234的原始值已被1522756覆盖,因为没有明显的代码。谁能指出这里出了什么问题?它与我使用unsigned long long的方式有关吗?

任何建议都会深表感谢。

感谢 维诺德

1 个答案:

答案 0 :(得分:2)

发生了什么

15227561234*1234,在

中设置
this->value *= this->value;

为什么

你错过了:

std::cout << a << b;

等同于:

operator<<(operator<<(std::cout, a), b);

由于标准未指定参数评估的顺序,您实际上在raise_to_reverse()之前调用reverse()(这特定于您的编译器及其设置,不要依赖它)。

修复

将输出语句分成两部分以保证正确的评估顺序:

std::cout << "Raising " << input << " to " << number.reverse();
std::cout << " gives " << number.raise_to_reverse() << std::endl;