对于一个只用C写十几二十行程序的菜鸟,也能遇到这样那样诡异郁闷的问题,其实知道点底层也挺好的。先说这个问题:
#include <stdio.h>
#include <malloc.h>
#define max(a,b) ((a)>(b)?(a):(b))
int computeMax(int [], int);
int main() {
int array[10] = {1,-1,2,2,3,-3,4,-4,5,-5};
/*printf("\n");*/
printf("%d\n", computeMax(array, 10));
return 0;
}
int computeMax(int a[], int length) {
int i,j,result;
int la[length-1], ra[length-1];
la[0] = a[0],ra[length-2] = a[length-1];
for(i=1;i<length-2;i++)
la[i] = max(la[i-1]+a[i], a[i]);
for(i=length-3;i>=0;i--)
ra[i] = max(ra[i+1]+a[i+1], a[i+1]);
result = la[0]+ra[1];
for(i=0;i<length-1;i++)
for(j=i;j<length-1;j++)
result = max(la[i]+ra[j], result);
return result;
}
这个程序解决什么问题的就不罗嗦了,不重要……代码中有一句被注释了,这段代码有这两种执行情况:
A:把注释去掉
B:带注释执行
我linux下的编译环境是gcc (GCC) 4.7.0 20120507 (Red Hat 4.7.0-5),编译选项是-Wall -std=c99 -g -lm
computeMax的正确返回值是13,执行A结果是1175124475,执行B结果是13。很显然A的结果是个乱七八糟的东西。如果其他不变,把computeMax函数改成这样:
int computeMax(int a[], int length) {
int i,j,result;
int *la=(int *)malloc((length-1)*sizeof(int)), *ra=(int *)malloc((length-1)*sizeof(int));
la[0] = a[0],ra[length-2] = a[length-1];
for(i=1;i<length-2;i++)
la[i] = max(la[i-1]+a[i], a[i]);
for(i=length-3;i>=0;i--)
ra[i] = max(ra[i+1]+a[i+1], a[i+1]);
result = la[0]+ra[1];
for(i=0;i<length-1;i++)
for(j=i;j<length-1;j++)
result = max(la[i]+ra[j], result);
free(la);
free(ra);
return result;
}
也就是将数组的直接声明换成malloc分配,不管是否去掉注释,均输出正确结果。如果把程序改成这样:
#include <stdio.h>
#include <malloc.h>
#define max(a,b) ((a)>(b)?(a):(b))
int computeMax(int [], int);
int main() {
int array[10] = {1,-1,2,2,3,-3,4,-4,5,-5};
int a = computeMax(array,10);
/*printf("\n");*/
printf("%d\n", a);
return 0;
}
int computeMax(int a[], int length) {
int i,j,result;
int la[length-1], ra[length-1];
la[0] = a[0],ra[length-2] = a[length-1];
for(i=1;i<length-2;i++)
la[i] = max(la[i-1]+a[i], a[i]);
for(i=length-3;i>=0;i--)
ra[i] = max(ra[i+1]+a[i+1], a[i+1]);
result = la[0]+ra[1];
for(i=0;i<length-1;i++)
for(j=i;j<length-1;j++)
result = max(la[i]+ra[j], result);
return result;
}
也就是把computeMax的返回值放到一个变量中,并且赋值操作在被注释语句之前完成,那么被注释的语句对执行结果也没有什么影响。
其实还可以做一些测试,比如在computeMax中返回之前输出一下result。结果也不相同。
一个简单的printf("\n")换行就能有这样的影响?把代码贴到网上,别人执行也没遇到这问题,很让我困惑。自己猜测可能是由于内存空间被污染了,用malloc自己分配释放空间,就没有问题,如果用程序自动分配就有问题。具体也说不上来什么,还得更细的分析,如果有高手知道具体可能是哪里出了问题,麻烦告知一下。
PS:http://www.iteye.com/topic/1105480感觉这个问题和上面的问题很像。
分享到:
相关推荐
C语言之Main函数返回值问题分析: 很多人甚至市面上的一些书籍,都使用了void main( ) ,其实这是错误的。C/C++ 中从来没有定义过void main( ) 。C++ 之父 Bjarne Stroustrup 在他的主页上的 FAQ 中明确地写着 The ...
中,如果不关心a[]的哪一个分量会被写入,这段代码就没有问题,i也的确会增加1,对吗? 3.11 人们总是说i=i++的行为是未定义的。可我刚刚在一个ANSI编译器上尝试过,其结果正如我所期望的。 3.12 我不想学习那些...
我们知道C语言函数的返回值是通过函数中的return语句来实现的,可是每调用一次函数,return语句只能返回一个值。那么当我们希望从一个函数中返回多个值时,用什么方法去实现比较合理呢?在教学过程中,我建议学生...
中,如果不关心a[]的哪一个分量会被写入,这段代码就没有问题,i也的确会增加1,对吗? 38 3.11 人们总是说i=i++的行为是未定义的。可我刚刚在一个ANSI编译器上尝试过,其结果正如我所期望的。 38 3.12 我不...
函数作表达式中的一项出现在表达式中,以函数返回值参与表达式的运算。这种方式要求函数是有返回值的。例如: z=max(x,y)是一个赋值表达式,把max的返回值赋予变量z。'Next of Page 2.函数语句 函数调用的一般...
难道在C语言中一个结构不能包含指向自己的指针吗? . . . . 3 1.7 怎样建立和理解非常复杂的声明?例如定义一个包含N 个指向返 回指向字符的指针的函数的指针的数组? . . . . . . . . . . . . . . 3 1.8 函数只定义...
o 7.1 我在一个源文件中定义了 char a[6], 在另一个中声明了 extern char *a 。为什么不行 ? o 7.2 可是我听说 char a[ ] 和 char *a 是一样的。 o 7.3 那么, 在 C 语言中 ``指针和数组等价" 到底是什么意思 ? ...
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、...【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。
免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累... 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,本人不对所涉及的版权问题或内容负法律责任。如有侵权,请举报或通知本人删除。
14. C语言函数二维数组传递方法 64 15. C语言复杂表达式的执行步骤 66 16. C语言字符串函数大全 68 17. C语言宏定义技巧 89 18. C语言实现动态数组 100 19. C语言笔试-运算符和表达式 104 20. C语言编程准则之稳定篇...
免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累... 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,本人不对所涉及的版权问题或内容负法律责任。如有侵权,请举报或通知本人删除。
C语言和C++的区别 (1)面向过程语言和面向对象语言 C语言是面向过程语言,即先分析出解决...C语言中如果一个函数没有指定返回值类型,默认返回int类型;C++中如果一个函数没有返回值则必须指定为void (5)函数重载
实训是在学生已经具备了使用C语言编写简单的应用程序的能力,为使学生对C语言有更全面的理解,进一步提高运用C语言编程解决实际问题的能力,通过提出算法、指定输入输出来设计一个解决方案。并为参加计算机等级考试...
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、...【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。
免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累... 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,本人不对所涉及的版权问题或内容负法律责任。如有侵权,请举报或通知本人删除。
11.3.3 作为函数返回值的结构 426 11.3.4 修改程序 430 11.3.5 二叉树 433 11.4 共享内存 442 11.4.1 联合 442 11.4.2 联合指针 444 11.4.3 联合的初始化 444 11.4.4 联合中的结构成员 444 11.5 定义自己的...
14. C语言函数二维数组传递方法 64 15. C语言复杂表达式的执行步骤 66 16. C语言字符串函数大全 68 17. C语言宏定义技巧 89 18. C语言实现动态数组 100 19. C语言笔试-运算符和表达式 104 20. C语言编程准则之稳定篇...