user-0 提问: C程序设计语言的练习1-19，又莫名出错了

回复:
user: user-0
content: 呵呵，编程这东西真的是要不得半点马虎，否则失之毫厘谬以千里。谢了，钻研一下您给出的参照帖子去。

user: user-1
content: 引用 3 楼 u013696899 的回复:[quote=引用 2 楼 sr1992102 的回复:] int reverse(char str1[], char str2[]) //翻转字符串的子程序  {     int i;     for (i = strlen(str1); i >= 0; i--){    //strlen(*)计算数组长度不会计算'\0'，所以不需要-1         str2[strlen(str1) - 1 - i] = str1[i];     }         str2[strlen(str1) ] = '\0'; //给字符串2加上结束标志，str2没有结束标志，所以不能直接用strlen(*)来计算str2的长度，可间接地通过计算str1的长度得到str2的长度。                return 0; } 您一针见血指出了问题之所在。关键果然是str2没有\0的时候，取其长度是不准确的。改为取str1的长度后，计算结果正确了。 但还有一事不明。您提到上面一句不需要 -1，我把 -1 去掉以后，计算的结果也是正确的，不过有一点尚不理解。 举例说明。假如str1的值是“abcdefgh”，则其长度是8。那么第五行：str2[strlen(str1) - 1 - i] = str1[i]; 在计算的时候，strlen(str1) - 1 - i = 8 - 1 - 8 = -1，赋值就变成了str2[-1] = str1[8]。为字符数组并不存在的-1位赋值，为什么系统不会出错呢？ 谢谢！[/quote]  引用 3 楼 u013696899 的回复:[quote=引用 2 楼 sr1992102 的回复:] int reverse(char str1[], char str2[]) //翻转字符串的子程序  {     int i;     for (i = strlen(str1); i >= 0; i--){    //strlen(*)计算数组长度不会计算'\0'，所以不需要-1         str2[strlen(str1) - 1 - i] = str1[i];     }         str2[strlen(str1) ] = '\0'; //给字符串2加上结束标志，str2没有结束标志，所以不能直接用strlen(*)来计算str2的长度，可间接地通过计算str1的长度得到str2的长度。                return 0; } 您一针见血指出了问题之所在。关键果然是str2没有\0的时候，取其长度是不准确的。改为取str1的长度后，计算结果正确了。 但还有一事不明。您提到上面一句不需要 -1，我把 -1 去掉以后，计算的结果也是正确的，不过有一点尚不理解。 举例说明。假如str1的值是“abcdefgh”，则其长度是8。那么第五行：str2[strlen(str1) - 1 - i] = str1[i]; 在计算的时候，strlen(str1) - 1 - i = 8 - 1 - 8 = -1，赋值就变成了str2[-1] = str1[8]。为字符数组并不存在的-1位赋值，为什么系统不会出错呢？ 谢谢！[/quote]  那里的确是我想错了，想当然的去掉了 -1，造成了数组越界。 关于数组越界，LZ可以参照这个帖子  http://bbs.csdn.net/topics/300215352

user: user-0
content: 引用 6 楼 zhao4zhong1 的回复:代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。 所言极是。在下当埋头钻研，遇到实在无法解决的有价值问题再做必要询问。谢谢。

user: user-2
content: 代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。

user: user-0
content: 第四行赋值的时候，如果赋为strlen(str1)，比起赋值为strlen(str1) - 1要多经历一次循环，而就是这第一次循环过程中出现的str2[-1]让我不解。是不是这一次循环因为是对数组本身并不存在的 -1 位进行赋值而被系统跳过了，所以两种方案的计算结果都是正确的呢？

user: user-3
content: 引用 2 楼 sr1992102 的回复:int reverse(char str1[], char str2[]) //翻转字符串的子程序  {     int i;     for (i = strlen(str1); i >= 0; i--){    //strlen(*)计算数组长度不会计算'\0'，所以不需要-1         str2[strlen(str1) - 1 - i] = str1[i];     }         str2[strlen(str1) ] = '\0'; //给字符串2加上结束标志，str2没有结束标志，所以不能直接用strlen(*)来计算str2的长度，可间接地通过计算str1的长度得到str2的长度。                return 0; } strlen(*)不计算‘\0’的长度没错，但我们需要计算遍历字符数组，其下标是从0-strlen(*)-1。因此，第四行i赋值为strlen(str1)-1才是是正确的。

user: user-0
content: 引用 2 楼 sr1992102 的回复:int reverse(char str1[], char str2[]) //翻转字符串的子程序  {     int i;     for (i = strlen(str1); i >= 0; i--){    //strlen(*)计算数组长度不会计算'\0'，所以不需要-1         str2[strlen(str1) - 1 - i] = str1[i];     }         str2[strlen(str1) ] = '\0'; //给字符串2加上结束标志，str2没有结束标志，所以不能直接用strlen(*)来计算str2的长度，可间接地通过计算str1的长度得到str2的长度。                return 0; } 您一针见血指出了问题之所在。关键果然是str2没有\0的时候，取其长度是不准确的。改为取str1的长度后，计算结果正确了。 但还有一事不明。您提到上面一句不需要 -1，我把 -1 去掉以后，计算的结果也是正确的，不过有一点尚不理解。 举例说明。假如str1的值是“abcdefgh”，则其长度是8。那么第五行：str2[strlen(str1) - 1 - i] = str1[i]; 在计算的时候，strlen(str1) - 1 - i = 8 - 1 - 8 = -1，赋值就变成了str2[-1] = str1[8]。为字符数组并不存在的-1位赋值，为什么系统不会出错呢？ 谢谢！

user: user-1
content: int reverse(char str1[], char str2[]) //翻转字符串的子程序  {     int i;     for (i = strlen(str1); i >= 0; i--){    //strlen(*)计算数组长度不会计算'\0'，所以不需要-1         str2[strlen(str1) - 1 - i] = str1[i];     }         str2[strlen(str1) ] = '\0'; //给字符串2加上结束标志，str2没有结束标志，所以不能直接用strlen(*)来计算str2的长度，可间接地通过计算str1的长度得到str2的长度。                return 0; }

user: user-4
content: char string2[MAX];这句没给变量初始化，可以这么写char string2[MAX]={0};