【转】安装MinGW和MSYS

今天和一位朋友聊天,了解到他现在win平台用eclipse来学习编程,于是我也打算安装一个试 试。google了之后发现在win平台上用eclipse开发c/c++程序需要c/c++编译器,而一般大家会安装mingw,当然也可以安装 cygwin,不过cygwin的安装包相对来说大很多,而mingw的软件包加起来总共也就只有20多m。

本来是不需要来介绍如何安装mingw的,因为安装方式很傻瓜,通过网络安装,根据提示一步一步往下设置就可以了,但我发现网络安装的速度实在不敢 恭维,几kb/s甚至0.xx kb/s的速度去下载一个9mb多的软件包实在太折磨人了。于是,我找到了一个既傻瓜又快速的安装方法,如下:

我下载的mingw安装程序为MinGW-5.1.3.exe,第一次打开之后它会产生一个mingw.ini配置文件,里面是相关版本的软件包信息,三个组合包:current、previous、candidate,我打算安装candidate版本的,下面分别是相应的软件包信息:

binutils=binutils-2.17.50-20060824-1.tar.gz|21940
core=gcc-core-3.4.5-20060117-1.tar.gz|8644
gpp=gcc-g++-3.4.5-20060117-1.tar.gz|16140
g77=gcc-g77-3.4.5-20060117-1.tar.gz|5161
ada=gcc-ada-3.4.5-20060117-1.tar.gz|33352
java=gcc-java-3.4.5-20060117-1.tar.gz|46767
objc=gcc-objc-3.4.5-20060117-1.tar.gz|4559
make=mingw32-make-3.81-2.tar.gz|720

那么我现在只需要去http://prdownloads.sourceforge.net/mingw下载上述软件包中我需要的包即可。用flashget或者thunder下载起来,速度可就快多了。把下载的软件包和MinGW-5.1.3.exe放在同一目录,再双击打开它,就可以顺利的安装完mingw了。

如果你喜欢动手,还可以这样来安装mingw:

下载的文件可以用WinRAR解开。接着操作如下:

1. 建立文件夹C:MinGW    (假设你把mingw安装在C盘根目录)

2. 解压binutils-2.17.50-20060824-1.tar.gz到这个文件夹,并在控制台中执行下面的命令:

cd info

ren dir dir.binutils

3. 解压gcc-core-3.4.5-20060117-1.tar.gz到这个文件夹,并在控制台中执行下面的命令:

copy dir dir.gcc

copy dir+dir.binutils

4. 解压gcc-g++-3.4.5-20060117-1.tar.gz到*MinGW

5. 解压mingw-runtime-3.10.tar.gz到*MinGW

6.解压w32api-3.7.tar.gz到*MinGW,在控制台中执行:

ren dir dir.gcc.binutils

7.解压mingw32-make-3.81-1.tar.gz到*MinGW,在控制台中执行:

copy dir+dir.gcc.binutils

更多细节可以参看这里:http://www.mingw.org/MinGWiki/index.php/Install%20MinGW

你如果需要增加其他语言的编译支持,也是同样的方法安装相应的包。

接下来要做两个设置:

1.拷贝一份MinGWbin下的mingw32-make.exe改名为make.exe,同样是放在MinGWbin下面。

2.设置windows系统的环境变量,编辑Path变量,在变量值的最前面添加“C:MinGWbin;”,这是为了防止和VC/.NET之类的make命令冲突。

接下来安装MSYS,你只要下载下面两个包就可以了:MSYS-1.0.10.exemsysDTK-1.0.1.exe

安装MSYS-1.0.10时,接受所有默认的选项,或者依照个人习惯设置,安装到最后会出现一个DOS窗口:

输入 y ,回车继续;

接着窗口中会出现:

Do you have MinGW installed? [yn ] 当然是选择 y

下面程序会询问的安装路径:

Please answer the following in the form of c:msys

Where is your MinGW installation?

输入C:MinGW (你如果安装在其他路径就输入相应的路径)。

之后写一篇关于Eclipse的安装的日志.

MD5算法之C#程序 MD5算法描述【转】

MD5算法描述

