关于作者

用户名:秦秦
笔名:秦秦
地区:
行业:其他

日历  

快速登录

+ 用户名:
+ 密 码:

快速通道

在线留言



访问统计:
文章个数:8
评论个数:10
留言条数:0




Powered by BlogDriver 2.1

珑 轩

 

把握现在!~你可以做更好~

文章

随机数 (转)
在论坛上看到很多人在问随机数的问题,我这里把我看到写比较详细的一个有关随机数的一些内容转贴介绍给大家,不正确的地方还请大家指正。


一.计算机中随机数的产生
现在,在计算机,用来产生随机数的算法是"线性同余"法。所谓线性同余,其实就是下面两个式子。假设I就是一个随机数的序列,Ij+1与Ij的关系如下:
Ij+1 =Ij * a+c  (mod m)
或是Ij+1 =Ij *a    (mod m),
其中,不妨取a=16807,m=2147483647,以为一常数。写个简单的程序就是:
long r;

void scand( long v)//初始化随机种子数
{
r = v;
}

long rand()//产生随机数
{
r = (r*a + c)%m;//a,c,m为常数
return r;
}
再看一下稍复杂一点的:(Random () 的 Borland 的实现)
long long RandSeed = #### ;
unsigned long Random(long max)
{
long long x ;
double i ;
unsigned long final ;
x = 0xffffffff;
x += 1 ;
RandSeed *= ((long long)134775813);
RandSeed += 1 ;
RandSeed = RandSeed % x ;
i = ((double)RandSeed) / (double)0xffffffff ;
final = (long) (max * i) ;
return (unsigned long)final;
}
二.计算机产生的随机数不是真的随机数
[引:]我们建立了真正调用伪随机数生成器的 random()。但什么是伪随机数生成器?假定需要生成介于 1 和 10 之间的随机数,每一个数出现的几率都是一样的。理想情况下,应生成 0 到 1 之间的一个值,不考虑以前值,这个范围中的每一个值出现的几率都是一样的,然后再将该值乘以 10。请注意,在 0 和 1 之间有无穷多个值,而计算机不能提供这样的精度。
为了编写代码来实现类似于前面提到的算法,常见情况下,伪随机数生成器生成 0 到 N 之间的一个整数,返回的整数再除以 N。得出的数字总是处于 0 和 1 之间。对生成器随后的调用采用第一次运行产生的整数,并将它传给一个函数,以生成 0 到 N 之间的一个新整数,然后再将新整数除以 N 返回。这意味着,由任何伪随机数生成器返回的数目会受到 0 到 N 之间整数数目的限制。
在大多数的常见随机数发生器中,N 是 232? (大约等于 40 亿),对于 32 位数字来说,这是最大的值。换句话说,我们经常碰到的这类生成器能够至多生成 40 亿个可能值。而这 40 亿个数根本不算大,只是指尖这么大。
伪随机数生成器将作为"种子"的数当作初始整数传给函数。这粒种子会使这个球(生成伪随机数)一直滚下去。伪随机数生成器的结果仅仅是不可预测。由伪随机数生成器返回的每一个值完全由它返回的前一个值所决定(最终,该种子决定了一切)。如果知道用于计算任何一个值的那个整数,那么就可以算出从这个生成器返回的下一个值。
结果,伪随机数生成器是一个生成完全可预料的数列(称为流)的确定性程序。一个编写得很好的的 PRNG 可以创建一个序列,而这个序列的属性与许多真正随机数的序列的属性是一样的。例如:
PRNG 可以以相同几率在一个范围内生成任何数字。
PRNG 可以生成带任何统计分布的流。
由 PRNG 生成的数字流不具备可辨别的模式。
PRNG 所不能做的是不可预测。如果知道种子和算法,就可以很容易地推算出这个序列。

计算机产生的随机数一般都只是一个周期很长的数列,不是真的随机数。也就是说,随机数一般是伪随机数,每个随机数都是由随机种子开始的一个已定的数列(周期很长)。一般地,为了随机数更真一点,随机种子在系统中通常是参照系统时钟生成的。
看看下面这个例子,从中,读者应能有所体会。
main()
{
  int i;
  scand(time(NULL)); /*可向计算机读取其时钟值,并把值自动设为随机数种子*/
  for(i=0;i<10;i++){
    printf("%10d",1+(rand()%6));/*这里1是移动值,他等于所需的连续整数*/
 }              /*数值范围的第一个数;b是比例因子;他*/
 return(0);            /*等于所需的连续整数值的范围宽度;*/
}
从数学上讲,为了得到一个周期性更长的随机序列,我们可以使用如下方法:(这是我在一个书上看到的,详细的情况大家可以查一查,我自己也记不清了,呵呵)
float rand(long* idum)
{
    int j;    long k;    static long iy=0;    static long iv[NTAB];
    float temp;    
    if(*idum<=0||!iy)
    {
        if(-(*idum)<1)            *idum=1;
        else            *idum=-(*idum);
        for(j=NTAB+7;j>=0;j--){
            k=(*idum)/IQ;
            *idum=IA*(*idum-k*IQ)-k*IR;
            if(*idum<0)
                *idum+=IM;
            if(j<NTAB)
                iv[j]=*idum;
        }    iy=iv[0];    }    
    k=(*idum)/IQ;
    *idum=IA*(*idum-k*IQ)-k*IR;
    if(*idum<0)        *idum+=IM;
     j=iy/NDIV;
    iy=iv[j];
    iv[j]=*idum;    
    if((temp=float(AM*iy))>RNMX)        return float(RNMX);
    else         return temp;
}

