问什么一个全局变量会被无缘无故的改变

paulqiu0224 2013-05-21 08:12:35
题目是c++大学教程的第八章的课后习题8.12 题目大意就是一个龟兔赛跑游戏,赛道长为70个空格,每次生成一个随机数,根据生成的随机数决定龟和兔的移动,看谁先走完70个空格。

为什么在执行moveHare 这个函数的时候,函数体里面根本就没有有关于positionT这个全局变量的操作,但是我分别在函数的开始和结尾cout positionT的值,值就是被无缘无故的改变了。。。
好困扰啊,代码如下,thxxx!!!

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;

void moveTortoise ( int , char * );
void moveHare ( int , char * );

int positionT = 0;
int positionH = 0;
const int size = 70;

char line[ size ];

int main()
{
int timer = 1;
for( int i = 0; i < size; i++)
line[ i ] = ' ';
srand (time(0));

while ( (positionT < 69) && (positionH < 69) )
{
cout << timer << ". " << endl;
int randNum = 1 + rand() % 10;
cout << "randNum= " << randNum << endl;

moveTortoise ( randNum, line );
moveHare ( randNum, line );

if ( positionT == positionH )
{
line[ positionT ] = 'O';
line[ positionT + 1 ] = 'U';
line[ positionT + 2 ] = 'C';
line[ positionT + 3 ] = 'H';
line[ positionT + 4 ] = '!';
line[ positionT + 5 ] = '!';
line[ positionT + 6 ] = '!';
}

cout << line << "\n" << endl;
timer++;

for( int i = 0; i < size; i++)
line[ i ] = ' ';
}

if( positionT >= 69 )
cout << "TORTOISE WINS!!! YAY!!!" << endl;
if ( positionH >= 69 )
cout << "Hare wins. Yuch." << endl;
system("pause");
}

void moveTortoise ( int ran, char *linePtr )
{
if ( ran <= 5 && ran >= 1 )
{
positionT =positionT + 3;
linePtr[positionT ] = 'T';

}
else if ( ran <= 7 && ran >= 6 )
{
positionT= positionT - 6;
if( positionT < 0 )
positionT = 0;
linePtr[positionT ] = 'T';

}
else if ( ran <= 10 && ran >= 8 )
{
positionT =positionT + 1;
linePtr[ positionT ] = 'T';

}

}

void moveHare ( int ran, char *linePtr )
{
if ( ran <= 2 && ran >= 1)
{
linePtr[ positionH ] = 'H';

}
else if ( ran <= 4 && ran >= 3 )
{
positionH = positionH + 9;
linePtr[ positionH ] = 'H';

}
else if ( ran == 5 )
{
positionH = positionH - 12;
if ( positionH < 0 )
positionH = 0;
linePtr[ positionH ] = 'H';

}
else if ( ran <= 8 && ran >= 6 )
{
positionH = positionH + 1;
linePtr[ positionH ] = 'H';

}
else if ( ran <= 10 && ran >= 9 )
{
positionH = positionH - 2;
if ( positionH < 0 )
positionH = 0;
linePtr[ positionH ] = 'H';

}
}



...全文
341 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
lm_whales 2013-05-22
  • 打赏
  • 举报
回复
建议改成如下代码:

const int size = 70;
const int addsize =20;
char line[ addsize + size ];
while((positionT < size-1) && (positionH < size-1) )
{
 ...
 if ( positionT == positionH )
        {
            memcpy(line,"OCH!!!",min(addsize,strlen("OCH!!!"))); 
            //line[ positionT ] = 'O';
            //line[ positionT + 1 ] = 'U';
            //line[ positionT + 2 ] = 'C';
            //line[ positionT + 3 ] = 'H';
            //line[ positionT + 4 ] = '!';
            //line[ positionT + 5 ] = '!';
            //line[ positionT + 6 ] = '!';
        }
....
}
lm_whales 2013-05-22
  • 打赏
  • 举报
回复
int positionT = 0; int positionH = 0; const int size = 70; //这个是常量,不占用内存,或者放到常量区。 char line[ size ]; //line[68+6]=line[74] 数组早就越界了,这个数组只有70个元素,positionH是最有可能被改写的。 while ( (positionT < 69) && (positionH < 69) ) { 。。。 line[ positionT + 6 ] = '!'; 。。。 当 positionT=68;line[ positionT + 6 ]=line[74];positionH 很可能被改写了,line[74]positionT也可能被改写!!!!!
图灵狗 2013-05-22
  • 打赏
  • 举报
