运行结果是随机数——我帮你解决

    xiaoxiao2022-07-07  198

    很多道友都会有疑问:我的程序看起来没有问题呀,逻辑也没有问题,为什么运行结果是个随机数呢?不知道正在看这篇文章的你有没有遇到同样类似的问题呢? 接下来,我就梳理一下导致随机数的常见原因:

    1、变量没有初始化 这是很多道友忽略的一个问题。在某些情况下,不初始化不会产生问题;但在某些情况下,不初始化就会产生问题。

    例如:输入n,计算1到n的所有数字之和。

    #include<stdio.h> int main() { int n,sum; scanf("%d",&n); for(int i=1; i<=n; i++) sum+=i; printf("%d\n",sum); return 0; }

    运行结果如下: 得到的sum值是18,这明显不对,整个程序的逻辑没有问题,问题在于sum没有初始化。因此,需要初始化sum的值为0,即:sum=0; 运行的结果如下: 此外,程序中的数组分为全局数组与局部数组,它们的默认值是不同的。 以下面的程序说明:

    #include <stdio.h> int a[5]; int main() { printf("数组a的值为:\n "); for(int i=0;i<5;i++){ printf("%d ",a[i]); } printf("\n"); int b[5]; printf("数组b的值为:\n "); for(int i=0;i<5;i++){ printf("%d ",b[i]); } return 0; }

    运行结果如下: 从上面的结果可以看出,数组a的值均为0,而数组b的值却是随机数。

    原因如下:数组a是全局数组,数组b是局部数组。局部数组放在栈区,栈的操作就是入栈和出栈.当我们声明数组,其实只是移动栈顶指针.而栈内的数据是上一次出栈时候遗留的数据,栈不会清空,所以数据是随机的。而全局数组放在静态区,编译器默认用数值0填充。

    因此,编程中养成初始化变量的好习惯!!!!

    2、数据溢出 这也是很多新手会忽略的问题。一般是因为数据值超出了数据类型所能接受的范围。

    首先介绍一下基本数据类型的取值范围 (1)int型占4个字节,1个字节为8位。因此,它的数值范围是-232到232,转化为十进制数,大约是-109到109。 (2)long long型占8个字节,1个字节为8位。因此,它的数值范围是-264到264,转化为十进制数,大约是-1018到1018。 注意:对于整数来说,一般不建议用long型。因为32位系统中它占4字节,64位系统中占它8字节。对于整型数据,用int和long long型就足够了!

    (3)float型占4个字节,其中指数占8位,实数值的大小取决于指数,由于是有符号型(符号占1位),指数的取值范围为27=128,因此,float的取值范围是-2128到2128转化为十进制数,大约是-1038到1038。 (4)double型占8个字节,其中指数占11位,实数值的大小取决于指数,由于是有符号型(符号占1位),指数的取值范围为210=1024,因此,float的取值范围是-21024到21024转化为十进制数,大约是-10308到10308。

    举个简单的例子:计算n!(n不超过20)

    #include<stdio.h> int main() { int n,sum=1; scanf("%d",&n); for(int i=1; i<=n; i++) sum*=i; printf("%d\n",sum); return 0; }

    当n=13时,运行结果如下: 正确的13!=6227020800,得到的结果却是1932053504,因为当n大于12时,n!的值超出了int型的取值范围-109到109 因此,需要把sum类型改为long long型。运行结果如下: (5)当超过long long型数据的范围时,采用字符数组或字符串的形式存储这些数据。比如:身份证号,很长的数字编码,大整数等。否则也会产生随机值。

    举个例子:输入数n(位数超过25),并输出n

    #include<stdio.h> int main() { long long n; scanf("%lld",&n); printf("%lld\n",n); return 0; }

    n为long long型,运行结果如下: 结果是个随机值,当把n的类型改为字符数组或者字符串:string n;或char n[100];注意加头文件#include<string.h>,运行结果如下: 当在定义变量时,一定要选择正确的数据类型,避免结果为随机数!!!

    3、数组越界 数组的下标统一从0开始。对于a[n]的数组,它的下标范围是0~n-1,没有a[n]这个元素。单独把这个提出来,很多道友都会说“这我知道呀!”,但实际上,很多道友在写程序时,常常忽略这一点。

    举个例子:

    #include<stdio.h> int main() { int i=0; int t=100; int a[5]; while(i<5) { a[i++]=++t; } for(t=0;t<6;t++) { printf("%d %d\n",t,a[t]); } return 0; }

    运行结果如下: 当t等于5时,a[5]的值是一个随机数。当改为t<5,程序运行正确,如图所示: 此外,数组越界还会引发程序死循环。

    举个例子:

    #include<iostream> int main(){ int i = 0; int arr[3] = {0}; for(;i<=3;i++){ arr[i] = 0; printf("hello world\n"); } return 0; }

    数组中的元素为arr[0],arr[1],arr[2],而for循环结束条件错写为i<=3,非法访问arr[3]导致死循环。运行结果如下: 把i<=3;改为i<3; 运行结果如下: C/C++语言中数组越界是一种未决行为,编译器不会做任何处理。因此遇到数组时,一定要避免越界!!!

    4、程序逻辑问题 这种问题不容易被发现,对于复杂的程序,需要有清晰的思路和扎实的基础知识,采用输出中间结果的方式,一步一步的调试。

    举个简单的例子:

    #include <stdio.h> int main() { int a=0,b=-1; do { b-=a; a++; } while(b--<0); printf("%d",b); return 0; }

    最后b的值是个随机数,是因为b- - 永远是负数,它会一直循环下去。

    特别说明:以上列举的例子虽然简单,但是它却能说明这些问题的存在。当然,实际编写程序肯定比这些复杂得多,这就需要我们细心、用心地去修正问题。

    为了便于道友们向我咨询问题,特意开设了一个免费的知识星球——CaptianXue,星球提供学习、理财、生活、职场等各类文章和免费答疑!!

    最新回复(0)