2 /*程序名称: array-04.c */
3 /*程序目的: 设计一个可容纳40位数的求n!程序 */
4 /*Written By Kuo-Yu Huang.(WANT Studio.) */
5 /*===================================================*/
6
7 void main(void)
8 {
9 int Data[40]; /* 存储40位数的整数数组 */
10 int Digit; /* 数据位数变量 */
11 int i,j,r,k; /* 循环讦数变量 */
12 int N; /* 用户输入值 */
13 for(i=1;i<40+1;i++) /* 将数组始值设为0 */
14 Data[i]=0;
15 Data[0]=1; /* 设第0位数数组为1 */
16 Data[1]=1; /* 设第1位数数组为1 */
17 Digit=1; /* 设数据位数为1 */
18 printf("Enter a number what you want to calculus : ");
19 scanf("%d",&N); /* 读到用户欲求的N值 */
20 for(i=1;i<N+1;i++)
21 {
22 for(j=1;j<Digit+1;j++)
23 Data[j]*=i; /* 数组中内容的运算 */
24 for(j=1;j<Digit+1;j++)
25 {
26 if(Data[j]>10)
27 {
28 for(r=1;r<Digit+1;r++)
29 {
30 if(Data[Digit]>10)
31 Digit++;
32 /* 当数组中的值大于10时,则位数加1 */
33 Data[r+1]+=Data[r]/10;
34 /* 前一们数组值 = 前一们数组值+此位数组什除以10 */
35 Data[r]=Data[r]%10;
36 /* 此位数组值 = 此位数组值除10取余数 */
37 }
38 }
39 }
40 printf("%d! = ",i);
41 for(k=Digit;k>0;k--) /* 输出数组中的内容 */
42 printf("%d",Data[k]);
43 printf("\n");
44 }
45 }
这是清华大学出版社出版的一本《数据结构》里的一道例题,其中我有几处不明白,特向高手们请教。
1. 第13行的for(i=1;i<40+1;i++)为什么循环条件是i<40+1而不是i<40呢?
2. 第24行到第39行的那两层循环for(j=1;j<Digit+1;j++)和for(r=1;r<Digit+1;r++),为什么要用两层?
谢谢大家。
53 个解决方案
#1
1。本来应该是:for(i = 0 ; i < 40 ; i++),你看得数严蔚民的那本C语言版的数据结构吧,该书只是在原来pascal版的基础上,把代码改了改而已,后面你还会遇到多处这种从pascal改过来但又改得不彻底的地方,但话又说回来了,该书已经声明使用的是“类C语言”,因此,细节上跟标准C语言有些许出入也不能算错。另外,数据结构教材上的源码重在阐述算法思想,而不是实现细节。
#2
1。本来应该是:for(i = 0 ; i < 40 ; i++),你看得数严蔚民的那本C语言版的数据结构吧,该书只是在原来pascal版的基础上,把代码改了改而已,后面你还会遇到多处这种从pascal改过来但又改得不彻底的地方,但话又说回来了,该书已经声明使用的是“类C语言”,因此,细节上跟标准C语言有些许出入也不能算错。另外,数据结构教材上的源码重在阐述算法思想,而不是实现细节。
#3
因为for(i=1;i<40+1;i++)它是从1开始初始化40个数组元素的,所以要到<40+1
后面两个也是一样的原因,主要就是因为它是从1开始的而不是我们通常习惯的0
后面两个也是一样的原因,主要就是因为它是从1开始的而不是我们通常习惯的0
#4
第24行到第39行的那两层循环for(j=1;j<Digit+1;j++)和for(r=1;r<Digit+1;r++),为什么要用两层?
这是因为它用于处理数组每一位的元素当它大于10的时候它就将它的十位数向前进位,用两层循环是为了,当后一位的进位加上本来的数字大于10的时候的进位
这是因为它用于处理数组每一位的元素当它大于10的时候它就将它的十位数向前进位,用两层循环是为了,当后一位的进位加上本来的数字大于10的时候的进位
#5
int Data[40];
for(i=1;i<40+1;i++) /* 将数组始值设为0 */
Data[i]=0;
这样不会越界么?
for(i=1;i<40+1;i++) /* 将数组始值设为0 */
Data[i]=0;
这样不会越界么?
#6
绝对越界
#7
越界,编译还不会出错
#8
同意楼上两位
#9
不会吧,我记得我看到过这种方法啊,编译器不同的关系把(个人意见)
#10
绝对不是编译器不同的关系!!!!
int Data[40];
for(i=1;i<40+1;i++) /* 将数组始值设为0 */
Data[i]=0;
定义了一个有40个元素的数组Data,(Data[0]--Data[39])
你说,上边的赋值越不越界呢????
只要你学过一点点C 语言的话,就应该明白的!!!
#11
你的13行也可以改为for(i=0,i<40,i++)因为要循环40次
#12
13 for(i=1;i<40+1;i++) /* 将数组始值设为0 */
14 Data[i]=0;
在pascal中数组下标从1开始而C中从1开始 这两行代码表示清0在c中应从
data[0]清起 应该是:for(i = 0 ; i < 40 ; i++),
14 Data[i]=0;
在pascal中数组下标从1开始而C中从1开始 这两行代码表示清0在c中应从
data[0]清起 应该是:for(i = 0 ; i < 40 ; i++),
#13
估计是编写书的的不懂C/C++,而给书的例子改写代码的人不懂算法而且也不大懂C/C++。
这就是中国。
这就是中国。
#14
整个就是思维混乱(本来写这个代码的人思维是清晰的,可是抄写到书上来的人是#$%@)
#15
还是我给你改写吧:
#include <stdio.h>
void main(void){
int data[40];
int digit;
int i,j;
int n;
for(i=0;i<40;++i)data[i]=0;
data[0]++;
digit=1;
printf("Enter a number what you want to caculus:");
scanf("%d",&n);
for(i=1;i<=n;++i){
for(j=0;j<digit;++j)data[j]*=i;
for(j=0;j<digit;++j){
if(data[j]>=10){
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
}
printf("%d!=",i);
for(j=digit-1;j>=0;--j)printf("%d",data[j]);
printf("\n");
}
}
#include <stdio.h>
void main(void){
int data[40];
int digit;
int i,j;
int n;
for(i=0;i<40;++i)data[i]=0;
data[0]++;
digit=1;
printf("Enter a number what you want to caculus:");
scanf("%d",&n);
for(i=1;i<=n;++i){
for(j=0;j<digit;++j)data[j]*=i;
for(j=0;j<digit;++j){
if(data[j]>=10){
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
}
printf("%d!=",i);
for(j=digit-1;j>=0;--j)printf("%d",data[j]);
printf("\n");
}
}
#16
它表示的是data[1]到data[40]啊,也是40个数据啊
#17
我告诉你
1、他这样写绝对错了,如果要这样写的话就应该这样定义数组int Data[41];
本来作者写成这样是因为习惯上我们计数是从1开始,当然编多了,习惯就变成了从0开始了。
1、他这样写绝对错了,如果要这样写的话就应该这样定义数组int Data[41];
本来作者写成这样是因为习惯上我们计数是从1开始,当然编多了,习惯就变成了从0开始了。
#18
我告诉你
1、他这样写绝对错了。原因就是越界。如果要这样写,那么数组应该这样定义
int Data[41];
作者从1开始是因为我们平常习惯上计数是从1开始,但是作者忘了他定义的时候只定义了40个单元,我想应该是失误吧。
第二个问题我就不回答了
1、他这样写绝对错了。原因就是越界。如果要这样写,那么数组应该这样定义
int Data[41];
作者从1开始是因为我们平常习惯上计数是从1开始,但是作者忘了他定义的时候只定义了40个单元,我想应该是失误吧。
第二个问题我就不回答了
#19
这本书很烂的,居然出现很多次的HeaD.>Next
是黄国瑜写的
原来连清华的书都那么烂
以后只买机械工业的
是黄国瑜写的
原来连清华的书都那么烂
以后只买机械工业的
#20
各位有谁能把这个程序的算法给解释一下 这对我很重要的 本人一定另给分
#21
c语言的数组默认起始值是从0开始的,他这样写也可以,只要定义好了,不越界
还有清华的经他妈的骗子,是个滥货就他妈的出书.严蔚敏的书就n多错误菲疑之处
还有清华的经他妈的骗子,是个滥货就他妈的出书.严蔚敏的书就n多错误菲疑之处
#22
原程序中两层循环是错的!
cui(蚊子王) 的程序是对的,只用一层循环。
算法:
40位数组DATA[40],开始设0,把1放入DATA[0],
然后用数组中每个元素*2*3*4*.....*N 循环
当每个元素DATA[i]的值大于10时,除10,余数留下,尚加入下一位,依次类
推,当最高位进位时,位数digit加一。
我认为程序中少了一句,当digit大于40时,退出!
cui(蚊子王) 的程序是对的,只用一层循环。
算法:
40位数组DATA[40],开始设0,把1放入DATA[0],
然后用数组中每个元素*2*3*4*.....*N 循环
当每个元素DATA[i]的值大于10时,除10,余数留下,尚加入下一位,依次类
推,当最高位进位时,位数digit加一。
我认为程序中少了一句,当digit大于40时,退出!
#23
caoxin()指出的问题是对的,事实上我当时刚刚发完贴的时候就发现了,可是由于我已经连续发3贴了,就作罢了。
昨天,我又发现一个大错误,就是在那句“if(data[digit])++digit;”,在这里刚好还没有事情,但大家可以想想如果没有调整之前的最高位不止超过10而是100甚至1000呢(如果阶乘到100甚至更多那就会发生的),所以不能只考虑位数增加一位。还有得考虑数组溢出的问题。
昨天,我又发现一个大错误,就是在那句“if(data[digit])++digit;”,在这里刚好还没有事情,但大家可以想想如果没有调整之前的最高位不止超过10而是100甚至1000呢(如果阶乘到100甚至更多那就会发生的),所以不能只考虑位数增加一位。还有得考虑数组溢出的问题。
#24
我对原程序进行修改,用while语句处理进位,而且为了简单化使用了goto语句(虽然有好多人对goto语句深恶痛疾,但我觉得事情都是两方面的,有时候用goto语句反而使思维更清晰)
#include <stdio.h>
#define LENGTH 40
void main(void){
int data[LENGTH];
int digit;
int i,j;
int n;
for(i=0;i<LENGTH;++i)data[i]=0;
data[0]++;
digit=1;
printf("Enter a number what you want to caculus:");
scanf("%d",&n);
for(i=1;i<=n;++i){
for(j=0;j<digit;++j)data[j]*=i;
for(j=0;j<digit;++j){
if(data[j]>=10){
data[j+1]+=data[j]/10;
data[j]%=10;
}
while(data[digit]){
if(digit>=LENGTH)goto end;
if(data[digit++]>=10){
if(digit>=LENGTH)goto end;
data[digit]+=data[digit-1]/10;
data[digit-1]%=10;
}
}
}
printf("%d!=",i);
for(j=digit-1;j>=0;--j)printf("%d",data[j]);
printf("\n");
}
end:
}
#include <stdio.h>
#define LENGTH 40
void main(void){
int data[LENGTH];
int digit;
int i,j;
int n;
for(i=0;i<LENGTH;++i)data[i]=0;
data[0]++;
digit=1;
printf("Enter a number what you want to caculus:");
scanf("%d",&n);
for(i=1;i<=n;++i){
for(j=0;j<digit;++j)data[j]*=i;
for(j=0;j<digit;++j){
if(data[j]>=10){
data[j+1]+=data[j]/10;
data[j]%=10;
}
while(data[digit]){
if(digit>=LENGTH)goto end;
if(data[digit++]>=10){
if(digit>=LENGTH)goto end;
data[digit]+=data[digit-1]/10;
data[digit-1]%=10;
}
}
}
printf("%d!=",i);
for(j=digit-1;j>=0;--j)printf("%d",data[j]);
printf("\n");
}
end:
}
#25
那个while语句还是应该移到外面去,再修改一点。
#include <stdio.h>
#define LENGTH 40
void main(void){
int data[LENGTH];
int digit;
int i,j;
int n;
for(i=0;i<LENGTH;++i)data[i]=0;
data[0]++;
digit=1;
printf("Enter a number what you want to caculus:");
scanf("%d",&n);
for(i=1;i<=n;++i){
for(j=0;j<digit;++j)data[j]*=i;
for(j=0;j<digit-1;++j){ /*最高位先不调整*/
if(data[j]>=10){
data[j+1]+=data[j]/10;
data[j]%=10;
}
}
while(data[digit-1]>=10){
if(digit>=LENGTH)goto end;
data[digit]+=data[digit-1]/10;
data[digit-1]%=10;
digit++;
}
printf("%d!=",i);
for(j=digit-1;j>=0;--j)printf("%d",data[j]);
printf("\n");
}
end:
}
#include <stdio.h>
#define LENGTH 40
void main(void){
int data[LENGTH];
int digit;
int i,j;
int n;
for(i=0;i<LENGTH;++i)data[i]=0;
data[0]++;
digit=1;
printf("Enter a number what you want to caculus:");
scanf("%d",&n);
for(i=1;i<=n;++i){
for(j=0;j<digit;++j)data[j]*=i;
for(j=0;j<digit-1;++j){ /*最高位先不调整*/
if(data[j]>=10){
data[j+1]+=data[j]/10;
data[j]%=10;
}
}
while(data[digit-1]>=10){
if(digit>=LENGTH)goto end;
data[digit]+=data[digit-1]/10;
data[digit-1]%=10;
digit++;
}
printf("%d!=",i);
for(j=digit-1;j>=0;--j)printf("%d",data[j]);
printf("\n");
}
end:
}
#26
这样的例题,真让我伤心。
#27
C语言规则数组下标从0开始,至N-1结束。则14句无法对第一个元书赋值,而且也溢出
#28
TOcui(蚊子王) :
int型数组每个元素2字节,可容纳2的16次方==65536大的数
就是当超过65536时才溢出,而且数组中每个元素都可能溢出,
况且当N=35 时就已超过40位了
对否?
int型数组每个元素2字节,可容纳2的16次方==65536大的数
就是当超过65536时才溢出,而且数组中每个元素都可能溢出,
况且当N=35 时就已超过40位了
对否?
#29
to caoxin():
对于每个元素的溢出可能性不大,因为每次乘之后都调整过的,都是在0-9之间的数了,如果要溢出那乘的数字至少要大于65536/9,也就是说至少要大于等于7282才行,所以求小于7282的数的阶乘的话是不会元素溢出的。
我说的溢出准确说是数组越位,就是超过数组的位数,就象你说的“当N=35 时就已超过40位了”,如果越位了,那就改写不是属于数组的内存了,在这里就是依照越位多少依次改写digit、i、j、n的值,那结果就是比较麻烦的了。
正是要防止数组越位,我才把最高位的调整不放在for语句里,而是放在while语句里了。
对于每个元素的溢出可能性不大,因为每次乘之后都调整过的,都是在0-9之间的数了,如果要溢出那乘的数字至少要大于65536/9,也就是说至少要大于等于7282才行,所以求小于7282的数的阶乘的话是不会元素溢出的。
我说的溢出准确说是数组越位,就是超过数组的位数,就象你说的“当N=35 时就已超过40位了”,如果越位了,那就改写不是属于数组的内存了,在这里就是依照越位多少依次改写digit、i、j、n的值,那结果就是比较麻烦的了。
正是要防止数组越位,我才把最高位的调整不放在for语句里,而是放在while语句里了。
#30
我发现类C语言的问题:它函数参数用引用&是在函数外定义变量(如果C)
它前言说是方便改成用C和C++写的程序,算法思想没有错
它前言说是方便改成用C和C++写的程序,算法思想没有错
#31
TO cui(蚊子王) :
应当把while语句放在for语句内,否则侵占数组外的内存是很危险的,
按你的说法 :溢出指数组越位,那么当不越位时,不须要调整最高位,
当数组越位时,已经用GOTO退出,更用不着调整最高位了。
就是说不需要调整最高位的代码
直接在你第一次写的程序里加一条GOTO语句就可以了
应当把while语句放在for语句内,否则侵占数组外的内存是很危险的,
按你的说法 :溢出指数组越位,那么当不越位时,不须要调整最高位,
当数组越位时,已经用GOTO退出,更用不着调整最高位了。
就是说不需要调整最高位的代码
直接在你第一次写的程序里加一条GOTO语句就可以了
#32
to caoxin() :
我觉得应该是在for外的,在for语句的时候我只调整除最高位外的其他位,就是说,位数没有增加,自然不会越界了。while语句是专门来最高位进位的,到这里才会位数增加啊。
我觉得应该是在for外的,在for语句的时候我只调整除最高位外的其他位,就是说,位数没有增加,自然不会越界了。while语句是专门来最高位进位的,到这里才会位数增加啊。
#33
TO : cui(蚊子王) :
你的while语句是对的,我看错了
不过在你第一个程序中:
for(j=0;j<digit;++j){
if(data[j]>=10){
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
}
是否已含有最高位处理了?
你的while语句是对的,我看错了
不过在你第一个程序中:
for(j=0;j<digit;++j){
if(data[j]>=10){
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
}
是否已含有最高位处理了?
#34
to caoxin() :
就是啊,就是这样第一个才有溢出啊,所以就只好改了。事实上除最后一个程序以外,其他的都有溢出的可能(倒数第二个也有)。
就是啊,就是这样第一个才有溢出啊,所以就只好改了。事实上除最后一个程序以外,其他的都有溢出的可能(倒数第二个也有)。
#35
在网络上,常常没有经过深思熟虑的就写的,所以常常漏洞百出,对于我贴的代码,我只有支持最后一次贴的。
#36
现在社会我么黑暗,什么事不可能
#37
to cui(蚊子王) :
我的意思是:在第一个程序中加一句:
for(j=0;j<digit;++j){
if(data[j]>=10){
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
if(digit>=LENGTH)goto end;//here
}
岂不简单?不需要while了?
我的意思是:在第一个程序中加一句:
for(j=0;j<digit;++j){
if(data[j]>=10){
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
if(digit>=LENGTH)goto end;//here
}
岂不简单?不需要while了?
#38
caoxin() :
事实上从时间复杂度来说,结果是一样的。
不过你这样写还是有毛病的,比如,刚刚在位数达到指定位(在这里是40位)的时候,本来应该正常的,可是你这样写就强制goto出去了,得不到结果了。
事实上从时间复杂度来说,结果是一样的。
不过你这样写还是有毛病的,比如,刚刚在位数达到指定位(在这里是40位)的时候,本来应该正常的,可是你这样写就强制goto出去了,得不到结果了。
#39
不过改成下面的,是可以的:
for(j=0;j<digit;++j){
if(data[j]>=10){
if(digit>=LENGTH)goto end;//here
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
}
for(j=0;j<digit;++j){
if(data[j]>=10){
if(digit>=LENGTH)goto end;//here
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
}
#40
错了错了,上面的错了,作废
#41
你的对了
哪儿错了?
哪儿错了?
#42
不过改成下面的,是可以的:
for(j=0;j<digit;++j){
if(data[j]>=10){
if(digit>=LENGTH)goto end;//here
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
}
应该写成
不过改成下面的,是可以的:
for(j=0;j<digit;++j){
if(data[j]>=10){
if(j>=LENGTH)goto end;//here
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
}
不然是有问题的
for(j=0;j<digit;++j){
if(data[j]>=10){
if(digit>=LENGTH)goto end;//here
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
}
应该写成
不过改成下面的,是可以的:
for(j=0;j<digit;++j){
if(data[j]>=10){
if(j>=LENGTH)goto end;//here
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
}
不然是有问题的
#43
其实不修改对40位的数是没有错的,但总觉得从逻辑上说有问题,所以还是改一下
#44
to caoxin():
你是哪里人啊,是在校生吧,什么大学的
你是哪里人啊,是在校生吧,什么大学的
#45
cui(蚊子王) :
写信交流吧
我的邮箱: c1x0067@sina.com
你的邮箱?
写信交流吧
我的邮箱: c1x0067@sina.com
你的邮箱?
#46
cui3k@yahoo.com.cn
#47
1。本来应该是:for(i = 0 ; i < 40 ; i++),你看得数严蔚民的那本C语言版的数据结构吧,该书只是在原来pascal版的基础上,把代码改了改而已,后面你还会遇到多处这种从pascal改过来但又改得不彻底的地方,但话又说回来了,该书已经声明使用的是“类C语言”,因此,细节上跟标准C语言有些许出入也不能算错。另外,数据结构教材上的源码重在阐述算法思想,而不是实现细节。
#48
up
#49
黄国瑜这本鸟书,错误多的离谱,不仅源代码错的一大堆,很多算法,数据结构也写的*一般。楼上的,为了你的身心健康还事把这本书扔掉的好。
#50
因为i是从1开始的,所以是40+1
#1
1。本来应该是:for(i = 0 ; i < 40 ; i++),你看得数严蔚民的那本C语言版的数据结构吧,该书只是在原来pascal版的基础上,把代码改了改而已,后面你还会遇到多处这种从pascal改过来但又改得不彻底的地方,但话又说回来了,该书已经声明使用的是“类C语言”,因此,细节上跟标准C语言有些许出入也不能算错。另外,数据结构教材上的源码重在阐述算法思想,而不是实现细节。
#2
1。本来应该是:for(i = 0 ; i < 40 ; i++),你看得数严蔚民的那本C语言版的数据结构吧,该书只是在原来pascal版的基础上,把代码改了改而已,后面你还会遇到多处这种从pascal改过来但又改得不彻底的地方,但话又说回来了,该书已经声明使用的是“类C语言”,因此,细节上跟标准C语言有些许出入也不能算错。另外,数据结构教材上的源码重在阐述算法思想,而不是实现细节。
#3
因为for(i=1;i<40+1;i++)它是从1开始初始化40个数组元素的,所以要到<40+1
后面两个也是一样的原因,主要就是因为它是从1开始的而不是我们通常习惯的0
后面两个也是一样的原因,主要就是因为它是从1开始的而不是我们通常习惯的0
#4
第24行到第39行的那两层循环for(j=1;j<Digit+1;j++)和for(r=1;r<Digit+1;r++),为什么要用两层?
这是因为它用于处理数组每一位的元素当它大于10的时候它就将它的十位数向前进位,用两层循环是为了,当后一位的进位加上本来的数字大于10的时候的进位
这是因为它用于处理数组每一位的元素当它大于10的时候它就将它的十位数向前进位,用两层循环是为了,当后一位的进位加上本来的数字大于10的时候的进位
#5
int Data[40];
for(i=1;i<40+1;i++) /* 将数组始值设为0 */
Data[i]=0;
这样不会越界么?
for(i=1;i<40+1;i++) /* 将数组始值设为0 */
Data[i]=0;
这样不会越界么?
#6
绝对越界
#7
越界,编译还不会出错
#8
同意楼上两位
#9
不会吧,我记得我看到过这种方法啊,编译器不同的关系把(个人意见)
#10
绝对不是编译器不同的关系!!!!
int Data[40];
for(i=1;i<40+1;i++) /* 将数组始值设为0 */
Data[i]=0;
定义了一个有40个元素的数组Data,(Data[0]--Data[39])
你说,上边的赋值越不越界呢????
只要你学过一点点C 语言的话,就应该明白的!!!
#11
你的13行也可以改为for(i=0,i<40,i++)因为要循环40次
#12
13 for(i=1;i<40+1;i++) /* 将数组始值设为0 */
14 Data[i]=0;
在pascal中数组下标从1开始而C中从1开始 这两行代码表示清0在c中应从
data[0]清起 应该是:for(i = 0 ; i < 40 ; i++),
14 Data[i]=0;
在pascal中数组下标从1开始而C中从1开始 这两行代码表示清0在c中应从
data[0]清起 应该是:for(i = 0 ; i < 40 ; i++),
#13
估计是编写书的的不懂C/C++,而给书的例子改写代码的人不懂算法而且也不大懂C/C++。
这就是中国。
这就是中国。
#14
整个就是思维混乱(本来写这个代码的人思维是清晰的,可是抄写到书上来的人是#$%@)
#15
还是我给你改写吧:
#include <stdio.h>
void main(void){
int data[40];
int digit;
int i,j;
int n;
for(i=0;i<40;++i)data[i]=0;
data[0]++;
digit=1;
printf("Enter a number what you want to caculus:");
scanf("%d",&n);
for(i=1;i<=n;++i){
for(j=0;j<digit;++j)data[j]*=i;
for(j=0;j<digit;++j){
if(data[j]>=10){
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
}
printf("%d!=",i);
for(j=digit-1;j>=0;--j)printf("%d",data[j]);
printf("\n");
}
}
#include <stdio.h>
void main(void){
int data[40];
int digit;
int i,j;
int n;
for(i=0;i<40;++i)data[i]=0;
data[0]++;
digit=1;
printf("Enter a number what you want to caculus:");
scanf("%d",&n);
for(i=1;i<=n;++i){
for(j=0;j<digit;++j)data[j]*=i;
for(j=0;j<digit;++j){
if(data[j]>=10){
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
}
printf("%d!=",i);
for(j=digit-1;j>=0;--j)printf("%d",data[j]);
printf("\n");
}
}
#16
它表示的是data[1]到data[40]啊,也是40个数据啊
#17
我告诉你
1、他这样写绝对错了,如果要这样写的话就应该这样定义数组int Data[41];
本来作者写成这样是因为习惯上我们计数是从1开始,当然编多了,习惯就变成了从0开始了。
1、他这样写绝对错了,如果要这样写的话就应该这样定义数组int Data[41];
本来作者写成这样是因为习惯上我们计数是从1开始,当然编多了,习惯就变成了从0开始了。
#18
我告诉你
1、他这样写绝对错了。原因就是越界。如果要这样写,那么数组应该这样定义
int Data[41];
作者从1开始是因为我们平常习惯上计数是从1开始,但是作者忘了他定义的时候只定义了40个单元,我想应该是失误吧。
第二个问题我就不回答了
1、他这样写绝对错了。原因就是越界。如果要这样写,那么数组应该这样定义
int Data[41];
作者从1开始是因为我们平常习惯上计数是从1开始,但是作者忘了他定义的时候只定义了40个单元,我想应该是失误吧。
第二个问题我就不回答了
#19
这本书很烂的,居然出现很多次的HeaD.>Next
是黄国瑜写的
原来连清华的书都那么烂
以后只买机械工业的
是黄国瑜写的
原来连清华的书都那么烂
以后只买机械工业的
#20
各位有谁能把这个程序的算法给解释一下 这对我很重要的 本人一定另给分
#21
c语言的数组默认起始值是从0开始的,他这样写也可以,只要定义好了,不越界
还有清华的经他妈的骗子,是个滥货就他妈的出书.严蔚敏的书就n多错误菲疑之处
还有清华的经他妈的骗子,是个滥货就他妈的出书.严蔚敏的书就n多错误菲疑之处
#22
原程序中两层循环是错的!
cui(蚊子王) 的程序是对的,只用一层循环。
算法:
40位数组DATA[40],开始设0,把1放入DATA[0],
然后用数组中每个元素*2*3*4*.....*N 循环
当每个元素DATA[i]的值大于10时,除10,余数留下,尚加入下一位,依次类
推,当最高位进位时,位数digit加一。
我认为程序中少了一句,当digit大于40时,退出!
cui(蚊子王) 的程序是对的,只用一层循环。
算法:
40位数组DATA[40],开始设0,把1放入DATA[0],
然后用数组中每个元素*2*3*4*.....*N 循环
当每个元素DATA[i]的值大于10时,除10,余数留下,尚加入下一位,依次类
推,当最高位进位时,位数digit加一。
我认为程序中少了一句,当digit大于40时,退出!
#23
caoxin()指出的问题是对的,事实上我当时刚刚发完贴的时候就发现了,可是由于我已经连续发3贴了,就作罢了。
昨天,我又发现一个大错误,就是在那句“if(data[digit])++digit;”,在这里刚好还没有事情,但大家可以想想如果没有调整之前的最高位不止超过10而是100甚至1000呢(如果阶乘到100甚至更多那就会发生的),所以不能只考虑位数增加一位。还有得考虑数组溢出的问题。
昨天,我又发现一个大错误,就是在那句“if(data[digit])++digit;”,在这里刚好还没有事情,但大家可以想想如果没有调整之前的最高位不止超过10而是100甚至1000呢(如果阶乘到100甚至更多那就会发生的),所以不能只考虑位数增加一位。还有得考虑数组溢出的问题。
#24
我对原程序进行修改,用while语句处理进位,而且为了简单化使用了goto语句(虽然有好多人对goto语句深恶痛疾,但我觉得事情都是两方面的,有时候用goto语句反而使思维更清晰)
#include <stdio.h>
#define LENGTH 40
void main(void){
int data[LENGTH];
int digit;
int i,j;
int n;
for(i=0;i<LENGTH;++i)data[i]=0;
data[0]++;
digit=1;
printf("Enter a number what you want to caculus:");
scanf("%d",&n);
for(i=1;i<=n;++i){
for(j=0;j<digit;++j)data[j]*=i;
for(j=0;j<digit;++j){
if(data[j]>=10){
data[j+1]+=data[j]/10;
data[j]%=10;
}
while(data[digit]){
if(digit>=LENGTH)goto end;
if(data[digit++]>=10){
if(digit>=LENGTH)goto end;
data[digit]+=data[digit-1]/10;
data[digit-1]%=10;
}
}
}
printf("%d!=",i);
for(j=digit-1;j>=0;--j)printf("%d",data[j]);
printf("\n");
}
end:
}
#include <stdio.h>
#define LENGTH 40
void main(void){
int data[LENGTH];
int digit;
int i,j;
int n;
for(i=0;i<LENGTH;++i)data[i]=0;
data[0]++;
digit=1;
printf("Enter a number what you want to caculus:");
scanf("%d",&n);
for(i=1;i<=n;++i){
for(j=0;j<digit;++j)data[j]*=i;
for(j=0;j<digit;++j){
if(data[j]>=10){
data[j+1]+=data[j]/10;
data[j]%=10;
}
while(data[digit]){
if(digit>=LENGTH)goto end;
if(data[digit++]>=10){
if(digit>=LENGTH)goto end;
data[digit]+=data[digit-1]/10;
data[digit-1]%=10;
}
}
}
printf("%d!=",i);
for(j=digit-1;j>=0;--j)printf("%d",data[j]);
printf("\n");
}
end:
}
#25
那个while语句还是应该移到外面去,再修改一点。
#include <stdio.h>
#define LENGTH 40
void main(void){
int data[LENGTH];
int digit;
int i,j;
int n;
for(i=0;i<LENGTH;++i)data[i]=0;
data[0]++;
digit=1;
printf("Enter a number what you want to caculus:");
scanf("%d",&n);
for(i=1;i<=n;++i){
for(j=0;j<digit;++j)data[j]*=i;
for(j=0;j<digit-1;++j){ /*最高位先不调整*/
if(data[j]>=10){
data[j+1]+=data[j]/10;
data[j]%=10;
}
}
while(data[digit-1]>=10){
if(digit>=LENGTH)goto end;
data[digit]+=data[digit-1]/10;
data[digit-1]%=10;
digit++;
}
printf("%d!=",i);
for(j=digit-1;j>=0;--j)printf("%d",data[j]);
printf("\n");
}
end:
}
#include <stdio.h>
#define LENGTH 40
void main(void){
int data[LENGTH];
int digit;
int i,j;
int n;
for(i=0;i<LENGTH;++i)data[i]=0;
data[0]++;
digit=1;
printf("Enter a number what you want to caculus:");
scanf("%d",&n);
for(i=1;i<=n;++i){
for(j=0;j<digit;++j)data[j]*=i;
for(j=0;j<digit-1;++j){ /*最高位先不调整*/
if(data[j]>=10){
data[j+1]+=data[j]/10;
data[j]%=10;
}
}
while(data[digit-1]>=10){
if(digit>=LENGTH)goto end;
data[digit]+=data[digit-1]/10;
data[digit-1]%=10;
digit++;
}
printf("%d!=",i);
for(j=digit-1;j>=0;--j)printf("%d",data[j]);
printf("\n");
}
end:
}
#26
这样的例题,真让我伤心。
#27
C语言规则数组下标从0开始,至N-1结束。则14句无法对第一个元书赋值,而且也溢出
#28
TOcui(蚊子王) :
int型数组每个元素2字节,可容纳2的16次方==65536大的数
就是当超过65536时才溢出,而且数组中每个元素都可能溢出,
况且当N=35 时就已超过40位了
对否?
int型数组每个元素2字节,可容纳2的16次方==65536大的数
就是当超过65536时才溢出,而且数组中每个元素都可能溢出,
况且当N=35 时就已超过40位了
对否?
#29
to caoxin():
对于每个元素的溢出可能性不大,因为每次乘之后都调整过的,都是在0-9之间的数了,如果要溢出那乘的数字至少要大于65536/9,也就是说至少要大于等于7282才行,所以求小于7282的数的阶乘的话是不会元素溢出的。
我说的溢出准确说是数组越位,就是超过数组的位数,就象你说的“当N=35 时就已超过40位了”,如果越位了,那就改写不是属于数组的内存了,在这里就是依照越位多少依次改写digit、i、j、n的值,那结果就是比较麻烦的了。
正是要防止数组越位,我才把最高位的调整不放在for语句里,而是放在while语句里了。
对于每个元素的溢出可能性不大,因为每次乘之后都调整过的,都是在0-9之间的数了,如果要溢出那乘的数字至少要大于65536/9,也就是说至少要大于等于7282才行,所以求小于7282的数的阶乘的话是不会元素溢出的。
我说的溢出准确说是数组越位,就是超过数组的位数,就象你说的“当N=35 时就已超过40位了”,如果越位了,那就改写不是属于数组的内存了,在这里就是依照越位多少依次改写digit、i、j、n的值,那结果就是比较麻烦的了。
正是要防止数组越位,我才把最高位的调整不放在for语句里,而是放在while语句里了。
#30
我发现类C语言的问题:它函数参数用引用&是在函数外定义变量(如果C)
它前言说是方便改成用C和C++写的程序,算法思想没有错
它前言说是方便改成用C和C++写的程序,算法思想没有错
#31
TO cui(蚊子王) :
应当把while语句放在for语句内,否则侵占数组外的内存是很危险的,
按你的说法 :溢出指数组越位,那么当不越位时,不须要调整最高位,
当数组越位时,已经用GOTO退出,更用不着调整最高位了。
就是说不需要调整最高位的代码
直接在你第一次写的程序里加一条GOTO语句就可以了
应当把while语句放在for语句内,否则侵占数组外的内存是很危险的,
按你的说法 :溢出指数组越位,那么当不越位时,不须要调整最高位,
当数组越位时,已经用GOTO退出,更用不着调整最高位了。
就是说不需要调整最高位的代码
直接在你第一次写的程序里加一条GOTO语句就可以了
#32
to caoxin() :
我觉得应该是在for外的,在for语句的时候我只调整除最高位外的其他位,就是说,位数没有增加,自然不会越界了。while语句是专门来最高位进位的,到这里才会位数增加啊。
我觉得应该是在for外的,在for语句的时候我只调整除最高位外的其他位,就是说,位数没有增加,自然不会越界了。while语句是专门来最高位进位的,到这里才会位数增加啊。
#33
TO : cui(蚊子王) :
你的while语句是对的,我看错了
不过在你第一个程序中:
for(j=0;j<digit;++j){
if(data[j]>=10){
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
}
是否已含有最高位处理了?
你的while语句是对的,我看错了
不过在你第一个程序中:
for(j=0;j<digit;++j){
if(data[j]>=10){
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
}
是否已含有最高位处理了?
#34
to caoxin() :
就是啊,就是这样第一个才有溢出啊,所以就只好改了。事实上除最后一个程序以外,其他的都有溢出的可能(倒数第二个也有)。
就是啊,就是这样第一个才有溢出啊,所以就只好改了。事实上除最后一个程序以外,其他的都有溢出的可能(倒数第二个也有)。
#35
在网络上,常常没有经过深思熟虑的就写的,所以常常漏洞百出,对于我贴的代码,我只有支持最后一次贴的。
#36
现在社会我么黑暗,什么事不可能
#37
to cui(蚊子王) :
我的意思是:在第一个程序中加一句:
for(j=0;j<digit;++j){
if(data[j]>=10){
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
if(digit>=LENGTH)goto end;//here
}
岂不简单?不需要while了?
我的意思是:在第一个程序中加一句:
for(j=0;j<digit;++j){
if(data[j]>=10){
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
if(digit>=LENGTH)goto end;//here
}
岂不简单?不需要while了?
#38
caoxin() :
事实上从时间复杂度来说,结果是一样的。
不过你这样写还是有毛病的,比如,刚刚在位数达到指定位(在这里是40位)的时候,本来应该正常的,可是你这样写就强制goto出去了,得不到结果了。
事实上从时间复杂度来说,结果是一样的。
不过你这样写还是有毛病的,比如,刚刚在位数达到指定位(在这里是40位)的时候,本来应该正常的,可是你这样写就强制goto出去了,得不到结果了。
#39
不过改成下面的,是可以的:
for(j=0;j<digit;++j){
if(data[j]>=10){
if(digit>=LENGTH)goto end;//here
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
}
for(j=0;j<digit;++j){
if(data[j]>=10){
if(digit>=LENGTH)goto end;//here
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
}
#40
错了错了,上面的错了,作废
#41
你的对了
哪儿错了?
哪儿错了?
#42
不过改成下面的,是可以的:
for(j=0;j<digit;++j){
if(data[j]>=10){
if(digit>=LENGTH)goto end;//here
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
}
应该写成
不过改成下面的,是可以的:
for(j=0;j<digit;++j){
if(data[j]>=10){
if(j>=LENGTH)goto end;//here
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
}
不然是有问题的
for(j=0;j<digit;++j){
if(data[j]>=10){
if(digit>=LENGTH)goto end;//here
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
}
应该写成
不过改成下面的,是可以的:
for(j=0;j<digit;++j){
if(data[j]>=10){
if(j>=LENGTH)goto end;//here
data[j+1]+=data[j]/10;
data[j]%=10;
}
if(data[digit])++digit;
}
不然是有问题的
#43
其实不修改对40位的数是没有错的,但总觉得从逻辑上说有问题,所以还是改一下
#44
to caoxin():
你是哪里人啊,是在校生吧,什么大学的
你是哪里人啊,是在校生吧,什么大学的
#45
cui(蚊子王) :
写信交流吧
我的邮箱: c1x0067@sina.com
你的邮箱?
写信交流吧
我的邮箱: c1x0067@sina.com
你的邮箱?
#46
cui3k@yahoo.com.cn
#47
1。本来应该是:for(i = 0 ; i < 40 ; i++),你看得数严蔚民的那本C语言版的数据结构吧,该书只是在原来pascal版的基础上,把代码改了改而已,后面你还会遇到多处这种从pascal改过来但又改得不彻底的地方,但话又说回来了,该书已经声明使用的是“类C语言”,因此,细节上跟标准C语言有些许出入也不能算错。另外,数据结构教材上的源码重在阐述算法思想,而不是实现细节。
#48
up
#49
黄国瑜这本鸟书,错误多的离谱,不仅源代码错的一大堆,很多算法,数据结构也写的*一般。楼上的,为了你的身心健康还事把这本书扔掉的好。
#50
因为i是从1开始的,所以是40+1