回复
数组越界之后产生的结果不可预料,深究下去是一种钻牛角尖的行为。
引用 8 楼 u010207374 的回复:
[quote=引用 1 楼 turingo 的回复:] 一般这种比较奇怪的现象都是数组访问越界而造成的,查查linePtr的下标有无越界的访问。
嗯嗯~THXXX~~!!确实是有越界,我把size改为100后就好了。但是有点不能理解为什么这边数组越界会影响到positionT的值哦?thx~[/quote]
赵4老师 2013-05-22
  • 打赏
  • 举报
回复
引用 15 楼 zhao4zhong1 的回复:
Setting a Breakpoint When a Variable Changes Value To set a breakpoint when a variable changes value 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type the name of the variable. 4. Click OK to set the breakpoint. Setting a Breakpoint When an Expression Changes Value To set a breakpoint when an expression changes value 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type an expression such as x+y. 4. Click OK to set the breakpoint. Setting a Breakpoint When an Expression Is True To set a breakpoint when an expression is true 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type an expression, such as x==3, that evaluates to true or false. 4. Click OK to set the breakpoint. Setting a Breakpoint on a Variable Outside the Current Scope To break on a variable outside the current scope 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type the variable name. 4. Select the drop-down arrow to the right of the text box. 5. From the menu that appears, click Advanced. The Advanced Breakpoint dialog box appears. 6. In the Expression text box, type the function name and (if necessary) the filename of the variable. 7. Click OK to close the Advanced Breakpoint dialog box. The information that you specified appears in the Expression text box in the Breakpoints dialog box. 8. In the Breakpoints dialog box, click OK to set the breakpoint. Note You can enter context information directly into the Expression field, using the advanced breakpoints syntax. For details, see Using Advanced Breakpoint Syntax. Setting a Breakpoint When the Initial Element of an Array Changes Value To break when the initial element of an array changes value 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type the first element of the array (myArray[0], for example). 4. In the Number Of Elements text box on the Data tab, type 1. 5. Click OK to set the breakpoint on myArray [0]. Setting a Breakpoint When the Initial Element of an Array Has a Specific Value To break when the initial element of an array has a specific value 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type an expression containing the initial element of the array (myArray[0]==1, for example). 4. In the Number Of Elements text box, type 1. 5. Click OK to set the breakpoint on myArray [0]. Setting a Breakpoint When a Particular Element of an Array Changes Value To break when a particular element of an array changes value 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type the element of the array (myArray[12], for example). 4. In the Number Of Elements text box, type 1. 5. Click OK to set the breakpoint on myArray [12]. Setting a Breakpoint When Any Element of an Array Changes Value To break when any element of an array changes value 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type the first element of the array (myArray[0]). 4. In the Number Of Elements text box, type the number of elements in the array. 5. Click OK to set the breakpoint on myArray. Setting a Breakpoint When Any of the First n Elements of an Array Change Value To break when any of the first n elements of an array change value 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type the first element of the array (myArray[0], for example). 4. In the Number Of Elements text box, type n (for example, 10). 5. Click OK to set the breakpoint on myArray[0] through myArray[9]. Setting a Breakpoint When the Location Value of a Pointer Changes To break when the location value of a pointer changes 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type the pointer variable name (p, for example). 4. Click OK to set the breakpoint. Setting a Breakpoint When the Value at a Location Pointed to Changes To break when the value at a location pointed to changes 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type the dereferenced pointer variable name (*p or p->next, for example). 4. Click OK to set the breakpoint. Setting a Breakpoint When an Array Pointed to by a Pointer Changes To break when an array pointed to by a pointer changes 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type the dereferenced pointer variable name (*p, for example). 4. In the Number Of Elements text box, type the length of the array in elements. For example, if the pointer is a pointer to double, and the array pointed to contains 100 values of type double, type 100. 5. Click OK to set the breakpoint. Setting a Breakpoint When the Value at a Specified Memory Address Changes To break when the value at a specified memory address changes 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type the memory address for the byte. For a word or doubleword memory address, enclose the address in parentheses, and precede it with a cast operator. For example, WO(21406036) for the word at memory location 21406036. Use the cast operator BY for a byte (optional), WO for a word, or DW for a doubleword. (The debugger interprets all integer constants as decimal unless they begin with zero (0) for octal or zero and x (0x) for hexadecimal.) 4. In the Number Of Elements text box, type the number of bytes, words, or doublewords to monitor. If you used the BY operator in the Expression field, specify the number of bytes. If you used WO, specify the number of words. If you used DW, specify the number of doublewords. 5. Click OK to set the breakpoint. Setting a Breakpoint When a Register Changes To break when a register changes 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type a register mnemonic, such as CS. 4. In the Number Of Elements text box, type the number of bytes to monitor. 5. Click OK to set the breakpoint. Setting a Breakpoint When a Register Expression Is True To break when a register expression is true 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type an expression that contains a boolean comparison operator, such as CS==0. 4. In the Number Of Elements text box, type the number of bytes to monitor. 5. Click OK to set the breakpoint. Note When you set a data breakpoint, the debugger places the variable or variables used into a special debug register, if possible. The number of debug registers is limited. (Intel 80386 and later CPUs provide four debug registers. Motorola 680X0 and PowerPC chips have no debug registers.) Furthermore, stacked-based variables (parameters) cannot be placed into debug registers. If a breakpoint variable cannot be placed into a debug register, the debugger must examine the variable’s memory location after every instruction to determine whether the contents have changed. These extra memory accesses reduce execution speed of the program with the debugger. In some cases, the program may appear to hang. Performance may be especially slow if you are debugging a remote application.
正解!
赵4老师 2013-05-22
  • 打赏
  • 举报
