首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

为什么程序无故修改数据成员解决思路

2012-02-19 
为什么程序无故修改数据成员这是一个猜数字的程序电脑想一个数,然后你输一个数,它告诉你猜对了几个数,猜对

为什么程序无故修改数据成员
这是一个猜数字的程序
电脑想一个数,然后你输一个数,它告诉你猜对了几个数,猜对了几个位置
下面是程序

//num.h
//Declaration of class Num
//Memeber functions are defined in Num.cpp

#ifndef NUM_H
#define NUM_H

class Num
{
public:
Num ( int = 4, int = 10 );
void setNum(); // Random number generator
void getNum(); // get the number guessed by the user
int getB(int,int);
bool compNum(); // compare the two numbers
void dispNum();
void dispRes(); // display the result
private:
int num1[];
int num2[];
int digit, carry;
int max, min;
int times;
};

#endif

//Num.cpp
//Memeber functions of Num.h
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "num.h"
using namespace std;

Num::Num ( int d, int c )
{
digit = d;
carry = c;
min = max = 1;
for ( int i = 0; ++i != digit; ) min *= carry;
max = min * carry - 1;
times = 0;
}

void Num::setNum()
{
srand( time( NULL ) );
for ( int i = 0; i++ != digit; ) num1[i] = rand() / ( RAND_MAX / carry + 1 );

while ( num1[1] == 0 ) num1[1] = rand() / ( RAND_MAX / carry + 1);
}

void Num::getNum() // store the bit into the array one after another
{
int num;
cout << "Time:" << ++times <<endl
<< "Please input the 4-digit decimal number you guessed" << endl;
cin >> num;
while ( ( num < min ) || ( num > max ) )
{ cout << "Out of range. Please input a number within the band." << endl;
cin >> num; }
for ( int i = 0; i++ != digit; ) num1[i] = getB ( num, i);
}

int Num::getB ( int n, int m ) // get the number in m bit of n, as the 2rd bit
 of 12345 is 4
{
if ( m-- == 1 ) return ( n % carry );
else return getB ( n / carry, m );
}

bool Num::compNum() // compare the two numbers
{
num1[0] = num2[0] = 0;
for ( int i = 0; i++ != digit; )
for ( int j = 0; j++ != digit; )
if ( num1[i] == num2[j] )
{ num1[0]++; break; }
for ( int i = 0; i++ != digit; ) num2[0] += ( num1[i] == num2[i] );
return (( num1[0] == digit ) && ( num2[0] == digit ));
}

void Num::dispNum()
{
cout << "Number correct: " << num1[0] << " "
<< "Position correct: " << num2[0] << endl << endl;
}

void Num::dispRes () // display the result
{
cout << endl << "Congratulations, you are correct!" << endl
<< "The number you got is:";
for ( int i = digit + 1 ; --i != 0; ) cout << num2[i];
cout << endl << "Times that you guessed:" << times;
}

//Guess.cpp
//4-digit decimal number guess programe
#include <iostream>
#include "num.h"
using namespace std;

int main()
{
  Num number;
  number.setNum();
  number.getNum();
  while ( !number.compNum() ) 
  { number.dispRes();
  number.getNum(); }
  number.dispRes();
  return 0;  
}

为什么在执行guess.cpp的时候,调试的时候发现运行到number.setNum()
digit carry max min 的值都被更改了 并没有涉及到更改他们的操作啊
times 也被更改 而且很没有逻辑的更改
把digit carry max min 用static_cast转换位const int类型之后仍然会被更改
这是问什么啊?????!

[解决办法]
通常是越界
[解决办法]
以下是我之前写的一个程序,看内容和楼主的差不多,在此抛砖引玉,希望可以对大家有所帮助。