[注:]有文讲 ,根据Randomize的工作原理,利用函数Timer得到从午夜开始到现在经过的秒数,然后再根据要得到的随机数值大小对该数值进行""衰减"处理,这样得到的数值则可称得上是真正意义的随机数值,我认为,这也是人为的方法,仍有它的确定性和周期性,仍称不上是真正的随机数,单纯改变伪随机数的生成逻辑计算方法并不能达到目的,最有效的办法只能是改变rand_seed,就是种子。而且,改变后的rand_seed不应该是人为的。(注:目前,在 Intel 的PIII处理器中内置了一个与CPU温度相关的随机数生成器,算是一个比较有效的种子生成器。)更好的办法是根据"随机事件"生成随机数,如键盘和鼠标输入值、中断、磁盘读取等等。然而,许多服务器没有键盘和鼠标,许多"黑盒"产品也不带有硬盘,因此很难找到好的随机数源,当然,通讯密钥也就一样不安全。而如网络状态等也不能很好地保证随机数的"随机性"。电器噪声和声音频率也许是很好的随机数源,但大多数人恐怕并不愿意在计算机中增加这种设备,而且也可能出现设备失灵和外部操纵(影响)等问题。对于要处理大量连接的网关服务器,是必须要考虑的问题。如果可以通过,精确检测机器cpu的通电电流强度,来作为随机数种子,或是其他一些没有人为因素的干扰的,且瞬间变化快的方法获得种子,必将能产生符和要求的随机数。

三.几种随机数的获取办法
1.产生一个范围内的随机数
一般地,我们可用j=1+(int)(n*rand()/(RAND_MAX+1.0))来生成一个0到n之间的随机数。
若用int x = rand() % 100;来生成 0 到 100 之间的随机数这种方法是不可取的,比较好的做法是: j=(int)(100.0*rand()/(RAND_MAX+1.0)) ,当然,我们也可是使用random(100)。下面的例子都是用了random(n).
2、筛选型随机数 如希望取0-99的随机数,但不能是6。
解决方法:
x = random(100);
while (x==6) {
x = random(100);
}
又如希望取0-99的随机数,但不要5的倍数 解决方法:
x = random(100);
while ((x % 5)==0) {
x = random(100);
}
3、从连续的一段范围内取随机数。
如从40--50的范围内取随机数。 解决方法: x=random(11)+40
4、从一组乱数中取随机数。 如:从 67, 87, 34, 78, 12, 5, 9, 108, 999, 378十个数中随机取数。 解决方法:可以用数组将些十个数存贮,然后把0--9中取出的随机数作为序号,实现随机取数。
a = new Array(67, 87, 34, 78, 12, 5, 9, 108, 999, 378);
j = random(10);
x = a[j];
四.产生具有一定分布的随机数
关于这点,有一篇文章写得很好,请看:
非均匀分布随机数的产生及其在计算机模拟研究中的应用
作者:胡性本 刘向明 方积乾
单位:胡性本(湖北职工医学院 荆州434000); 刘向明(湖北职工医学院 荆州434000 现为华中理工大学生物工程系博士研究生); 方积乾(湖北职工医学院 荆州434000 中山医科大学)
关键词:非均匀分布随机数;计算机模拟;程序设计
摘 要:非均匀分布随机数在进行计算机模拟研究中有重要作用,但计算机高级语言通常都只提供产生均匀分布随机数的函数,给研究工作带来困难。该文提出的方法,较好地解决了这一问题,有很强的适用性。

中图分类号:O 242.1
文章编号:1004-4337(2000)01-0059-02▲
1 问题的提出
常用的计算机高级程序设计语言,大多提供了产生在[0,1]区间内连续均匀分布的独立随机数r的函数。若将产生的随机数作简单的变换X=a+(b-a)r,就能得到在区间[a,b]上均匀分布的随机数X。如果与取整或舍入函数结合运用,还可得到离散均匀分布的随机数,给计算机模拟提供了方便。但在很多情况下进行计算机模拟需要用到按某些特定规律分布的非均匀随机数。例如,在离子通道门控模型的模拟研究中,就经常要用到服从指数分布、对数分布、正态分布、普畦松分布等非均匀分布的随机数。这时可以在源程序中编写一个函数或过程来产生。我们在近年来所进行的计算机模拟研究工作[1,2]中,大量使用了非均们分布的随机数,获得成功。由于离散随机数可以由连续随机数通过取整或舍入等途径转换而得,本文只侧重介绍非均匀分布连续随机数的产生原理和应用实例,并给出了用类PASCAL语言[3]编写的相应的函数和过程。掌握了任何一种计算机高级语言编程技术和数据结构知识的人,都能很方便地转换成能上机运行的程序,有很大的灵活性与很强的实用性。
2 产生原理
假定连续随机变量X是连续随机变量R的函数
x= (r)                  (1)
由概率统计知识可知,X与R在对应点的分布函数的数值应当相等,即产生R的反变换
F(x)=F(r)                 (2)
其中,r为(1)式的解,即r= -1(x)=Ψ(x)
  在特殊情况下,若R是在[0,1]区间内的均匀分布的连续随机变量,那么R<r的概率P(R<r)=r。此时,(2)式可以简化为