回复
Setting a Breakpoint When a Variable Changes Value To set a breakpoint when a variable changes value 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type the name of the variable. 4. Click OK to set the breakpoint. Setting a Breakpoint When an Expression Changes Value To set a breakpoint when an expression changes value 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type an expression such as x+y. 4. Click OK to set the breakpoint. Setting a Breakpoint When an Expression Is True To set a breakpoint when an expression is true 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type an expression, such as x==3, that evaluates to true or false. 4. Click OK to set the breakpoint. Setting a Breakpoint on a Variable Outside the Current Scope To break on a variable outside the current scope 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type the variable name. 4. Select the drop-down arrow to the right of the text box. 5. From the menu that appears, click Advanced. The Advanced Breakpoint dialog box appears. 6. In the Expression text box, type the function name and (if necessary) the filename of the variable. 7. Click OK to close the Advanced Breakpoint dialog box. The information that you specified appears in the Expression text box in the Breakpoints dialog box. 8. In the Breakpoints dialog box, click OK to set the breakpoint. Note You can enter context information directly into the Expression field, using the advanced breakpoints syntax. For details, see Using Advanced Breakpoint Syntax. Setting a Breakpoint When the Initial Element of an Array Changes Value To break when the initial element of an array changes value 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type the first element of the array (myArray[0], for example). 4. In the Number Of Elements text box on the Data tab, type 1. 5. Click OK to set the breakpoint on myArray [0]. Setting a Breakpoint When the Initial Element of an Array Has a Specific Value To break when the initial element of an array has a specific value 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type an expression containing the initial element of the array (myArray[0]==1, for example). 4. In the Number Of Elements text box, type 1. 5. Click OK to set the breakpoint on myArray [0]. Setting a Breakpoint When a Particular Element of an Array Changes Value To break when a particular element of an array changes value 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type the element of the array (myArray[12], for example). 4. In the Number Of Elements text box, type 1. 5. Click OK to set the breakpoint on myArray [12]. Setting a Breakpoint When Any Element of an Array Changes Value To break when any element of an array changes value 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type the first element of the array (myArray[0]). 4. In the Number Of Elements text box, type the number of elements in the array. 5. Click OK to set the breakpoint on myArray. Setting a Breakpoint When Any of the First n Elements of an Array Change Value To break when any of the first n elements of an array change value 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type the first element of the array (myArray[0], for example). 4. In the Number Of Elements text box, type n (for example, 10). 5. Click OK to set the breakpoint on myArray[0] through myArray[9]. Setting a Breakpoint When the Location Value of a Pointer Changes To break when the location value of a pointer changes 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type the pointer variable name (p, for example). 4. Click OK to set the breakpoint. Setting a Breakpoint When the Value at a Location Pointed to Changes To break when the value at a location pointed to changes 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type the dereferenced pointer variable name (*p or p->next, for example). 4. Click OK to set the breakpoint. Setting a Breakpoint When an Array Pointed to by a Pointer Changes To break when an array pointed to by a pointer changes 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type the dereferenced pointer variable name (*p, for example). 4. In the Number Of Elements text box, type the length of the array in elements. For example, if the pointer is a pointer to double, and the array pointed to contains 100 values of type double, type 100. 5. Click OK to set the breakpoint. Setting a Breakpoint When the Value at a Specified Memory Address Changes To break when the value at a specified memory address changes 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type the memory address for the byte. For a word or doubleword memory address, enclose the address in parentheses, and precede it with a cast operator. For example, WO(21406036) for the word at memory location 21406036. Use the cast operator BY for a byte (optional), WO for a word, or DW for a doubleword. (The debugger interprets all integer constants as decimal unless they begin with zero (0) for octal or zero and x (0x) for hexadecimal.) 4. In the Number Of Elements text box, type the number of bytes, words, or doublewords to monitor. If you used the BY operator in the Expression field, specify the number of bytes. If you used WO, specify the number of words. If you used DW, specify the number of doublewords. 5. Click OK to set the breakpoint. Setting a Breakpoint When a Register Changes To break when a register changes 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type a register mnemonic, such as CS. 4. In the Number Of Elements text box, type the number of bytes to monitor. 5. Click OK to set the breakpoint. Setting a Breakpoint When a Register Expression Is True To break when a register expression is true 1. From the Edit menu, click Breakpoints. 2. Click the Data tab of the Breakpoints dialog box. 3. In the Expression text box, type an expression that contains a boolean comparison operator, such as CS==0. 4. In the Number Of Elements text box, type the number of bytes to monitor. 5. Click OK to set the breakpoint. Note When you set a data breakpoint, the debugger places the variable or variables used into a special debug register, if possible. The number of debug registers is limited. (Intel 80386 and later CPUs provide four debug registers. Motorola 680X0 and PowerPC chips have no debug registers.) Furthermore, stacked-based variables (parameters) cannot be placed into debug registers. If a breakpoint variable cannot be placed into a debug register, the debugger must examine the variable’s memory location after every instruction to determine whether the contents have changed. These extra memory accesses reduce execution speed of the program with the debugger. In some cases, the program may appear to hang. Performance may be especially slow if you are debugging a remote application.
paulqiu0224 2013-05-22
  • 打赏
  • 举报