C/C++ code
/* 输入字符串与随机取的字符串比较,字符和位置都正确方可退出程序。 在一长度为(n)的数组 C 中,存入从长度(m)的数组 A 中选出的(n)个字符,与第(8)题中生成的数组 B 的内容进行比较,输出比较结果。比较结果有一个"1",表示数组 C 中有一个字符的位置与数组 B 的相同;比较结果有一个"0",表示数组 C 中有一个字符与数组 B 的相同,但位置不同。 目的:通过思维过程图,将思维活动与程序的实现相结合要求:1)输出比较结果时,先输出"1",再输出"0"      2)直到输出结果为n个"1"时,程序才退出*/#include "stdlib.h"#include "stdio.h"#include "time.h"#include "math.h"#define X 50int main(void) {     char c[X];    char A[X]="abcdefghij";    int i,j,x;    int m=strlen(A);    int n=0;    /*A为要随机取字符的数组,m为要随机取字符的数组的长度,n为要随机取字符的个数,    x为中间变量,有时用来存放随机取到的1个数,有时用来存放临时字符数据.*/    time_t t;    srand((unsigned) time(&t));  /*产生随机数的时候用时刻变化着的时间t来控制产生的随机数序列在每次运行的时候都不一样。*/    while(n<=0)    {    printf("随机数发生器将从%s中为您随机取字符。\n",A);    printf("请输入您要随机取的字符的个数(>0的整数):");     scanf("%s",c);    n=atoi(c);    };     char B[n],C[n],d[n];    /*B为对比数组,用来存放随机字符串,C为比较数组,用来存放输入的字符串,d为结果显示数组,用来存放判断结果,    其中1表示字符和位置都相同,0表示字符相同但位置不相同,空格表示字符和位置都不相同。*/    for(j=0; j<n; j++)    {        x=rand()% m;        B[j]=A[x];    }     /*初始化对比数组B,用来存放随机取到的字符串*/      printf("\n要对比的字符串为:");     for(j=0; j<n; j++)        printf("%c",B[j]);    printf("\n备注:比较结果中1表示字符和位置都相同,0表示字符相同但位置不相同。\n");     while(1)    {              printf("\n请输入%d个字符进行比较:",n);        scanf("%s",C);           for(j=0; j<n; j++)            d[j]=' ';/*初始化结果显示数组*/          for(i=0;i<n;i++)/*具体的字符和位置的比较,将相应位置设置为1或0。*/        {            if(B[i]==C[i])/*判断字符和位置是否都相同,都相同结果显示数组中标志为1。*/               d[i]='1';        }        for(i=0;i<n;i++)            {            for(j=0;j<n;j++)            {                    if(B[i]==C[j])/*如果字符相同且已标志为1,则与跳出本次循环,用下一个进行比较;如果字符相同但未标志为1,则标志为0。*/                {                    if(d[i]=='1')                    {                        i++;                        continue;                    }                      else                      {                        d[i]='0';                    }                              }                       }  /*内层for循环结束。*/              }/*外层for循环结束。*/         for(i=0;i<n;i++)           for(j=i+1;j<n;j++)           {               if(d[i]<d[j])               {                   x=d[i];                   d[i]=d[j];                   d[j]=x;               }              }          /*对结果显示数组中的1、0和空格进行具体的排序(从大到小),         要求显示格式:1在前,0在后,空格在最后但是显示不出来。*/           printf("比较结果:");        for(i=0;i<n;i++)                printf("%c",d[i]);        for(i=0;i<n;i++)        {            if(d[i]=='1'&&i==(n-1))            {                printf("\n恭喜您!输入正确!\n");                                       exit(0);               }                else            {                if(d[i]=='1')                       continue;                 }       } /*判断是否全为1*/                    };} 


[解决办法]
因为int g[];中g并不是一个指针,它实际上代表的是该数组的第一个元素地址,因为没有声明数组大小,所以实际上数组大小为0;
但对有些编译器,当类或结构体大小为0时,自动插入一个字节。可以用struct A{}试试看看大小.

热点排行