F(x)=F(r)=r                (3)
其反函数
x=F-1(r)                  (4)
具有分布函数F,现予以证明:因为分布函数是单调递增函数,其反函数存在。由概率知识可知,对任意实数X,有
  P(X<x)=P(F-1(R)<x)=P(R<F(x))
  因为R是在[0,1]区间上的均匀分布的连续随机变量,故P(R<F(x))=F(x),即F-1(r)具有分布函数F。
  (4)式表明,要产生一个服从某种分布的随机数,可以先求出其分布函数的反函数的解析式,再将一个在[0,1]区间内的均匀随机数的值代入其中计算就可以了。
3 应用实例
例1 产生密度函数满足指数分布

的随机数,其中α>0。
因为  ,故分布函数为:

由(4)式可得
             (5)
当r为[0,1]区间内的均匀随机数时,1-r也是[0,1]区间内的均匀随机数,故(5)式还可以简化为:
                (6)
假定计算机高级语言已提供了产生在[0,1]区间内均匀分布的随机数的函数RND(0),则根据(6)式可以写出产生服从指数分布的随机数的类PASCAL语言的函数如下:
  FUNC get_exp_random(alpha:real):real;
  {产生服从指数分布的随机数,值参alpha为比例参数}
  get_exp_random=-ln(RND(0))/alpha;
ENDF; {get_exp_random}
  例2 产生服从正态分布的随机数
  正态分布X~N(a,σ)都可以由标准的正态分布X′~N(0,1)经过变换X=a+σX′得到,在此只讨论服从标准正态分布的随机数的产生方法。标准正态分布的密度函数为:
               (7)
但其分布函数不能用有限的解析形式来表示,给转换带来困难,但可以用以下的变换来产生随机数。
  假定r1与r2是[0,1]区间的两个独立的均匀分布随机数,现将其作如下的变换,令
             (8)
再将其反变换为:
              (9)
(9)式中的C为常数。由此可导出其密度函数为:
           (10)
比较(10)式与(7)式,可知X1与X2是两个相互独立的服从正态分布的随机变量,因而(8)式是与(4)相当的据以产生随机数的表达式。由此可以写出产生服从标准正态分布随机数的类PASCAL语言的过程如下:
  PROC gauss(VAR x1,x2:real);
  {产生服从正态分布的随机数对,用变量参数x1与x2传递随机数}
  pi:=3.14159265;  {赋π值}
  r1:=RND(0);  r2:=RND(0);
  s:=SQRT(-2*ln(r1));  {中间变量赋值}
  x1:=s*cos(2*pi*r2);
  x2:=s*sin(2*pi*r2);
  {正态分布随机数赋给变量参数}
ENDP; {gauss}
  此过程每调用一次能产生两个相互正交的标准正态分布随机数。

- 作者: 秦秦 2004年11月26日, 星期五 15:42  回复(2) |  引用(0) 加入博采

c语言里函数rand()和srand()的用法

 

rand(void)用于产生一个伪随机unsigned int 整数。

srand(seed)用于给rand()函数设定种子。


srand 和 rand 应该组和使用。一般来说,srand 是对 rand 进行设置。

比如:
srand((UINT)GetCurrentTime());
int x = rand() % 100;

是生成 0 到 100 之间的随机数。

 

srand()是用来初始化随机种子数的,因为rand的内部实现是用线性同余法做的,他不是真的随机数,只不过是因为其周期特别长,所以有一定的范围里可看成是随机的,式子如下:

rand = rand*const_1 + c_var;

srand函数就是给它的第一个rand值。

 

用"int x = rand() % 100;"来生成 0 到 100 之间的随机数这种方法是不或取的,

比较好的做法是: j=(int)(n*rand()/(RAND_MAX+1.0))   产生一个0到n之间的随机数

- 作者: 秦秦 2004年11月26日, 星期五 14:57  回复(0) |  引用(0) 加入博采