回复
引用 10 楼 turingo 的回复:
数组越界之后产生的结果不可预料,深究下去是一种钻牛角尖的行为。 [quote=引用 8 楼 u010207374 的回复:] [quote=引用 1 楼 turingo 的回复:] 一般这种比较奇怪的现象都是数组访问越界而造成的,查查linePtr的下标有无越界的访问。
嗯嗯~THXXX~~!!确实是有越界,我把size改为100后就好了。但是有点不能理解为什么这边数组越界会影响到positionT的值哦?thx~[/quote][/quote] 恩,好的,thxx~!!!
paulqiu0224 2013-05-22
  • 打赏
  • 举报
回复
引用 12 楼 lm_whales 的回复:
建议改成如下代码:

const int size = 70;
const int addsize =20;
char line[ addsize + size ];
while((positionT < size-1) && (positionH < size-1) )
{
 ...
 if ( positionT == positionH )
        {
            memcpy(line,"OCH!!!",min(addsize,strlen("OCH!!!"))); 
            //line[ positionT ] = 'O';
            //line[ positionT + 1 ] = 'U';
            //line[ positionT + 2 ] = 'C';
            //line[ positionT + 3 ] = 'H';
            //line[ positionT + 4 ] = '!';
            //line[ positionT + 5 ] = '!';
            //line[ positionT + 6 ] = '!';
        }
....
}
嗯嗯,我懂了,谢谢~!
paulqiu0224 2013-05-21
  • 打赏
  • 举报
回复
引用 7 楼 baichi4141 的回复:
“无缘无故的改变”首先该想到的就是数组越界 你每次操作linePtr[ positionH ]的时候,并没有检测positionH是否在数组大小的范围内
嗯嗯,确实是这个问题~谢谢!以后会注意的
paulqiu0224 2013-05-21
  • 打赏
  • 举报
回复
引用 1 楼 turingo 的回复:
一般这种比较奇怪的现象都是数组访问越界而造成的,查查linePtr的下标有无越界的访问。
嗯嗯~THXXX~~!!确实是有越界,我把size改为100后就好了。但是有点不能理解为什么这边数组越界会影响到positionT的值哦?thx~
baichi4141 2013-05-21
  • 打赏
  • 举报
回复
“无缘无故的改变”首先该想到的就是数组越界 你每次操作linePtr[ positionH ]的时候,并没有检测positionH是否在数组大小的范围内
paulqiu0224 2013-05-21
  • 打赏
  • 举报
回复
引用 3 楼 startservice 的回复:
在VS2008试了下LZ的代码,没发现positionT有改变。
不是每次都会出问题的,个别次会出问题,多运行几次就不对了
paulqiu0224 2013-05-21
  • 打赏
  • 举报
回复
引用 4 楼 u010784036 的回复:
positionT =positionT + 3; positionT= positionT - 6; 这些不就是对positionT的操作么
我是指在moveHare这个函数里面没有对positionT的操作,但是调用这个函数之后positionT的值就会有改变
u010784036 2013-05-21
  • 打赏
  • 举报
回复
positionT =positionT + 3; positionT= positionT - 6; 这些不就是对positionT的操作么
startservice 2013-05-21
  • 打赏
  • 举报
回复
在VS2008试了下LZ的代码,没发现positionT有改变。
anshiny 2013-05-21
  • 打赏
  • 举报
回复
真的不相信。
图灵狗 2013-05-21
  • 打赏
  • 举报
回复
一般这种比较奇怪的现象都是数组访问越界而造成的,查查linePtr的下标有无越界的访问。

64,652

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