作者:rufi 2004.06.22
当我要写一个MD5算法的程序时,发现中英文的语言描述都有一些不确切的地方,某些个细节
讲得不清楚,或者说很费解。最后不得不拿出C语言的源程序来调试,这对于理解算法是很不
利的。于是就总结了一下我摸索到的一些要点。
1.
来历
MD5
的全称是message-digest algorithm 5(信息摘要算法,在90年代初由mit laboratory
for computer science
rsa data security incronald l. rivest开发出来,
md2md3md4发展而来。 http://www.ietf.org/rfc/rfc1321.txt ,是一份最权威的文档,
ronald l. rivest19928月向ieft提交。
2.
用途
MD5
的作用是对一段信息(message)生成信息摘要(message-digest),该摘要对该信息具有
唯一性,可以作为数字签名。用于验证文件的有效性(是否有丢失或损坏的数据),对用户
密码的加密,在哈希函数中计算散列值。
3.
特点
输入一个任意长度的字节串,生成一个128位的整数。由于算法的某些不可逆特征,在加密应用
上有较好的安全性。并且,MD5算法的使用不需要支付任何版权费用。
4.
说明
唯一性和不可逆性都不是绝对的,从理论上分析是一种多对一的关系,但两个不同的信息产生
相同摘要的概率很小。不可逆是指从输出反推输入所需的运算量和计算时间太大,使用穷搜字
典的方法又需要太多的存储空间。
5.
算法描述
算法输入是一个字节串,每个字节是8bit.
算法的执行分为以下几个步骤:
第一步,补位:
MD5
算法先对输入的数据进行补位,使得数据的长度(byte为单位)64求余的结果是56
即数据扩展至LEN=K*64+56个字节,K为整数。
补位方法:补一个1,然后补0至满足上述要求。相当于补一个0x80的字节,再补值
0的字节。这一步里总共补充的字节数为063个。
第二步,附加数据长度:
用一个64位的整数表示数据的原始长度(bit为单位),将这个数字的8个字节按低位的在前,
高位在后的顺序附加在补位后的数据后面。这时,数据被填补后的总长度为:
LEN = K*64+56+8=(K+1)*64 Bytes

注意那个64位整数是输入数据的原始长度而不是填充字节后的长度,我就在这里栽了跟头.
第三步,初始化MD5参数:
有四个32位整数变量 (A,B,C,D) 用来计算信息摘要,每一个变量被初始化成以下
以十六进制数表示的数值,低位的字节在前面。
word A: 01 23 45 67
word B: 89 ab cd ef
word C: fe dc ba 98
word D: 76 54 32 10
注意低位的字节在前面指的是Little Endian平台上内存中字节的排列方式,
而在程序中书写时,要写成:
A=0x67452301
B=0xefcdab89
C
=0x98badcfe
D=0x10325476
第四步,定义四个MD5基本的按位操作函数:
X
YZ32位整数。
F(X,Y,Z) = (X and Y) or (not(X) and Z)
G(X,Y,Z) = (X and Z) or (Y and not(Z))
H(X,Y,Z) = X xor Y xor Z
I(X,Y,Z) = Y xor (X or not(Z))
再定义四个分别用于四轮变换的函数。
Mj表示消息的第j个子分组(从015),<<
FF(a,b,c,d,Mj,s,ti)
表示a=b+((a+(F(b,c,d)+Mj+ti)<<
GG(a,b,c,d,Mj,s,ti)
表示a=b+((a+(G(b,c,d)+Mj+ti)<<
HH(a,b,c,d,Mj,s,ti)
表示a=b+((a+(H(b,c,d)+Mj+ti)<<
II(a,b,c,d,Mj,s,ti)
表示a=b+((a+(I(b,c,d)+Mj+ti)<<

第五步,对输入数据作变换。
处理数据,N是总的字节数,以64个字节为一组,每组作一次循环,每次循环进行四轮操作。
要变换的64个字节用1632位的整数数组M[0 …15]表示。而数组T[1 … 64]表示一组常数,
T[i]
4294967296*abs(sin(i))32位整数部分,i的单位是弧度,i的取值从164
具体过程如下:
/*
设置主循环变量 */
For i = 0 to N/16-1 do
/*
每循环一次,把数据原文存放在16个元素的数组X. */
For j = 0 to 15 do
Set X[j] to M[i*16+j].
end /
结束对J的循环
/* Save A as AA, B as BB, C as CC, and D as DD.
*/
AA = A
BB = B
CC = C
DD = D
/*
1*/
/*
[abcd k s i]表示如下操作
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
[ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4]
[ABCD 4 7 5] [DABC 5 12 6] [CDAB 6 17 7] [BCDA 7 22 8]
[ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11] [BCDA 11 22 12]
[ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22 16]

/* 第2* */
/*
[abcd k s i]表示如下操作
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
[ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20]
[ABCD 5 5 21] [DABC 10 9 22] [CDAB 15 14 23] [BCDA 4 20 24]
[ABCD 9 5 25] [DABC 14 9 26] [CDAB 3 14 27] [BCDA 8 20 28]
[ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31] [BCDA 12 20 32]
/*
3*/
/*
[abcd k s i]表示如下操作
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
[ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36]
[ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA 10 23 40]
[ABCD 13 4 41] [DABC 0 11 42] [CDAB 3 16 43] [BCDA 6 23 44]
[ABCD 9 4 45] [DABC 12 11 46] [CDAB 15 16 47] [BCDA 2 23 48]

/* 第4*/
/*
[abcd k s i]表示如下操作
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
[ABCD 0 6 49] [DABC 7 10 50] [CDAB 14 15 51] [BCDA 5 21 52]
[ABCD 12 6 53] [DABC 3 10 54] [CDAB 10 15 55] [BCDA 1 21 56]
[ABCD 8 6 57] [DABC 15 10 58] [CDAB 6 15 59] [BCDA 13 21 60]
[ABCD 4 6 61] [DABC 11 10 62] [CDAB 2 15 63] [BCDA 9 21 64]
/*
然后进行如下操作 */
A = A + AA
B = B + BB
C = C + CC
D = D + DD
Next i /*
结束对I的循环*/
第六步,输出结果。
A
BCD连续存放,共16个字节,128位。按十六进制依次输出这个16个字节。

最后,用程序语言实现算法后,可以输入以下几个信息对程序作一个简单的测试,
看看程序有没有错误。
  MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
  MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
  MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
  MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
  MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
  MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =
d174ab98d277d9f5a5611c2c9f419d9f
MD5 ("123456789012345678901234567890123456789012345678901234567890123456789
01234567890") = 57edf4a22be3c955ac49da2e2107b67a

MD5算法之C#程序
MD5
算法比较特别,最适合用汇编语言来写,好多高级语言对之无能无力或效率极低。
比如我最开始尝试用PythonEuphoria编写,发现不太容易。相比而言,C#作为C家簇
中新兴的一门.net语言,功能比较全面。花了一晚上的工夫终于用C#最先实现了MD5
主要是由于对算法的一些细节不太注意,结果输出总是不对,调试了好长时间。

//源文件:md5.cs
// MD5 Alogrithm
// by rufi 2004.6.20 http://rufi.yculblog.com/
using System;
using System.Collections;
using System.IO;
public class MD5 {
//static state variables
private static UInt32 A;
private static UInt32 B;
private static UInt32 C;
private static UInt32 D;
//number of bits to rotate in tranforming
private const int S11 = 7;
private const int S12 = 12;
private const int S13 = 17;
private const int S14 = 22;
private const int S21 = 5;
private const int S22 = 9;
private const int S23 = 14;
private const int S24 = 20;
private const int S31 = 4;
private const int S32 = 11;
private const int S33 = 16;
private const int S34 = 23;
private const int S41 = 6;
private const int S42 = 10;
private const int S43 = 15;
private const int S44 = 21;

/* F, G, H and I are basic MD5 functions.
* 四个非线性函数:
*
* F(X,Y,Z) =(X&Y)|((~X)&Z)
* G(X,Y,Z) =(X&Z)|(Y&(~Z))
* H(X,Y,Z) =X^Y^Z
* I(X,Y,Z)=Y^(X|(~Z))
*
*
&与,|或,~非,^异或)
*/
private static UInt32 F(UInt32 x,UInt32 y,UInt32 z){
return (x&y)|((~x)&z);
}
private static UInt32 G(UInt32 x,UInt32 y,UInt32 z){
return (x&z)|(y&(~z));
}
private static UInt32 H(UInt32 x,UInt32 y,UInt32 z){
return x^y^z;
}
private static UInt32 I(UInt32 x,UInt32 y,UInt32 z){
return y^(x|(~z));
}
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
* Rotation is separate from addition to prevent recomputation.
*/
private static void FF(ref UInt32 a,UInt32 b,UInt32 c,UInt32 d,UInt32 mj,int s,UInt32 ti){
a = a + F(b,c,d) + mj + ti;
a = a << s | a >>(32-s);
a += b;
}
private static void GG(ref UInt32 a,UInt32 b,UInt32 c,UInt32 d,UInt32 mj,int s,UInt32 ti){
a = a + G(b,c,d) + mj + ti;
a = a << s | a >>(32-s);
a += b;
}
private static void HH(ref UInt32 a,UInt32 b,UInt32 c,UInt32 d,UInt32 mj,int s,UInt32 ti){
a = a + H(b,c,d) + mj + ti;
a = a << s | a >>(32-s);
a += b;
}
private static void II(ref UInt32 a,UInt32 b,UInt32 c,UInt32 d,UInt32 mj,int s,UInt32 ti){
a = a + I(b,c,d) + mj + ti;
a = a << s | a >>(32-s);
a += b;
}
private static void MD5_Init(){
A=0x67452301; //in memory, this is 0x01234567
B=0xefcdab89; //in memory, this is 0x89abcdef
C=0x98badcfe; //in memory, this is 0xfedcba98
D=0x10325476; //in memory, this is 0x76543210
}
private static UInt32[] MD5_Append(byte[] input){
int zeros=0;
int ones =1;
int size=0;
int n = input.Length;
int m = n%64;
if( m < 56 ){
zeros = 55-m;
size=n-m+64;
}
else if (m==56){
zeros = 0;
ones = 0;
size=n+8;
}
else{
zeros = 63-m+56;
size=n+64-m+64;
}
ArrayList bs = new ArrayList(input);
if(ones==1){
bs.Add( (byte)0x80 ); // 0x80 = $10000000
}
for(int i=0;i
bs.Add( (byte)0 );
}
UInt64 N = (UInt64) n * 8;
byte h1=(byte)(N&0xFF);
byte h2=(byte)((N>>8)&0xFF);
byte h3=(byte)((N>>16)&0xFF);
byte h4=(byte)((N>>24)&0xFF);
byte h5=(byte)((N>>32)&0xFF);
byte h6=(byte)((N>>40)&0xFF);
byte h7=(byte)((N>>48)&0xFF);
byte h8=(byte)(N>>56);
bs.Add(h1);
bs.Add(h2);
bs.Add(h3);
bs.Add(h4);
bs.Add(h5);
bs.Add(h6);
bs.Add(h7);
bs.Add(h8);
byte[] ts=(byte[])bs.ToArray(typeof(byte));
/* Decodes input (byte[]) into output (UInt32[]). Assumes len is
* a multiple of 4.
*/
UInt32[] output = new UInt32[size/4];
for(Int64 i=0,j=0;i
output[j]=(UInt32)(ts[i] | ts[i+1]<<8 | ts[i+2]<<16 | ts[i+3]<<24);
}
return output;
}
private static UInt32[] MD5_Trasform(UInt32[] x){
UInt32 a,b,c,d;
for(int k=0;k
a=A;
b=B;
c=C;
d=D;

/* Round 1 */
FF (ref a, b, c, d, x[k+ 0], S11, 0xd76aa478); /* 1 */
FF (ref d, a, b, c, x[k+ 1], S12, 0xe8c7b756); /* 2 */
FF (ref c, d, a, b, x[k+ 2], S13, 0x242070db); /* 3 */
FF (ref b, c, d, a, x[k+ 3], S14, 0xc1bdceee); /* 4 */
FF (ref a, b, c, d, x[k+ 4], S11, 0xf57c0faf); /* 5 */
FF (ref d, a, b, c, x[k+ 5], S12, 0x4787c62a); /* 6 */
FF (ref c, d, a, b, x[k+ 6], S13, 0xa8304613); /* 7 */
FF (ref b, c, d, a, x[k+ 7], S14, 0xfd469501); /* 8 */
FF (ref a, b, c, d, x[k+ 8], S11, 0x698098d8); /* 9 */
FF (ref d, a, b, c, x[k+ 9], S12, 0x8b44f7af); /* 10 */
FF (ref c, d, a, b, x[k+10], S13, 0xffff5bb1); /* 11 */
FF (ref b, c, d, a, x[k+11], S14, 0x895cd7be); /* 12 */
FF (ref a, b, c, d, x[k+12], S11, 0x6b901122); /* 13 */
FF (ref d, a, b, c, x[k+13], S12, 0xfd987193); /* 14 */
FF (ref c, d, a, b, x[k+14], S13, 0xa679438e); /* 15 */
FF (ref b, c, d, a, x[k+15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (ref a, b, c, d, x[k+ 1], S21, 0xf61e2562); /* 17 */
GG (ref d, a, b, c, x[k+ 6], S22, 0xc040b340); /* 18 */
GG (ref c, d, a, b, x[k+11], S23, 0x265e5a51); /* 19 */
GG (ref b, c, d, a, x[k+ 0], S24, 0xe9b6c7aa); /* 20 */
GG (ref a, b, c, d, x[k+ 5], S21, 0xd62f105d); /* 21 */
GG (ref d, a, b, c, x[k+10], S22, 0x2441453); /* 22 */
GG (ref c, d, a, b, x[k+15], S23, 0xd8a1e681); /* 23 */
GG (ref b, c, d, a, x[k+ 4], S24, 0xe7d3fbc8); /* 24 */
GG (ref a, b, c, d, x[k+ 9], S21, 0x21e1cde6); /* 25 */
GG (ref d, a, b, c, x[k+14], S22, 0xc33707d6); /* 26 */
GG (ref c, d, a, b, x[k+ 3], S23, 0xf4d50d87); /* 27 */
GG (ref b, c, d, a, x[k+ 8], S24, 0x

汉诺(Hanoi)塔问题(C#版)【转】

问题描述:古代有一个梵塔,塔内有3个座,ABC,开始时A座有64个盘,盘子大小不等,大的在上,小的在下。有一个老和尚想把这64个盘子从A座移到C座(如图所示),但每次只允许移动一个盘,且在移动过程中在3个座上始终保持大盘在下,小盘在上。
在移动地程中可以行用
B座,要求编程序打印出移动的步骤。

逆向推理:1.假如一个和尚能把上面63个盘子先搬到B座,第二个和尚再把最大的那个移到C,第三个和尚再把63个盘子移到C座;至此整个工作就完成的。

    2.问题是怎么才能把63个盘子移到B座,按照同样的方法,先把62个盘子选移到C

,再把第63个盘子移到B座,最后再将62个盘子移到B座。

    3……如此类推;

    4.从上面分析可以看出:只有等后面那个和尚搬完盘子,前面的和尚才能够去完成任。让我们来栈的数据结构:数据的处理只在一端处理,且是先进后出。所以用递归的方法去处理是正确的。


       (汉诺塔图)

using System;
using System.Collections.Generic;
using System.Text;

namespace HanoiProgram
{
    
class Program
     {
      
static int count = 0;//计数,总共搬动盘子的次数;
      static  void PrintMove(char x,char y)
         {
             Console.WriteLine(
"{0}–>{1}",x,y);
        
         }

       static void Hanoi(int n,char one, char two,char three)
         {
            
if (n == 1)
             {
                
++count;
                 PrintMove(one, three);
                
             }
            
else
             {
                
++count;
                
//借助中间塔把第N个盘上面(n-1)个盘子的搬移到另一个盘;
                 Hanoi(n1,one,three,two);
                
//打印第N个盘移到目标塔的步骤;
                 PrintMove(one,three);
                
//借助中间塔把原来第N个盘子上面的(n-1)个盘子搬到现在第N个盘子所在的塔上;
               
                 Hanoi(n
1,two,one,three);
             }
        
         }
        
static void Main(string[] args)
         {
             Console.WriteLine(
"开始搬64个盘子..");
             Hanoi(
4,A,B,C);
             Console.WriteLine(
"搬迁结速;一共进行了{0}次的搬迁。",count);
             Console.Read();
         }
     }
}

Visual C#中随机数使用实例

随机数的使用很普遍,可用它随机显示图片,用它防止无聊的人在论坛灌水还可以用来加密信息等等。本文讨论如何在一段数字区间内随机生成若干个互不相同的随机数,比如在从1到

20间随机生成6个互不相同的整数,并通
过此文介绍Visual c#中随机数的用法。

.net.Frameword中提供了一个专门产生随机数的类System.Random,此类默认情况下已被导入,编程过程中可以直接使用。我们知道,计算机并不能产生完全随机的数字,它生成的数字被称为伪随机数,它是以相同的概率从一组有限的数字中选取的,所选的数字并不具有完全的随机性,但就实用而言,其随机程度已经足够了。

我们可以用以下两种方法初始化一个随机数发生器;

第一种方法不指定随机种子,系统自动选取当前时前作随机种子:

Random ra=new Random();

第二种方法是指定一个int型的参数作为随机种子:

int iSeed=6;

Random ra=new Random(iSeed);

下面我们要用到Random.Next()方法产生随机数。

ra.Next();

它返回一个大于或等于零而小于2,147,483,647的数,这并不满足我们的需要,下面我们介绍它的重载函数和其它一些方法。

public virtual int Next(int);

用法:ra.next(20)

返回一个小于所指定最大值(此处为20)的正随机数。

public virtual int Next(int minValue, int maxValue);

用法:ra.next(1,20)

返回一个指定范围内(此处为1-20之间)的随机数,我们在下面的实例中会用到此函数。

类System.Random还有几个方法分别是:

公共方法:

NextBytes用随机数填充指定字节数组的元素。

NextDouble返回一个介于 0.0 和 1.0 之间的随机数。

受保护的方法:

Sample返回一个介于 0.0 和 1.0 之间的随机数,只允许子类对象访问。

以上介绍了随机数的基本用法,下面我们用一个实例来做更进一步的介绍。要在一段数字区间内随机生成若干个互不相同的随机数,比如在从1到20间随机生成6个互不相同的整数。

主要是下面两个函数getRandomNum与getNum:

public int[] getRandomNum(int num,int minValue,int maxValue){

Random ra=new Random(unchecked((int)DateTime.Now.Ticks));

int[] arrNum=new int[num];

int tmp=0;

for (int i=0;i<=num-1;i++){

tmp=ra.Next(minValue,maxValue); //随机取数

arrNum[i]=getNum(arrNum,tmp,minValue,maxValue,ra); //取出值赋到数组中

}

return arrNum;

}

getRandomNum即是在区间[minValue,maxValue]取出num个互不相同的随机数,返回的数组包含着结果。

其中随机数是这样创建的 Random ra=new Random(unchecked((int)DateTime.Now.Ticks));为什么不用Random ra=new Random();(系统自动选取当前时前作随机种子)呢?

用系统时间做随机种子并不保险,如果应用程序在一个较快的计算机上运行,则该计算机的系统时钟可能没有时间在此构造函数的调用之间进行更改,Random 的不同实例的种子值可能相同。这种情况下,我们就需要另外的算法来保证产生的数字的随机性。所以为了保证产生的随机数足够“随机”,我们不得不使用复杂一点的方法来获得随机种子。 在上面的这段程序中,我们首先使用系统时间作为随机种子,然后将上一次产生的随机数跟循环变量和一个与系统时间有关的整型参数相乘,以之作为随机种子,从而得到了每次都不同的随机种子,保证了产生足够“随机”的随机数。

函数getNum是一递归,用它来检测生成的随机数是否有重复,如果取出来的数字和已取得的数字有重复就重新随机获取。值得注意的是要用一同一个随机数实例生成,所以ra要作为参数传入getNum中,否则生成的数字会有重复。

public int getNum(int[] arrNum,int tmp,int minValue,int maxValue,Random ra){

int n=0;

while (n<=arrNum.Length-1)

{

if (arrNum[n]==tmp) //利用循环判断是否有重复

{

tmp=ra.Next(minValue,maxValue); //重新随机获取。

getNum(arrNum,tmp,minValue,maxValue,ra);//递归:如果取出来的数字和已取得的数字有重复就重新随机获取。

}

n++;

}

return tmp;

}

最后就是要显示出来,当点击一个button时取出的数字显示在一个label中。

private void button1_Click(object sender, System.EventArgs e)

{

int[] arr=getRandomNum(6,1,20); //从1至20中取出6个互不相同的随机数

int i=0;

string temp="";

while (i<=arr.Length-1){

temp+=arr[i].ToString()+"n";

i++;

}

label1.Text=temp; //显示在label1中

}

随机数的作用不止如此,读者可用它进行游戏开发,安全验证等等,这有待读者去开发和实践。

原码如下:

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

namespace random

{

/// <summary>

/// Form1 的摘要说明。

/// </summary>

public class Form1 : System.Windows.Forms.Form

{

private System.Windows.Forms.Button button1;

private System.Windows.Forms.Label label1;

/// <summary>

/// 必需的设计器变量。

/// </summary>

private System.ComponentModel.Container components = null;

public Form1()

{

//

// Windows 窗体设计器支持所必需的

//

InitializeComponent();

//

// TODO: 在 InitializeComponent 调用后添加任何构造函数代码

//

}

/// <summary>

/// 清理所有正在使用的资源。

/// </summary>

protected override void Dispose( bool disposing )

{

if( disposing )

{

if (components != null)

{

components.Dispose();

}

}

base.Dispose( disposing );

}

#region Windows Form Designer generated code

/// <summary>

/// 设计器支持所需的方法 – 不要使用代码编辑器修改

/// 此方法的内容。

/// </summary>

private void InitializeComponent()

{

this.button1 = new System.Windows.Forms.Button();

this.label1 = new System.Windows.Forms.Label();

this.SuspendLayout();

//

// button1

//

this.button1.Location = new System.Drawing.Point(96, 32);

this.button1.Name = "button1";

this.button1.TabIndex = 0;

this.button1.Text = "随机数";

this.button1.Click += new System.EventHandler(this.button1_Click);

//

// label1

//

this.label1.BackColor = System.Drawing.SystemColors.Desktop;

this.label1.ForeColor = System.Drawing.SystemColors.ActiveCaptionText;

this.label1.Location = new System.Drawing.Point(49, 112);

this.label1.Name = "label1";

this.label1.Size = new System.Drawing.Size(168, 80);

this.label1.TabIndex = 1;

this.label1.Text = "label1";

//

// Form1

//

this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);

this.ClientSize = new System.Drawing.Size(292, 273);

this.Controls.AddRange(new System.Windows.Forms.Control[] {

this.label1,

this.button1});

this.Name = "Form1";

this.Text = "Form1";

this.ResumeLayout(false);

}

#endregion

/// <summary>

/// 应用程序的主入口点。

/// </summary>

[STAThread]

static void Main()

{

Application.Run(new Form1());

}

private void button1_Click(object sender, System.EventArgs e)

{

int[] arr=getRandomNum(6,1,20);

int i=0;

string temp="";

while (i<=arr.Length-1){

temp+=arr[i].ToString()+"n";

i++;

}

label1.Text=temp;

}

public int[] getRandomNum(int num,int minValue,int maxValue){

Random ra=new Random(unchecked((int)DateTime.Now.Ticks));

int[] arrNum=new int[num];

int tmp=0;

for (int i=0;i<=num-1;i++){

tmp=ra.Next(minValue,maxValue);

arrNum[i]=getNum(arrNum,tmp,minValue,maxValue,ra);

}

return arrNum;

}

public int getNum(int[] arrNum,int tmp,int minValue,int maxValue,Random ra){

//Random ra=new Random(unchecked((int)DateTime.Now.Ticks));

int n=0;

while (n<=arrNum.Length-1)

{

if (arrNum[n]==tmp)

{

tmp=ra.Next(minValue,maxValue);

getNum(arrNum,tmp,minValue,maxValue,ra);

}

n++;

}

return tmp;

}

}

}

PS:记得以前用C语言写过一个发扑克牌的程序,这次换了,老师要图形界面的不过课上讲的是VC++,我用的C#,估计就代码长度上来说我是最短的了……..C#果然方便。这里记录下取随机数的办法。

【C#高手对Windows窗体上的控件的认识】转

DataGridView 控件DataGridView 控件提供用来显示数据的可自定义表。使用 DataGridView 类,可以自定义单元格、行、列和边框。

注意
DataGridView 控件提供 DataGrid 控件所不具备的许多基本和高级功能。有关更多信息,请参见 Windows 窗体 DataGridView 控件和

DataGrid 控件之间的区别

常用属性:
DefaultCellStyle、ColumnHeadersDefaultCellStyle、CellBorderStyle 和 GridColor

数据绑定和定位
BindingSource 组件
通过提供当前项管理、更改通知和其他服务,来简化将窗体上的控件绑定到数据的过程。

BindingNavigator 控件
提供工具栏式的界面来定位和操作窗体上的数据。

文本编辑
TextBox 控件
显示设计时输入的文本,它可由用户在运行时编辑或以编程方式更改。
RichTextBox 控件
使文本能够以纯文本或 RTF 格式显示。
MaskedTextBox 控件
约束用户输入的格式

信息显示(只读)
Label 控件
显示用户无法直接编辑的文本。

LinkLabel 控件
将文本显示为 Web 样式的链接,并在用户单击该特殊文本时触发事件。该文本通常是到另一个窗口或网站的链接。

StatusStrip 控件
通常在父窗体的底部使用有框架的区域显示有关应用程序的当前状态的信息。

ProgressBar 控件
向用户显示操作的当前进度。

网页显示
WebBrowser 控件
使用户可以在窗体内导航网页。

从列表中选择
CheckedListBox 控件
显示一个可滚动的项列表,每项旁边都有一个复选框。

ComboBox 控件
显示一个下拉式项列表。

DomainUpDown 控件
显示用户可用向上和向下按钮滚动的文本项列表。

ListBox 控件
显示一个文本项和图形项(图标)列表。

ListView 控件
在四个不同视图之一中显示项。这些视图包括纯文本视图、带有小图标的文本视图、带有大图标的文本视图和详细信息视图。

NumericUpDown 控件
显示用户可用向上和向下按钮滚动的数字列表。

TreeView 控件
显示一个节点对象的分层集合,这些节点对象由带有可选复选框或图标的文本组成。

图形显示
PictureBox 控件
在一个框架中显示图形文件(如位图和图标)。

图形存储
ImageList控件
充当图像储存库。ImageList 控件和及其包含的图像可以在不同的应用程序中重用。

值的设置
CheckBox 控件
显示一个复选框和一个文本标签。通常用来设置选项。

CheckedListBox 控件
显示一个可滚动的项列表,每项旁边都有一个复选框。

RadioButton 控件
显示一个可打开或关闭的按钮。

TrackBar 控件
允许用户通过沿标尺移动“滚动块”来设置标尺上的值。

数据的设置
DateTimePicker 控件
显示一个图形日历以允许用户选择日期或时间。

MonthCalendar 控件
显示一个图形日历以允许用户选择日期范围。

对话框
ColorDialog 控件
显示允许用户设置界面元素的颜色的颜色选择器对话框。

FontDialog 控件
显示允许用户设置字体及其属性的对话框。

OpenFileDialog 控件
显示允许用户定位文件和选择文件的对话框。

PrintDialog 控件
显示允许用户选择打印机并设置其属性的对话框。

PrintPreviewDialog件
显示一个对话框,该对话框显示 PrintDocument 组件在打印出来后的外观。

FolderBrowserDialog 控件
显示用来浏览、创建以及最终选择文件夹的对话框

SaveFileDialog 控件
显示允许用户保存文件的对话框。

菜单控件
MenuStrip 控件
创建自定义菜单

注意
MenuStrip 的设计目的是为了取代 MainMenu 控件。

ContextMenuStrip 控件
创建自定义上下文菜单。

注意
ContextMenuStrip 的设计目的是为了取代 ContextMenu 控件。
  
命令
Button 控件
启动、停止或中断进程。

LinkLabel 控件
将文本显示为 Web 样式的链接,并在用户单击该特殊文本时触发事件。该文本通常是到另一个窗口或网站的链接。

NotifyIcon 控件
在表示正在后台运行的应用程序的任务栏的状态通知区域中显示一个图标。

ToolStrip 控件
创建工具栏,这些工具栏可以具有与 Microsoft Windows XP、Microsoft Office 或 Microsoft Internet Explorer 类似的外观,也可以具

有自定义外观,可以有主题,也可以没有主题,并支持溢出和运行时项重新排序。

注意
ToolStrip 控件的设计目的是为了取代 ToolBar 控件。
  
用户帮助
HelpProvider 组件
为控件提供弹出式帮助或联机帮助。

ToolTip 组件
当用户将指针停留在控件上时,提供一个弹出式窗口来显示该控件的用途的简短说明。

将其他控件分组
Panel 控件
将一组控件分组到未标记、可滚动的框架中。

GroupBox 控件
将一组控件(如单选按钮 (RadioButton))分组到带标记、不可滚动的框架中。

TabControl 控件
提供一个选项卡式页面以有效地组织和访问已分组对象。

SplitContainer 控件
提供用可移动拆分条分隔的两个面板。

注意
SplitContainer 控件的设计目的是为了取代 Splitter 控件。

TableLayoutPanel 控件
表示一个面板,它可以在一个由行和列组成的网格中对其内容进行动态布局。

FlowLayoutPanel 控件
表示一个沿水平或垂直方向动态排放其内容的面板。

音频
SoundPlayer 控件
播放 .wav 格式的声音文件。加载声音和播放声音可以异步进行。

C#语法入门

1、大小写区别
2、在C#中的布尔类型为bool,而JAVA为boolean
3、C#有一个不安全模式,在此模式之下可以使用指针
4、有枚举类型
5、代理和索引器
6、运算符重载
7、没有throws关键字

下面开始C#之行。

在开始学习C#之前,先了解下C#语句的特点:

1. C#是区别大小。2. 每一句都以分号结束,不象VB.NET。3. 多个语句通过分号可以写在一行,不过不推荐,因为不清晰。OK,开始了。

先了解下其数据类型:

bool true或false
byte 8位无符号整数
short 16位整数
int 32位整数
long 64位整数
float 32位浮点数
double 64位浮点数
char 16位字符
string 多个16位字符
宽度窄的(即字节数少的)数据类型可以直接赋给较宽的数据类型,并会自动转换为新类型。例:

float a = 9.9f;
int b=4;
a = b;
//上述把一个整型的4转换成了浮点型.同样也可以通过强制类型转换将宽类型的缩成窄类型例: float a = 9.9f;
int b=4;
b = (int)a;
//注意必须把要转换的类型名称放在圆括号内,并放在其前面字符串与数值互换: string a = Convert.ToString(b);
float a = Convert.ToSingle(b);

同样也可以像C语言那样格式化输出:
float a=3.1415926728f;
string b=a.ToString("##.##");

变量与常量声明:

C#中允许一条语句声明同一类型的多个变量
int a,b;
但为了语句清晰推荐将多个声明写成多个语句。
有一点要注意,就是如果在声明数值型变量时没有小数部分,则自动为整数类型,有小数部分的,则自动为double类型,而不是float类型,可通过下面声明,转换为不同类型:

float a=1.2f ; long b=23L ;

对于常量声明,习惯用大写符号来表示常数,如:

const float PI = 3.1415926 ;

对于字符声明,得用单引号括起来,如:

char a = ‘d’ ;

还可以这样赋值:

int a = b = c = 2;

虽然方便,但并不推荐,推荐将其拆成三个语句来写,这样结构也清晰。

(注:C#的变量名长度是任意的,可以由数字和大小写字母混合组成,但第一个必须是字母。

关于C#中的转义字符:

n ————————- 换行
r ————————- 回车
t ————————- 制表符
b ————————- 退格
f ————————- 换页
————————- 空符号
" ————————- 双引号
‘ ————————-单引号
\ ————————-反斜杠

还有一个较特殊的,就是@号,只要语句前加@号,即表示@号后面的包括有转义符的都按不进行转义运算。

————————————————————–

还是先看个例子吧,因为自己也有体会,一味地看语句,很无聊 ^_^

using System;
class sample
{
static void Main(string[] args)
{
string hey="希望如我所愿";
Console.WriteLine("c#快速入门,"+hey);
}
}
很头开始分析:using 语句说明程序中要用到C#的代码库,接着是个类名,可以包括有多个类,类中的东西都必须放在大括号中,整个程序以Main函数开始。按F5可以编译执行。好,完成第一个C#程序。再来看烦燥的语法:

运算符:

算术运算符:

+ ——————— 加
– ——————— 减
* ——————— 乘
/ ——————— 除
% ——————— 求余(即整除后的余数)

逻辑运算符:

& ——————— 按位与
| ——————— 按位或
^ ——————— 按位异或
~ ——————— 取反
>>n ——————- 右移n位
<<n ——————- 左移n位

递增递减运算符:

++ 或 — 或 += 或 -= 或 *= 或/=

如i=1;i++;即等i=i+1; 其它为同样的道理,不说。

比较运算符:
> 或 < 或 == 或 != 或 >= 或<= 一看就明白,也不说。

C#的条件判断:

if(a > 0)
{
a = -1;
}
else
{
Console.WriteLine(a);
}
条件必须放在括号里.

两个条件的判断,注意括号和条件中的等号
if((a = = 0) && (b>0))
{
a = -1;
b = -1;
}
else
{
Console.WriteLine(a + b);
}

switch 用于多个可能的值,如果有一个匹配,则执行相应代码,每句之后必须有break语句中断后面语句的执行。
switch(a)
{
case 1:
Console.WriteLine("1");
break;
case 2:
Console.WriteLine("2");
break;
case 3:
Console.WriteLine("3");
break;
default:
Console.WriteLine("default");
}

while 循环:
——————————————-
a=1;
while (a<20)
{
a=+=a;
}
只要a<20这个条件为真,则循环加a,直到a<20
——————————————
do-while 循环:
——————————————
a=1;
do
{
a=+=a;
}
while(a<20);
——————————————
do while循环与while循环类似,区别在于do-while循环至少执行一次a+=a;

for 循环:
——————————————-
int j=1;
for(int i=0;i<100;i++)
{
j++;
Console.WriteLine("i = "+i+"j = "+j);

}
OK,烦人的基本语法介绍完毕。