(转)C语言笔试轻松过—也谈二级C应试技巧
  二级C语言笔试只有选择题和填空题两种题型。这两种题型的解题方法有所不同,考生在备考时要深化对基本概念和知识点的理解,并注重实践,同时要作一些针对性的练习,特别是历年真题,从中找出规律性的东西以及解题技巧。
  二级C语言笔试只有选择题和填空题两种题型。这两种题型的解题方法有所不同,考生在备考时要深化对基本概念和知识点的理解,并注重实践,同时要作一些针对性的练习,特别是历年真题,从中找出规律性的东西以及解题技巧。

   一、选择题

  这种类型的题,要求考生从四个待选答案中选择一个正确答案。考生可综合运用直选法,排除法等多种方法。但是这类题目考的知识点往往都比较多且细,容易出错,考生在做这类题时,切忌不加分析,一看就选,从而漏掉正确的答案。如2003年9月笔试第49题:

  有以下程序

  mai( )

  { int a[3][3],p,i;

   p=&&a[0][0];

   for (i=0;i<9;i++) p[i]=i+1;

   printf("%d\n",a[1][2]);

  }

  程序运行后的输出结果是

  (A)3 (B)6 (C)9 (D)2

  此题主要考的知识点有:(1)数组与指针的关系;(2)数组的初始化和数组元素的引用。在C语言中,数组与指针有着非常密切的联系。任何能用数组下标完成的操作也都可以用指针来实现。语句"p=&&a[0][0];"使p指向数组中的第0号元素,即a[0][0],指针变量p中存放了数组元素a[0][0]的地址,由于数组元素在内存中是连续存储的,因此,我们就可以通过指针变量p访问数组中的任何一个元素。本题中通过"for (i=0;i<9;i++) p[i]=i+1;"语句使a[3][3]={1,2,3,4,5,6,7,8,9},所以a[1][2]=6。这里要特别注意C语言中数组的下标从0开始,不要错选a[1][2]=3。

   二、填空题

  填空题主要考查考生对基础知识的准确理解。对于这类型的题,考生应深刻理解题意,明确题目要求,运用相关知识做出正确回答。在历年考试中,考生这部分试题的得分直接决定考试成绩。由于这部分共20个空,计40分,有的考生能得35~40分,而有的考生却得不到10分,直接拉开了最后成绩。在判卷过程中发现考生常犯的错误有以下几个方面:

  1.基础知识掌握不扎实,概念理解不准确。

  如2003年9月填空第8题:

  main( )

  {int a=1,b=3,c=5;

   if (c=a+b) printf ("yes\n");

   else printf("no");

  }

  题目问程序运行后的输出结果,答案应是yes。因为"if (c=a+b) printf ("yes\n");"中的条件"c=a+b"是一个赋值语句,c的值为a+b=1+3=4,所以条件为真。而许多考生却把赋值语句"c=a+b"理解为关系表达式"c==a+b"即5=1+3为逻辑假,故答no。

  2.答案表述不准确,会做的题却不得分或少得分。

  如第12题:

  main( )

  {int i,n[ ]={0,0,0,0,0};

  for(i=1;i<=4;i++)

   {n[i]=n[i-1]2+1;

   printf("%d ",n[i]);

   }

  }问程序运行后的输出结果是____。答案是"1 3 7 15"许多考生虽然写对了但却在每个数字后加了标点而不得分如"1,3,7,15"或"1. 3. 7. 15"。

  又如第19题:

  以下程序的功能是将字符串s中的数字字符放入d数组中,最后输出d中的字符串;例如,输入字符串:abc123edf456gh,执行后输出:123456。请填空:

  #include

  #include

  main( )

  {char s[80], d[80]; int i, j;

  gets(s);

  for(i=j=0;s[i]!='\0' ;i++)

   if( ) {d[j]=s[i];j++}

  d[j]='\0' ;

  puts(d);

  }

  答案应是s[i]<='9'&&&&s[i]>='0'或s[i]<=48&&&&s[i]>=57而许多考生却把">=","<="写成"≥","≤"导致不能得分。

  3.注意答题卡的号码并不是试题卷上的题号,而是填空的顺序号。许多考生答题时将答案张冠李戴,位置写错,白白丢了分。

  总之,只要考生能准确理解基本知识点,善于动手动脑多练习,举一反三,触类旁通,就能从中找出规律性的东西,轻松通过笔试。

- 作者: 秦秦 2004年11月26日, 星期五 14:17  回复(0) |  引用(0) 加入博采

C语言学习中的四大难点 (转贴)

      C语言是一种结构化语言,适于按模块化方式组织程序,层次十分清晰,易于调试和维护。C语言的表现能力和处理能力极强,不仅具有丰富的运算符和数据类型,便于实现各类复杂的数据结构,而且还可以直接访问内存的物理地址,进行位(bit)一级的操作。

 


算术表达式

  C语言中的算术运算有单目运算和双目运算两种。单目运算指的是该运算符只能连接一个运算量,除了正负号外,主要有++(加1)和--(减1),它有前缀和后缀之分,主要区别在于前缀++n表示先令n=n+1,然后取n的值,后缀n++表示先取n的值,然后令n=n+1。双目运算是指该运算符的左右两侧都必须有运算量。常见的双目运算符有:+、-、、/、%等。诸如x+y、x/y、xy等运算均为双目运算。遇到双目运算时,要特别注意数据的类型问题。具体要求有以下几点:

  1.双目运算的结果的类型必须与运算量的类型一致;

  2.如果参与双目运算的两个运算量类型不一致,系统将自动把其中的一个进行类型转换,使两个运算量的类型一致后再进行运算。自动转换的规则是:按"向高看齐"的原则进行转换。在几个基本的数据类型中,由高到低的排列顺序为:double、int、char。

  2000年春季考试中有一道选择题:

  下列程序的输出结果是( )

