兔子问题c语言

题目:

有一对兔子,从出生第3个月起每个月都生一对兔子,小兔子长到第3月后每个月又生一对兔子。假设所有兔子都不死,编程求第20个月总数为多少?

源代码:

//兔子问题
//#include <stdio.h>
//
//int main() {
//    int rab[31] = {1, 1};
//    int j = 2, i = 1;
//    for (rab[i] = 1; i < 31; i++) {
//        rab[j] = rab[i] + rab[i - 1];
//        printf("the %d month has rabbit %d\n", j, rab[j]);
//        j++;
//    }
//
//
//}

在vs和devc中得到了不同的结果,求原因,为未定义行为。

那什么是未定义行为呢?
包含多个不确定的副作用的代码的行为总是被认为未定义。编译器对于未定义行为可能不会报错,但是这些行为编译器会自行处理。
这里附上一个比较全面生动的阐述c语言的未定义行为(undefined behaviour)

这里又涉及到了另外两个知识点:序列点和副作用。

1.在c语言中存在一些符号会产生序列点,例如“ ,” “&& 和 || ”等。这些序列点会对左右的表达式运算存在影响,而影响主要指的是副作用的生效顺序。
2.如果一个表达式不仅算出一个值,还修改了环境(数据对象或者文件),就说这个表达式有副作用(因为它多做了额外的事)。比如:a++ 。
3.可参考C语言中的序列点和副作用(文章里说:“甚至都不要试图探究这些东西在你的编译器中是如何实现的,K&R 明智地指出,”如果你不知道它们在不同的机器上如何实现, 这样的无知可能恰恰会有助于保护你。” 结果我正好去研究了。。)

#于是我大致得出了如下结论#

由于printf函数中存在带着副作用的表达式,导致计算机在执行printf过程中判定其为未定义行为,于是不同的编译器对相同的一段代码产生了自己的编译行为,导致了执行顺序不同,最后输出结果也不同了。

Final,在了解以上知识点外,深刻认识到了一点————在写程序的时候绝不能按照自己想当然的想法去写代码,这会是极大的隐患,所以我们应该尽量避免这种情况的发生,而是应该写出让所有编译器只会存在一种处理方式的代码。
————————————————
版权声明:本文为CSDN博主「一涵涵一」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/shen962806862/article/details/83067457

1.数组定义问题

一维数组的初始化可以使用以下方法实现:
1) 定义数组时给所有元素赋初值,这叫“完全初始化”。例如:

 
  1. int a[5] = {1, 2, 3, 4, 5};

通过将数组元素的初值依次放在一对花括号中,如此初始化之后,a[0]=1;a[1]=2;a[2]=3;a[3]=4;a[4]=5,即从左到右依次赋给每个元素。需要注意的是,初始化时各元素间是用逗号隔开的,不是用分号。

2) 可以只给一部分元素赋值,这叫“不完全初始化”。例如:

 
  1. int a[5] = {1, 2};

定义的数组 a 有 5 个元素,但花括号内只提供两个初值,这表示只给前面两个元素 a[0]、a[1] 初始化,而后面三个元素都没有被初始化。不完全初始化时,没有被初始化的元素自动为 0。

需要注意的是,“不完全初始化”和“完全不初始化”不一样。如果“完全不初始化”,即只定义“int a[5];”而不初始化,那么各个元素的值就不是0了,所有元素都是垃圾值。
这里定义rab[31]后,再令rab[0]=0;出现了错误

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值