A) 3 B) 3.2 C) 0 D) 3.07

main
 double d=3.2 int xy
x=1.2 y=x+3.8/5.0
printf″%d \n″ dy

  解析:本题中,程序先执行语句x=1.2,根据赋值运算的类型转换规则,这里要将double型的常量1.2转换为int型,即取整为1,然后将1赋值给变量x。接下来执行语句y=x+3.8/5.0;根据运算符的优先级,先计算小括号内,再计算除法,最后执行赋值运算。小括号内的运算过程为:先将整型变量x的值1转换为double型1.0,然后与3.8进行加法运算,得到中间结果4.8。接着进行除法运算4.8/5.0,其结果小于1.0,这里没有必要计算出精确值,因为接着进行赋值运算,赋值号左边的变量y的类型为整型,于是对这个小于1.0的中间结果进行取整,结果为0,于是变量y的值为0。因此该程序的输出结果应该是0,即正确答案为C。


逗号表达式

  C语言中的逗号表达式的形式如下:

表达式1,表达式2,表达式3,......,表达式n

  学习逗号表达式时一定要掌握它的要领:1.逗号表达式的运算过程为:从左往右逐个计算;2.逗号表达式是作为一个整体的,它的最终结果就是最后一个表达式(也即表达式n)的值;3.逗号运算符的优先级别是所有运算符中最低的。只有这样,才能真正掌握这种运算,得出正确的解答。

  2001年秋季考试中有一道选择题(此题曾在1998年春季考试中出现过):

  若已定义x和y为double类型,则表达式:x=1y=x+3/2的值是:

A) 1 B) 2 C) 2.0 D) 2.5

  解析:该表达式就是一个逗号表达式,所以要按照运算顺序先运算x=1,所以变量x的值为1.0,然后运算y=x+3/2,此表达式中需先计算二个整数相除3/2,结果为整数1,然后再与x相加,结果为2.0。由于逗号表达式x=1y=x+3/2的值就是其最后一个表达式即y=x+3/2的值,此值即为2.0,所以正确的答案应该是C。

复合语句

  复合语句就是用一对"{}"把若干语句括起来构成一个语句组,复合语句是C语言中最重要的一种语句,语句的形式如下:

语句l;语句2;...;语句n

  一个复合语句在语法上视为一条语句,在复合语句中,花括号内的语句数量不限,可以有执行语句,也可以有定义部分,定义部分应该出现在可执行语句的前面,复合语句可以嵌套使用,例如:{语句1;{语句2;...;语句n;}}。

  复合语句还可以嵌套C语言中任何结构的控制语句,如if、switch、while、for等。使用好复合语句的关键是理解和掌握变量的作用域。

  2002年春季考试中有一道填空题:


  下面程序的输出结果是__________

# include
main
int a=3b=2c=1
c-=++b
b=a+c
int b=5c=12
c/=b2
a-=c
printf"%d%d%d"abc
a+=--c

printf"%d%d%d"abc

  解析:本题程序中函数main的首部定义了3个整形变量a、b、c,按它们的初值,可计算执行复合语句之前c的值为-2,b的值为3。进入复合语句后,变量b、c被重新定义,并赋以初值,用户可计算出复合语句中a、b、c的值分别是2、5、1,第一个printf语句输出"251"(没有引号,下同),最后执行复合语句中的最后一条语句,可以得到a的值为2。变量b、c在main首部及复合语句中均被说明,在复合语句中,说明b、c的作用域只限制在本复合语句中,所以执行复合语句之后的printf语句中的b、c的输出值与复合语句中b、c的值无关,其值应该取复合语句之前的两个赋值语句的计算结果,即b值为3,c值为-2,也就是说,第二个printf语句的输出结果为"23-2",所以正确答案为"25123-2"。


指针与一维数组

  
指针与一维数组是二级C语言的必考内容,甚至有时一次考试中会出现2到3个相关的题目,因此,掌握这一类题型的解答技巧是十分重要的。一般情况下,题目总是先定义一个一维数组和一个指针变量,如"int a=12345p",然后将数组a的首地址赋值给指针变量p,使指针p指向数组a的首地址,即"p=a",这样就完成了数组与指针之间指向关系的建立。这是该类题目在提出问题前必须做的一件事,也是考生解答此类问题需要了解的前提条件。注意:数组a的首地址有两种表示方法,一是直接用数组名a表示,二是用数组的第一个元素a0的地址&a0表示,这两种表示法是完全等价的。因此,上述表达式"p=a"也可写成"p=&a0"。通过语句"p=a"在数组与指针之间建立了指向关系之后,接下来必须弄明白以下两组等价关系:

  第一组等价关系:以下4种表示法是等价的,它们均表示下标为i的数组元素ai(本例中,i的取值范围为0到4):

ai pia+ip+i

  第二组等价关系:以下4种表示法也是等价的,它们均表示下标为i的数组元素ai的地址值

&ai &pi a+i p+i

  数组名a和指针p在使用时是可以相互替代的,所以凡使用a的地方均可以p替代,反之亦然。这其中要注意以下事实:a是一个常量,它的值是不可改变的,而p是一个变量,它的值是可以改变的,这是它们之间的惟一区别。

  明白了以上等价关系之后,就可以解答大部分此类题目了。

  2002年春季考试中有一道选择题:

  若有以下定义


int a10=12345678910p=a

  则值为3的表达式是

  A)p+=2p++ B)p+=2++p

  C)p+=3p++ D)p+=2++p

  解析:该题考查的主要内容就是指针与一维数组,当然它还涉及到了指针的移动以及运算符++和之间的优先级问题。首先确定,值为3的数组元素是a2,因此也可用p2、a+2或p+2表示,但题目的4个选择答案中都没有出现,所以要再考虑其它途径。注意到4个表达式均为逗号表达式,它们的值应该分别等于各自最后一个表达式的值。再看表达式p+=2的作用,在进行这一运算之前,指针p指向数组元素a0,表达式p+=2使指针p向后移动了2个存储单元,也即运算后指针p指向了数组元素a2,同样,经过p+=3的运算后,指针p将指向数组元素a3。现在看答案A,先经p+=2运算,使p指向a2,然后通过指针运算符引用表达式p++所指向的元素,我们知道,表达式p++的值就是p的值,所以p++的值就等于p的值,即a2的值3,它正符合题目要求,因此,A是正确答案。B表达式的值应该为4(先使p指向a3,然后通过p取值),C表达式的值应该为4(先使p指向a3,再通过p取值),D表达式的值也为4(先使p指向a2,再通过p取值,最后自增1)。

- 作者: 秦秦 2004年11月26日, 星期五 14:03  回复(2) |  引用(0) 加入博采

在c语言中如何根据公式产生随机数

  能不能说说这个程序?

  这是根据公式"k=((k*159)+23)%n+1"求随机数。

  运行后输入"3"就提示:

  "3" is not recognized as an internal or external command,operable program or batch file.

  的中文意思是:"3"不是被承认作为一种内部或者外部命令,可操作计划或者批处理文

  输入其它数也一样!

  为什么?


这个公式是怎么产生随机数啊?

 #include "stdio.h"                         /*应用函数printf和scanf*/
 #define N 10
 static unsigned long k=-1;                 /*k为静态无符号整型全局变量*/
 void unsigned startnum(unsigned int seed)
  {
    k=seed;                                 /*返回k值*/
  }

 unsigned randnum(long n)                   /*n为形参*/
   {
     k=((k*159+23)%n)+1;
     return k;
   }
 main()
 {
   register unsigned int i;                 /*寄存器变量*/
   long n=0;                                /*自动整型局部变量*/
   while(!(n>0&&(k>0&&k<=65536)))
     {
       printf("\n Input the seed and the max random[1-65535]:\n");
       scanf("%ld%ld",&k,&n);
       if(n<=0)
  printf("\n wrong seed!");          /*显示错误信息*/
       if(k<=0||k>65536)
  printf("\n wrong max random!");
     }
   startnum(n);                             /*n为实参,传值调用*/
   for(i=0;i<N;i++)
     printf("%6u",randnum(n));              /*循环求值并显示*/
   return;
 }

- 作者: 秦秦 2004年11月24日, 星期三 16:38  回复(6) |  引用(0) 加入博采

怎样学习C语言
工欲善其事,必先利其器~

1:工欲善其事,必先利其器
这里介绍几个学习C语言必备的东东:
   一个开发环境,例如turbo C 2.0,这个曾经占据了DOS时代开发程序的大半个江山。但是现在windows时代,用turbo C有感觉不方面,编辑程序起来很吃力,并且拖放,更没有函数变量自动感应功能,查询参考资料也不方便。建议使用Visual C++,这个东西虽然比较大块头,但是一旦安装好了,用起来很方便。
   一本学习教程,现在C语言教材多如牛毛,但推荐大家使用《C语言程序设计》谭浩强主编 第二版 清华大学出版社,此书编写的很适合初学者,并且内容也很精到。
   除此以外,现在有很多辅助学习的软件,毕竟现在是Window时代了,学习软件多如牛毛,不象我们当初学习,只有读书做题这么老套。我向大家推荐一个"集成学习环境(C语言)",里边的知识点总结和例程讲解都非常好,还有题库测试环境,据说有好几千题,甚至还有一个windows下的trubo C,初学者甚至不用装其它的编译器,就可以练习编程了,非常适合初学者。还有一个"C语言学习系统"软件,不过感觉只是一个题库系统,如果你觉得题做的不够,不妨也可以试试。

2:葵花宝典
学习计算机语言最好的方法是什么?答曰:读程序。
    没错,读程序是学习C语言入门最快,也是最好的方法。如同我,现在学习新的J#,C#等其他语言,不再是抱着书本逐行啃,而是学习它们的例程。当然,对于没有学过任何计算机语言的初学者,最好还是先阅读教程,学习完每一章,都要认真体会这一章的所有概念,然后不放过这一章中提到的所有例程,然后仔细研读程序,直到每一行都理解了,然后找几个编程题目,最好是和例程类似的或一样的,自己试图写出这段已经读懂的程序,不要以为例程你已经读懂了,你就可以写出和它一样的程序,绝对不一定,不相信你就试一试吧,如果写不出来,也不要着急,回过头来再继续研究例程,想想自己为什么写不出来,然后再去写这段程序,反反复复,直到你手到擒来为止,祝贺你,你快入门了。

3:登峰造极
写程序的最高境界其实就是掌握各种解决问题的手段(数据结构)和解决问题的方法(算法)。
是不是写出底层程序就是程序设计高手呢?非也,写底层程序,无非是掌握了硬件的结构,况且硬件和硬件还不一样,要给一个芯片写驱动程序,无非就是掌握这块芯片的各种寄存器及其组合,然后写值读值,仅此而已。这不过是熟悉一些io函数罢了。那么怎样才算精通程序设计呢?怎样才能精通程序设计呢?举个例子:你面前有10个人,找出一个叫"张三"的人,你该怎么办?第一种方法:直接对这10个人问:"谁叫张三"。第2种方法:你挨个去问"你是不是张三?",直到问到的这个人就是张三。第三种方法:你去挨个问一个人"你认不认识张三,指给我看"。不要小看这个问题,你说当然会选第一种方法,没错恭喜你答对了,因为这个方法最快,效率最高,但是在程序设计中找到解决问题的最优方法和你用的手段却是考验一个程序员程序设计水平的重要标志,而且是不容易达到的。刚才这个问题类似于数据结构和算法中的:Map数据结构,穷举查找和折半查找。所以掌握好数据结构和一些常用算法,是登峰造极的必然之路。最后给大家推荐严尉敏的《数据结构》清华大学出版社,希望每一个想成为程序设计高手的人研读此书。

前人的经验总结:
1.自己编程
2.看书可以通过考试,但成不了程序员.
3.基础知识比语言重要.
4.少抱怨教育体制,多学些本事.
5.不要为了钱和工作学习.
6.不要因为感时髦而学习编程.
7.认真,负责,自信,谨慎:
    认真:学习和写代码的过程要认真,编程是要全身心投入的.
    负责:要对自己写的代码负责,要终身维护自己的代码,因为那是你的孩子.
    自信:相信自己的能够写出好的代码,相信自己的代码是最好的.
    谨慎:思考问题和编码要谨慎,不要想当然,每一行都要细细揣摩.

- 作者: 秦秦 2004年11月24日, 星期三 12:06  回复(0) |  引用(0) 加入博采

推荐:关于C语言关键的核心概念

 推荐~~

  初学C语言的同学应该首先了解C语言关键的核心概念(结构化、三个执行流程、优先级、指针、文件、共用体、函数、作用域、重载等 ),只有弄明白了这些才能在今后的学习中游刃有余的把握C语言的精髓。这几个概念就像逻辑线一样,把整个C语言的体系贯穿起来,给人一种"结构化"的思想体系。下面我简要谈一下这几个核心概念。

     1、从宏观角度来看,结构化是C语言的编程思想基础,就是说C语言每一个功能模块就是一个结构,每一个结构实现一个运算或一个算法,这个结构就用大括号表示"{  }",大括号里面的就是算法。尤其注意的是大括号的"}"括在那里,就决定在哪里结束算法功能。这些是初学者经常犯的错误,往往会把算法功能的结束点弄错。



    2、 三个执行流程就是顺序流程、条件流程、循环流程。三个流程都是计算机通用的执行流程,是必须了解的流程,每一个算法都基于这三个流程执行顺序。



    3、 优先级是对多个函数并列时候优先算法的特权,没有注意优先级的顺序就会把算法出错,这些优先级是必须记住的。



    4、 指针是C语言的重要特点,是对运算速度加快运算的重要精髓。它是对数据地址的操作,而不是对数据的操作。



    5、文件和共用体是很简单的概念,不用多说了。文件顾名思义和日常概念一样,学过数据软件的都对共用体了解不是太难。



    6、从微观角度来看,函数是C语言的驱动机制,所有的语句都由函数驱动来实现的。记住函数命令和相关的配置参数,就能好好的利用C的优势。注意的是,函数不能记错,不然你将得出错的结果。如果能学会调试,那就会更深一层了解函数功能的作用。



    7、作用域就像使用期限一样,说明从那里到那里所起的作用,在这之外的就不起作用了(过期的东西就不值钱一样)。把握好作用域的使用方式,就能明确函数的关系,不会在巨大的函数名里面迷失方向。



    8、重载就是为了方便用户,使用类似于调用的机制给用户减少写入时间的功能。就像查字典一样,你不懂一个字,就要去查字典(相当于调用别的工具来实现你要做的事),而查字典是你已经学会的东西,就可以做这件事了。



    学习C语言从大体上了解还不够,要把各种原理在脑海里模拟一遍,实现把计算机C的功能在人脑里运作,就能从宏观上把握C的步骤。

  

  不要再想那些还没发生的事,

  集中精力做好现在的事!

- 作者: 秦秦 2004年11月24日, 星期三 12:04  回复(0) |  引用(0) 加入博采

推荐:经典英语学习网站(转)

 推荐~~
http://www.edunet.com/elt
主题:是一个全方位的学英语作为第二语言的网站
功能:聊天室,语法讲解,练习,小测试,成语讲解
特色:特别深入地介绍了语法,听力,沟通技巧等
对象:ESL教师和学英语人士

《世界日报》北美版-生活美语
http://www.chineseworld.com/publish/37_9999.r/r.htm
主题:生活化和实用化的英语网页
功能:分主题讲解英语的实用方法,还有母语非英语人士闹的语言笑话
特色:灵活生动,有许多实例
对象:英语基础教好的人士

Edunet.com
http://www.englishtown.com
主题:是目前网上最有深度的英语学习网站
功能:非常好的语法讲解,练习,和阅读材料
特色:正宗英国英语
对象:学英语人士

English-at-Home
http://www.english-at-home.com/
主题:是一个全方位的学英语作为第二语言的网站
功能:聊天室,语法讲解,练习,小测试,成语讲解
特色:特别深入地介绍了语法,听力,沟通技巧等
对象:ESL教师和学英语人士

English, baby!
http://www.englishbaby.com/
主题:是一个年轻人学习交流的美国英语网站
功能:每天不同的网上课程,以美国流行文化为主题
特色:可以学到很多美国俚语和方言
对象:面向年轻人

Englishclub.net
http://www.englishclub.net/
主题:丰富齐全的商业性英文网站
功能:语法讲解,练习,参考资料,教师材料
对象:ESL教师和学英语人士

Englishpage
http://www.englishpage.com/index.html
主题:针对英文基础较好的学习人士和教师的网站
功能:阅读,游戏。语法讲解,讨论等
特色:深入讲解了时态用法,每周有新课程推出,旧课程可以在存档中找到
对象:ESL教师和学英语人士

The English Zone
http://members.home.net/englishzone/index.html
主题:非商业性英文学习网站
功能:语法讲解,练习,小成语讲解,英文笑话,阅读和写作
对象:学英语人士

ESL Flow
http://www.homestead.com/ESLflow/Index.html
主题:内容组织得很好的英文网站
功能:语法讲解,口语,英语对话,阅读和课程安排
特色:用流程图的方式讲解英语语法概念
对象:ESL教师和学英语人士

ESL House
http://www.eslhouse.com/
主题:内容广泛,参考资料甚多
功能:大量词汇讲解,课程安排和参考资料
特色:多媒体中心可播放课程
对象:ESL教师和学英语人士

ESL Partyland
http://www.eslpartyland.com/default.htm
主题:自学和互相交流
功能:75个互动式测试和15个论坛,让学生互相交流,教师可以下载课程材料
特色:互动式
对象:ESL教师和学英语人士

ESL STUDY HALL
http://gwis2.circ.gwu.edu/~gwvcusas/
主题:由George Washington University的Professor Christine Meloni维护的ESL链接网页
功能:有学多学习英语的链接
对象:ESL教师和学英语人士

To Learn English.com
http://www.ToLearnEnglish.com
主题:内容广泛,资源丰富,值得一看
功能:聊天室,语法讲解,练习,小测试,图片,论坛
特色:做完练习可以得到评语,老师可以在线制作试题
对象:ESL教师和学英语人士

LinguaCenter Home Page
http://deil.lang.uiuc.edu/
主题:包括了网上学英语的一些最基本的内容
功能:语法讲解,练习,互动式3听力训练,笔友交换,教师参考
对象:ESL教师和学英语人士

Longman English Language Teaching
http://www.longman-elt.com/index.html
主题:为中国朋友所熟知的朗曼英语教学方法
功能:测试,专题文章,链接,小窍门
对象:ESL教师和学英语人士

Parlo - Language, Culture, Life
http://www.parlo.com/index.asp
主题:学语言的网站
功能:对语言结构,国际文化作出探讨
特色:教你怎样学语言,而不仅是英语
对象:ESL教师和学英语人士

Peak English
http://www.peakenglish.com
主题:在线的远程英语学习网站 功能:词汇,阅读,听力(用REALAUDIO),语法课程,
特色:所教英语是用于美国的
对象:学英语人士

Schmooze University
http://schmooze.hunter.cuny.edu:8888/
主题:英语学习个网站,可以一对一或分小组进行对话
功能:在线字典,语言游戏,USENET
对象:学英语人士

Tower of English
http://members.tripod.com/~towerofenglish/index.htm
主题:非常友好的英文学习网站
功能:设计专业的网站,大量的有用资源
对象:学英语人士

- 作者: 秦秦 2004年11月24日, 星期三 11:38  回复(0) |  引用(0) 加入博采