﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-寂静岭-随笔分类-Win32API</title><link>http://www.cppblog.com/yaoming/category/5454.html</link><description>图形学专业空间</description><language>zh-cn</language><lastBuildDate>Wed, 21 May 2008 12:47:46 GMT</lastBuildDate><pubDate>Wed, 21 May 2008 12:47:46 GMT</pubDate><ttl>60</ttl><item><title>硬盘保护卡破解--小哨兵篇</title><link>http://www.cppblog.com/yaoming/archive/2008/01/10/40895.html</link><dc:creator>姚明</dc:creator><author>姚明</author><pubDate>Thu, 10 Jan 2008 06:19:00 GMT</pubDate><guid>http://www.cppblog.com/yaoming/archive/2008/01/10/40895.html</guid><wfw:comment>http://www.cppblog.com/yaoming/comments/40895.html</wfw:comment><comments>http://www.cppblog.com/yaoming/archive/2008/01/10/40895.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/yaoming/comments/commentRss/40895.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yaoming/services/trackbacks/40895.html</trackback:ping><description><![CDATA[<span style="COLOR: #3366ff">六年前研究保护卡的时候，写下的一堆文字，最先被《看雪》论坛收录，至今仍然能在网上搜索到，自己写的东西，被流传开来，真的很有成就感的事情！怀恋一下，呵呵！（<span style="COLOR: #ff0000">当时还是小屁孩，</span><span style="COLOR: #ff0000">文字略显稚嫩</span>）</span><br><br>硬盘保护卡破解--小哨兵篇 &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 作者:Ym &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2002.6.15 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 23:43:50 &nbsp; &nbsp; &nbsp; &nbsp; email:yaomingmail@sina.com &nbsp; &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 现在硬盘保护卡日益盛行,网吧,学校随处可见,本人就遇到几种类型和品牌的,小哨兵是其中技术比较完善的一种.早期在学校机房遇到的看门狗,就存在严重的技术缺陷,只要修改cmos中的硬盘参数即可破解,所以这里我想着重谈谈小哨兵的解法,当然对付看门狗的方法在这里是行不通的,为此我琢磨了很长时间,直到我前几天在网上看到一篇破解硬盘保护卡的文章,给我一个崭新的破解思路,但事实上按原文的方法还是不可破解小哨兵,但离成功仅一步之遥,这篇文章就算是一个补充说明,希望能对大家有点帮助. &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; 首先本人通过阅读那篇文章后,得知保护卡是通过修改中断向量来达到保护硬盘不被真正写入的,其中int13是关键,同时还修改了时钟中断来达到反跟踪,恢复中断向量表的目的.小哨兵拦截了int13的处理程序,将自己的程序挂到上面,这也是无法写进数据的原因所在,知道了这个,你一定会说我们只要把bios的int13的程序地址,在dos下填入中断向量表不就大功告成了,其实不然,小哨兵早以想到了这一点,它会利用早以被它修改过的时钟中断定时检查中断向量表,它一旦发现0000:4c+3处为f0即会修改为别的值.原文章的建议是将时钟中断一一还原,本人觉得太过烦琐,而且出错的可能性大,不可取.经过尝试将原中断处理程序的第一条语句改为0255:0148(此不一定) &nbsp; jmp &nbsp; f000:xxxx即可. &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; 这里还要谈谈xxxx的获取,这一步也是关键,我一开始用debug &nbsp; t跟踪了几次都出现了死机,通过观察每次死机地址都不同,怀疑小哨兵利用时钟中断反跟踪,但每次跟踪都给了一段时间后才死机,所以在进入int13后你要在这段时间内,以最快的速度,t到f000:xxxx &nbsp; <br>&nbsp; 处,当屏幕上t出第一个f000为段的地方时,后面的偏移量即为我们要找的xxxx.记住它,相信这时你已经死机了,重新启动,f8进dos. &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; debug &nbsp; <br>&nbsp; -d &nbsp; 0:4c &nbsp; <br>&nbsp; 0000:004c &nbsp; 48 &nbsp; 01 &nbsp; 55 &nbsp; 02 &nbsp; <br>&nbsp; -a &nbsp; 0255:0148 &nbsp; <br>&nbsp; -0255:0148 &nbsp; jmp &nbsp; f000:xxxx &nbsp; <br>&nbsp; -q &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; c:\&gt;cd &nbsp; windows &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; c:\windows&gt;win &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; OK,现在改个桌面,拷个游戏进去,再重新启动试一下,还在吧,游戏可要藏好哟,祝你愉快! 
<img src ="http://www.cppblog.com/yaoming/aggbug/40895.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yaoming/" target="_blank">姚明</a> 2008-01-10 14:19 <a href="http://www.cppblog.com/yaoming/archive/2008/01/10/40895.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C语言上机实验</title><link>http://www.cppblog.com/yaoming/archive/2007/12/03/37680.html</link><dc:creator>姚明</dc:creator><author>姚明</author><pubDate>Mon, 03 Dec 2007 05:48:00 GMT</pubDate><guid>http://www.cppblog.com/yaoming/archive/2007/12/03/37680.html</guid><wfw:comment>http://www.cppblog.com/yaoming/comments/37680.html</wfw:comment><comments>http://www.cppblog.com/yaoming/archive/2007/12/03/37680.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/yaoming/comments/commentRss/37680.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yaoming/services/trackbacks/37680.html</trackback:ping><description><![CDATA[<p>/*--------------------------------------------------------------------------------------<br>专业：计算机原理与应用<br>姓名：姚明<br>学号：04051<br>日期：2007.12.3<br>说明：C语言上机实验1～6程序设计<br>---------------------------------------------------------------------------------------*/</p>
<p>&nbsp;</p>
<p>//------------------------------------------------------------<br>//&nbsp;&nbsp;<br>//&nbsp;&nbsp;&nbsp;实验2 基本数据类型和运算程序设计<br>//<br>//------------------------------------------------------------</p>
<p>#include &lt;stdio.h&gt;<br>#define PI 3.14159;</p>
<p>void main(void)<br>{<br>&nbsp;int k,p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* for task 1*/<br>&nbsp;int c;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* for task 2*/<br>&nbsp;int x,y,z,w;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* for task 3*/<br>&nbsp;float r, s;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* for task 4*/<br>&nbsp;unsigned short i,m,n,_result;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* for task 5*/<br>&nbsp;char a;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* for task 6*/<br>&nbsp;<br>&nbsp;/*task 1*/<br>&nbsp;/*输入整数ｋ、ｐ,将整数ｋ的高字节作为结果的低字节,<br>&nbsp;整数ｐ的高字节作为结果的高字节,拼成一个新的整数,<br>&nbsp;然后输出;*/</p>
<p>&nbsp;printf("input int k,p:");<br>&nbsp;scanf("%x%x",&amp;k,&amp;p);<br>&nbsp;int newint = (p&amp;0xff00)|(k&amp;0xff00)&gt;&gt;8;<br>&nbsp;printf("new int = %x\n\n",newint);<br>&nbsp;getchar();<br>&nbsp;<br>&nbsp;/*task 2*/<br>&nbsp;/*输入字符ｃ。如果ｃ是大写字母,<br>&nbsp;则将ｃ转换成对应的小写,否则ｃ的值不变,<br>&nbsp;最后输出ｃ;*/</p>
<p>&nbsp;printf("input a character:");<br>&nbsp;c = getchar();<br>&nbsp;c &gt;= 'A' &amp;&amp; c &lt;= 'Z'? putchar(c + 'a'- 'A'): putchar(c);<br>&nbsp;putchar('\n');<br>&nbsp;putchar('\n');<br>&nbsp;<br>&nbsp;/*task 3*/<br>&nbsp;/*输入整数ｘ、ｙ、ｚ,输出其中最小值;*/<br>&nbsp;printf("input x, y, z:");<br>&nbsp;scanf("%d%d%d", &amp;x, &amp;y, &amp;z);<br>&nbsp;w = x &lt; y?x:y;<br>&nbsp;w = w &lt; z?w:z;<br>&nbsp;printf("min = %d\n\n",w);<br>&nbsp;<br>&nbsp;/*task 4*/<br>&nbsp;/*输入圆的半径值ｒ,计算并输出圆的面积<br>&nbsp;ｓ＝&#8719;ｒ２(&#8719;＝3.14159);*/</p>
<p>&nbsp;printf("input the radius r:");<br>&nbsp;scanf("%f", &amp;r);<br>&nbsp;s = r * r * PI;<br>&nbsp;printf("The acreage is %.2f\n\n",s);<br>&nbsp;<br>&nbsp;/*task 5*/<br>&nbsp;/* 输入无符号短整数<br>&nbsp;ｉ,ｍ,ｎ（0 &lt;= ｍ&lt;= 15, 1 &lt;= ｎ&lt;= 16-ｍ）,<br>&nbsp;取出ｉ从第ｍ位开始向左的ｎ位<br>&nbsp;（ｍ从右至左编号为0～15）,<br>&nbsp;并使其向左端（第15位）靠齐;*/</p>
<p>&nbsp;printf("input i, m, n(0 &lt;= m &lt;= 15, 1 &lt;= n &lt;= 16 - m):");<br>&nbsp;scanf("%hu%hu%hu", &amp;i, &amp;m, &amp;n);<br>&nbsp;_result = i &lt;&lt; 16 - m - n &amp; ~0xffff &gt;&gt; m + n;<br>&nbsp;printf("The result is %hu\n\n", _result);<br>&nbsp;getchar();<br>&nbsp;<br>&nbsp;/*task 6*/<br>&nbsp;/*输入一个字符,如果是数字（０～９）<br>&nbsp;则输出该数字代表的整数（８位）的反码,<br>&nbsp;否则原样输出。（反码用十六进制数表示,<br>&nbsp;例如,整数0的反码为0xff,整数1的反码为0xfe,<br>&nbsp;整数9的反码0xf6。）*/</p>
<p>&nbsp;printf("input a charater:");<br>&nbsp;a = getchar();<br>&nbsp;a &gt;= '0' &amp;&amp; a &lt;= '9'?printf("%hx",~a - '0'):putchar(a);<br>&nbsp;printf("\n\n");<br>&nbsp;getchar();<br>}</p>
<p><br>//------------------------------------------------------------<br>//&nbsp;&nbsp;<br>//&nbsp;&nbsp;&nbsp;实验3 C程序流程控制实验<br>//<br>//------------------------------------------------------------<br>#include &lt;stdio.h&gt;<br>void main()<br>{<br>&nbsp;&nbsp;&nbsp; int c;&nbsp;&nbsp;&nbsp; /* 每行的元素值(循环中生成), 初值为1 */<br>&nbsp;&nbsp;&nbsp; int n;&nbsp;&nbsp;&nbsp; /* 显示的行数 */<br>&nbsp;&nbsp;&nbsp; int i, j; /* 循环控制 */<br>&nbsp;<br>&nbsp;&nbsp;&nbsp; /* 输入行数,显示13行以内为佳 */<br>&nbsp;&nbsp;&nbsp; do<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Input n=");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf("%d",&amp;n);&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; } while(n &lt;= 0 || n &gt; 13); <br>&nbsp;&nbsp;&nbsp; for(i = 0; i &lt; n; i++)<br>&nbsp;&nbsp;&nbsp; { </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(j = 0; j &lt; n - i; j++) /* 输入每行前的空格 */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%3c", ' ');</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c=1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 每行开始输出前都将c重置为1 */</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(j = 0; j &lt;= i; j++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%-3d", c);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%-3c", ' ');<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c = c * (i - j) / (j + 1); /* 核心: 递推公式 */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\n");<br>&nbsp;&nbsp;&nbsp; }<br>}</p>
<p>运行结果(VC):<br>=======================================================================<br>Input n=10↙<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp; 1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp; 2&nbsp;&nbsp;&nbsp;&nbsp; 1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp; 1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp;&nbsp; 6&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp;&nbsp; 1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp; 10&nbsp;&nbsp;&nbsp; 10&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp; 1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp; 6&nbsp;&nbsp;&nbsp;&nbsp; 15&nbsp;&nbsp;&nbsp; 20&nbsp;&nbsp;&nbsp; 15&nbsp;&nbsp;&nbsp; 6&nbsp;&nbsp;&nbsp;&nbsp; 1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp; 7&nbsp;&nbsp;&nbsp;&nbsp; 21&nbsp;&nbsp;&nbsp; 35&nbsp;&nbsp;&nbsp; 35&nbsp;&nbsp;&nbsp; 21&nbsp;&nbsp;&nbsp; 7&nbsp;&nbsp;&nbsp;&nbsp; 1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp; 8&nbsp;&nbsp;&nbsp;&nbsp; 28&nbsp;&nbsp;&nbsp; 56&nbsp;&nbsp;&nbsp; 70&nbsp;&nbsp;&nbsp; 56&nbsp;&nbsp;&nbsp; 28&nbsp;&nbsp;&nbsp; 8&nbsp;&nbsp;&nbsp;&nbsp; 1<br>&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp; 9&nbsp;&nbsp;&nbsp;&nbsp; 36&nbsp;&nbsp;&nbsp; 84&nbsp;&nbsp;&nbsp; 126&nbsp;&nbsp; 126&nbsp;&nbsp; 84&nbsp;&nbsp;&nbsp; 36&nbsp;&nbsp;&nbsp; 9&nbsp;&nbsp;&nbsp;&nbsp; 1<br>=======================================================================</p>
<p><br>/*&nbsp;编写一个程序，将用户输入的任意正整数逆转，例如，输入1234，输出4321。*/<br>#include &lt;stdio.h&gt;<br>void main()<br>{<br>&nbsp;&nbsp;&nbsp; int num,_result=0;<br>&nbsp;printf("enter number:");<br>&nbsp;scanf("%d",&amp;num);<br>&nbsp;while(num)<br>&nbsp;{<br>&nbsp;&nbsp;_result=_result*10;<br>&nbsp;&nbsp;_result= num%10+_result;<br>&nbsp;&nbsp;num/=10;<br>&nbsp;}<br>&nbsp;printf("%d\n",_result);<br>}</p>
<p>/*&nbsp;验证歌德巴赫猜想：任何充分大（&gt;=4）的偶数都可以用两个素数之和表示，<br>将4到100中的所有偶数分别用两个素数之和的形式表示。（例如：4=2+2，100=3+97）*/</p>
<p><br>#include &lt;stdio.h&gt;<br>int IsPrime(int n);</p>
<p>void main()<br>{<br>&nbsp;for(int i=4;i&lt;=100;i+=2)<br>&nbsp;{<br>&nbsp;&nbsp;int x=0;</p>
<p>&nbsp;&nbsp;for(x=2;x&lt;i;x++)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;if(IsPrime(x)&amp;&amp;IsPrime(i-x))<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;printf("%d = %d + %d\n",i,x,i-x);<br>&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}<br>&nbsp;}<br>}</p>
<p>int IsPrime(int n) <br>{ <br>&nbsp;int i; <br>&nbsp;if (n == 1 || n == 2 || n == 3 || n == 5) <br>&nbsp;&nbsp;return 1; <br>&nbsp;else if (n % 2) <br>&nbsp;{ <br>&nbsp;&nbsp;for (i = 3; i &lt;= n / 2 + 1; i += 2) <br>&nbsp;&nbsp;{ <br>&nbsp;&nbsp;&nbsp;if (n % i == 0) return 0; <br>&nbsp;&nbsp;} <br>&nbsp;&nbsp;return 1; <br>&nbsp;} <br>&nbsp;else <br>&nbsp;{ <br>&nbsp;&nbsp;return 0; <br>&nbsp;} <br>} </p>
<p><br>/*计算两个数的最大公约数*/</p>
<p>#include &lt;stdio.h&gt;<br>unsigned int gcd(unsigned int,unsigned int);</p>
<p>void main()<br>{<br>&nbsp;int x,y;<br>&nbsp;printf("Enter 2 num:");<br>&nbsp;scanf("%d%d",&amp;x,&amp;y);<br>&nbsp;printf("common divisor:%d\n",gcd(x,y));<br>}</p>
<p>unsigned int gcd(unsigned int x,unsigned int y) // common divisor<br>{ <br>&nbsp;unsigned int i,j,t; <br>&nbsp;if(x==0) <br>&nbsp;&nbsp;return y; <br>&nbsp;if(y==0) <br>&nbsp;&nbsp;return x;<br>&nbsp;for(i=0;0==(x&amp;1);x&gt;&gt;=1,++i);<br>&nbsp;for(j=0;0==(y&amp;1);y&gt;&gt;=1,++j); <br>&nbsp;if(j&lt;i) <br>&nbsp;&nbsp;i=j;<br>&nbsp;for(;;)<br>&nbsp;{ <br>&nbsp;&nbsp;if(x&lt;y)<br>&nbsp;&nbsp;&nbsp;t=y,y=x,x=t;<br>&nbsp;&nbsp;if(0==(x-=y))<br>&nbsp;&nbsp;&nbsp;return y&lt;&lt;i;<br>&nbsp;&nbsp;for(;0==(x&amp;1);x&gt;&gt;=1);<br>&nbsp;}<br>}</p>
<p><br>/*&nbsp;输出所输入的正文。输出时将连续的多个空格字符和横向制表符缩减为一个空格字符，<br>空行删去不输出（空行是指仅由空格字符、横向制表符和行结束符组成的行）*/</p>
<p>#include &lt;stdio.h&gt;<br>int main()<br>{<br>&nbsp;&nbsp; int ch, flag1 =0, flag2 = 0;<br>&nbsp;&nbsp;&nbsp; while((ch=getchar())!=EOF)<br>&nbsp;&nbsp;&nbsp; switch(ch){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case '\n':<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(flag2) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; flag1=flag2=0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; putchar(ch);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case ' ':<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case '\t':<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; flag1=1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(flag1){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; putchar(' ');<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; flag1=0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; putchar(ch);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; flag2=1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return 0;<br>}</p>
<p>//------------------------------------------------------------<br>//&nbsp;&nbsp;<br>//&nbsp;&nbsp;&nbsp;实验4 C函数程序设计<br>//<br>//------------------------------------------------------------</p>
<p>#include &lt;stdio.h&gt;</p>
<p>int factorial(int n);&nbsp;&nbsp;&nbsp;&nbsp; //计算阶乘<br>double reckon(int n);&nbsp;&nbsp;&nbsp;&nbsp; //公式函数</p>
<p>void main()<br>{<br>&nbsp;int num;<br>&nbsp;printf("Enter num:");<br>&nbsp;scanf("%d",&amp;num);<br>&nbsp;printf("out:%f\n",reckon(num));<br>}</p>
<p>int factorial(int n)<br>{<br>&nbsp;long _result; <br>&nbsp;&nbsp;&nbsp; if(n&gt;1)&nbsp; <br>&nbsp;&nbsp;_result=factorial(n-1)*n; <br>&nbsp;&nbsp;&nbsp; else&nbsp; _result=1; <br>&nbsp;&nbsp;&nbsp; return(_result);<br>}</p>
<p>double reckon(int n)<br>{<br>&nbsp;double sum=0;<br>&nbsp;for(int i=1;i&lt;n;i++)<br>&nbsp;{<br>&nbsp;&nbsp;double ret = factorial(i);<br>&nbsp;&nbsp;sum += 1/ret;<br>&nbsp;}<br>&nbsp;return sum;<br>}</p>
<p><br>//------------------------------------------------------------<br>//&nbsp;&nbsp;<br>//&nbsp;&nbsp;&nbsp;实验5 数组程序设计<br>//<br>//------------------------------------------------------------</p>
<p>/* 用rand函数模拟掷双骰子，计算投掷出的两个值的和。在程序中把这两个骰子各掷3600次，<br>用一维数组记录每一种可能值的出现次数，以表格格式打印出结果，判断算出的和是否合理。*/</p>
<p>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br>#include &lt;memory.h&gt;<br>#include &lt;time.h&gt;</p>
<p>void main()<br>{<br>&nbsp;&nbsp; int rands[13];int num1,num2;int i;<br>&nbsp;&nbsp; memset(rands,0,sizeof(int)*13);<br>&nbsp;&nbsp; <br>&nbsp;&nbsp; /* Seed the random-number generator with current time so that<br>&nbsp;&nbsp;&nbsp; * the numbers will be different every time we run.<br>&nbsp;&nbsp;&nbsp; */<br>&nbsp;&nbsp; srand( (unsigned)time( NULL ) );</p>
<p>&nbsp;&nbsp; for(i = 1;&nbsp;&nbsp; i &lt; 3600; i++ )<br>&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; num1 = rand()%6;<br>&nbsp;&nbsp;&nbsp; num2 = rand()%6;<br>&nbsp;&nbsp;&nbsp; num1==0?num1=6:num1;<br>&nbsp;&nbsp;&nbsp; num2==0?num2=6:num2;<br>&nbsp;&nbsp;&nbsp; rands[num1+num2]++;<br>&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp; printf("-------------------------------------------------------------------------------\n");<br>&nbsp;&nbsp; printf("number:\t");<br>&nbsp;&nbsp; for(i=2; i&lt;13; i++)<br>&nbsp;&nbsp; {<br>&nbsp;&nbsp;printf("%d\t",i);<br>&nbsp;&nbsp; }<br>&nbsp;&nbsp; printf("\ntimes:\t");<br>&nbsp;&nbsp; for(i=2; i&lt;13; i++)<br>&nbsp;&nbsp; {<br>&nbsp;&nbsp;printf("%d\t",rands[i]);<br>&nbsp;&nbsp; }<br>&nbsp;&nbsp; printf("\n-------------------------------------------------------------------------------\n");<br>}</p>
<p>/* 定义函数stncat(s,t,n),从串t中至多取 n个字符添加到 s的尾部，在主函数中输入两个字符串和一个整数n，<br>调用函数stncat按要求连接成一个字符串，输出连接后的结果字符串。*/</p>
<p>#include &lt;stdio.h&gt;</p>
<p>char * strncat(char*,const char *,int);</p>
<p>void main()<br>{<br>&nbsp;&nbsp; char string[80] = "This is the initial string!";<br>&nbsp;&nbsp; char suffix[] = " extra text to add to the string...";<br>&nbsp;&nbsp; /* Combine strings with no more than 19 characters of suffix: */<br>&nbsp;&nbsp; printf( "Before: %s\n", string );<br>&nbsp;&nbsp; strncat( string, suffix, 19 );<br>&nbsp;&nbsp; printf( "After:&nbsp; %s\n", string );</p>
<p>}</p>
<p>char * strncat(char *dest,const char *source,int count)</p>
<p>{</p>
<p>&nbsp;&nbsp; char *p = dest;</p>
<p>&nbsp;&nbsp; while (*p) p++;</p>
<p>&nbsp;&nbsp; while (count-- &amp;&amp; (*p++ = *source++));</p>
<p>&nbsp;&nbsp; *p = '\0';</p>
<p>&nbsp;&nbsp; return(dest);<br>}</p>
<p><br>/* 找出二维数组b[3][3]的&#8220;鞍点&#8221;（即行上为最大，列上为最小的元素）<br>及其位置（行、列下标），如果不存在鞍点也输出相应信息。*/</p>
<p>#include&lt;stdio.h&gt;<br>#define N 3<br>#define M 3</p>
<p>void main()<br>{<br>&nbsp;int a[N][M],i,j,k,max=0,xmax,ymax,found=0,flag=1;<br>&nbsp;<br>&nbsp;printf("Input the array(%d numbers):\n",N*M);<br>&nbsp;for( i=0;i&lt;N;i++ )<br>&nbsp;{<br>&nbsp;&nbsp;for( j=0;j&lt;M;j++ )<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;printf("array[%d][%d]=",i,j);<br>&nbsp;&nbsp;&nbsp;scanf("%d",&amp;a[i][j]);<br>&nbsp;&nbsp;}<br>&nbsp;}<br>&nbsp;<br>&nbsp;for( i=0;i&lt;N;i++ )<br>&nbsp;{<br>&nbsp;&nbsp;for( j=0;j&lt;M;j++ )<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;if( max&lt;a[i][j] )<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;max=a[i][j];<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;for( j=0;j&lt;M;j++ )<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;if(max==a[i][j])<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;xmax=j;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;for( k=0;k&lt;N;k++ )<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( max&gt;a[k][xmax] )<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flag=0;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;if( flag==1 )<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ymax = i;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%d is the andian.\n",max);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("pt: x=%d\ty=%d\n",xmax+1,ymax+1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;found++;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}<br>&nbsp;}<br>&nbsp;if( found==0 )<br>&nbsp;&nbsp;printf("andian not found!\n");<br>} </p>
<p><br>/* 八皇后问题，在8*8方格国际象棋盘上放置8个皇后，任意两个皇后不能位于同一行、<br>同一列或同一斜线（正斜线或反斜线）上，输出所有可能的放法。*/<br>#include &lt;stdio.h&gt;<br>#include "math.h"</p>
<p>void paichu(char (*a)[8],int i,int j);</p>
<p>void main()<br>{<br>&nbsp;int i,j,k,n;<br>&nbsp;char a[8][8];<br>&nbsp;for(k=0;k&lt;8;++k)<br>&nbsp;{<br>&nbsp;&nbsp;n=0;&nbsp; <br>&nbsp;&nbsp;for(i=0;i&lt;8;++i)<br>&nbsp;&nbsp;&nbsp;for(j=0;j&lt;8;++j)<br>&nbsp;&nbsp;&nbsp;&nbsp;a[i][j]='*';<br>&nbsp;&nbsp;&nbsp;for(i=0;i&lt;8;++i)<br>&nbsp;&nbsp;&nbsp;&nbsp;for(j=0;j&lt;8;++j)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(i==0 &amp;&amp; j&lt;k) continue;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else if(a[i][j]=='*' &amp;&amp; (fabs(j-k)&lt;i+5)) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;paichu(a,i,j);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a[i][j]='*';<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;for(i=0;i&lt;8;++i)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(j=0;j&lt;8;++j)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(a[i][j]=='*') ++n;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(n!=8) continue;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(i=0;i&lt;8;++i)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(j=0;j&lt;8;++j)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%c",a[i][j]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("\n");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("\n");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getchar(); <br>&nbsp;}<br>}</p>
<p>void paichu(char (*a)[8],int i,int j)<br>{<br>&nbsp;int k,n,i1,i2,j1,j2;<br>&nbsp;if(i&gt;j) n=j;<br>&nbsp;else n=i;<br>&nbsp;for(k=0;k&lt;8;++k)<br>&nbsp;{<br>&nbsp;&nbsp;*(*(a+k)+j)='o';<br>&nbsp;&nbsp;*(*(a+i)+k)='o';<br>&nbsp;}<br>&nbsp;i1=i-n;<br>&nbsp;j1=j-n;<br>&nbsp;while(i1&lt;8 &amp;&amp; j1&lt;8)<br>&nbsp;{<br>&nbsp;&nbsp;*(*(a+i1)+j1)='o';<br>&nbsp;&nbsp;++i1;<br>&nbsp;&nbsp;++j1;<br>&nbsp;}<br>&nbsp;if(i+j&lt;8) i2=0;<br>&nbsp;&nbsp;&nbsp; else i2=i-7+j;<br>&nbsp;j2=j+i-i2;<br>&nbsp;while(i2&lt;8 &amp;&amp; j2&gt;=0)<br>&nbsp;{<br>&nbsp;&nbsp;*(*(a+i2)+j2)='o';<br>&nbsp;&nbsp;++i2;<br>&nbsp;&nbsp;--j2;<br>&nbsp;}<br>}</p>
<p>//------------------------------------------------------------<br>//&nbsp;&nbsp;<br>//&nbsp;&nbsp;&nbsp;实验6 指针程序设计<br>//<br>//------------------------------------------------------------</p>
<p>1．2 运行下面的程序之前，先给出你自己认为的结果，再看看运行结果是否和你想的一样，试着解释程序输出的结果。<br>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br>&nbsp;<br>void f(char s[100])<br>{<br>&nbsp; &nbsp;printf("s size in function f: %d\n", sizeof(s));<br>}</p>
<p>int main()<br>{<br>&nbsp; &nbsp;char s[] = "hello";&nbsp;&nbsp;&nbsp;<br>&nbsp; &nbsp;char *p, *mp;<br>&nbsp; &nbsp;int n;<br>&nbsp; &nbsp;char str[100];<br>&nbsp;&nbsp;<br>&nbsp; &nbsp;printf("s size: %d\n", sizeof(s));<br>&nbsp;<br>&nbsp; &nbsp;p = s;<br>&nbsp; &nbsp;printf("p size: %d\n", sizeof(p));<br>&nbsp;<br>&nbsp; &nbsp;printf("n size: %d\n", sizeof(n));<br>&nbsp;<br>&nbsp; &nbsp;printf("str size: %d\n", sizeof(str));<br>&nbsp;<br>&nbsp; &nbsp;mp = malloc(100);<br>&nbsp; &nbsp;printf("mp size: %d\n", sizeof(mp));<br>&nbsp;<br>&nbsp; &nbsp;f(str);<br>&nbsp;<br>&nbsp; &nbsp;return 0;<br>}</p>
<p>sizeof是是长度运算符, 获得数据类型或是变量的长度，如果是数据类型，<br>则返回数据类型大小，如果是用数组，则返回数组所占空间大小</p>
<p>s size:6&nbsp; s是自动分配的数组,根据所给字符串长度，编译器自动分配空间，(h,e, l, l, o, \0)<br>p size:4&nbsp; p是char*,通常，指针长度和计算机CPU的位数相等，此计算机为32位，即4字节<br>str size:100 返回数组长度，str是用户自定义长度的数组<br>mp size:4 同上 p size<br>s size in function f:4 f函数属于传参操作，即指针传递，没有开辟新空间，函数对s做指针处理。</p>
<p>&nbsp;</p>
<p>2．判断与改错：<br>#include &lt;stdio.h&gt;</p>
<p>void upper(char *s)<br>{<br>&nbsp; while (*s != '\0')<br>&nbsp; {<br>&nbsp;&nbsp;&nbsp; if (*s &gt;= 97 &amp;&amp; *s &lt;= 122)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *s -= 32;<br>&nbsp;&nbsp;&nbsp; s++;<br>&nbsp; }<br>}</p>
<p>void lower(char *s)<br>{<br>&nbsp; while (*s != '\0')<br>&nbsp; {<br>&nbsp;&nbsp;&nbsp; if (*s &gt;= 65 &amp;&amp; *s &lt;= 90)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *s += 32;<br>&nbsp;&nbsp;&nbsp; s++;<br>&nbsp; }<br>}</p>
<p>int main ()<br>{<br>&nbsp; char str[100];<br>&nbsp; char *p, *q;</p>
<p>&nbsp; printf("Input a string with uppercase, lowercase or digits: \n");<br>&nbsp; gets(str);<br>&nbsp; printf("Original:&nbsp; %s\n",str);</p>
<p>&nbsp; p = str;<br>&nbsp; upper(p);<br>&nbsp; printf("Uppercase: %s\n",p);</p>
<p>&nbsp; q = str;<br>&nbsp; lower(q);<br>&nbsp; printf("Lower:&nbsp;&nbsp;&nbsp;&nbsp; %s\n",q);</p>
<p>&nbsp; return 0;<br>}</p>
<p>错误原因:<br>p,q两个指针指向了同一个数据源str,对p,q的操作会直接改变str的内容,<br>printf函数必须在每次数据改变时，分别打印到屏幕，否则只能输出3行同样的str数据。</p>
<p><br>/*编写一个你自己的strlen函数，输入一个字符串，返回它的长度，<br>并在一个完整的程序中验证它。提示：字符串的结尾为 &#8216;\0&#8217;*/</p>
<p>void main ()<br>{<br>&nbsp;&nbsp; char buffer[61] = "How long am I?";<br>&nbsp;&nbsp; int&nbsp; len;<br>&nbsp;&nbsp; len = strlen( buffer );<br>&nbsp;&nbsp; printf( "'%s' is %d characters long\n", buffer, len );<br>}</p>
<p>int strlen(const char * str) {<br>&nbsp;&nbsp;&nbsp;&nbsp; int length = 0 ;<br>&nbsp;&nbsp;&nbsp;&nbsp; while (*str++ )<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++ length;<br>&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp; length;<br>&nbsp;} </p>
<p>/*指针数组最频繁的用处是存放具有不同长度的字符串。<br>试用指针数组对输入的n个长度不等的字符串进行排序，<br>升序。字符串的比较可以用标准库中的strcmp函数。*/<br>#include &lt;stdio.h&gt;</p>
<p>void BubbleSort(char* pt[1024],int count);</p>
<p>void main()<br>{<br>&nbsp;char buffer[1024];<br>&nbsp;char *pBuffer;<br>&nbsp;char *pt[1024];<br>&nbsp;int i, ch;<br>&nbsp;<br>&nbsp;printf( "Do over please input '0'\n" );<br>&nbsp;printf( "Before:\n" );<br>&nbsp;<br>&nbsp;/* Read in single line from "stdin": */<br>&nbsp;for( i = 0; (i &lt; 1024) &amp;&amp;&nbsp; ((ch = getchar()) != EOF) <br>&nbsp;&nbsp;&amp;&amp; (ch != '0'); i++ )<br>&nbsp;&nbsp;buffer[i] = (char)ch;<br>&nbsp;<br>&nbsp;/* Terminate string with null character: */<br>&nbsp;buffer[i] = '\0';<br>&nbsp;<br>&nbsp;int pl=0;<br>&nbsp;pt[pl] = buffer;</p>
<p>&nbsp;pBuffer = buffer;<br>&nbsp;while (*pBuffer++)<br>&nbsp;{<br>&nbsp;&nbsp;if(*pBuffer == '\n')<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;++pl;<br>&nbsp;&nbsp;&nbsp;*pBuffer = '\0';<br>&nbsp;&nbsp;&nbsp;pBuffer++;<br>&nbsp;&nbsp;&nbsp;pt[pl] = pBuffer;<br>&nbsp;&nbsp;}<br>&nbsp;}</p>
<p>&nbsp;BubbleSort(pt,pl);</p>
<p>&nbsp;printf( "After:\n" );<br>&nbsp;for(i=0;i&lt;pl;i++)<br>&nbsp;{<br>&nbsp;&nbsp;printf( "%s\n", pt[i]);<br>&nbsp;}<br>}</p>
<p>void BubbleSort(char* in[1024],int count)<br>{<br>&nbsp;char* temp;<br>&nbsp;for(int y=0;y&lt;count-1;y++)<br>&nbsp;{<br>&nbsp;&nbsp;for(int x=1;x&lt;count-y;x++)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;if((in[x][0])&lt;(in[x-1][0]))<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;temp=in[x-1];<br>&nbsp;&nbsp;&nbsp;&nbsp;in[x-1]=in[x];<br>&nbsp;&nbsp;&nbsp;&nbsp;in[x]=temp;<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}<br>&nbsp;}<br>} </p>
<p><br>/*编写一个带有命令行参数的程序showletter*/</p>
<p>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;</p>
<p>int main(int argc, char* argv[])<br>{</p>
<p>&nbsp;printf("showletter [start] [end]\nstart\t a~z\nend\t0~99\n");</p>
<p>&nbsp;int start=0,end=0;</p>
<p>&nbsp;if(argc == 1)<br>&nbsp;{<br>&nbsp;&nbsp;start = 'a';<br>&nbsp;&nbsp;end&nbsp;&nbsp; = 'z';<br>&nbsp;}<br>&nbsp;else if(argc == 2)<br>&nbsp;{<br>&nbsp;&nbsp;start = (int)argv[1][0];<br>&nbsp;&nbsp;end&nbsp;&nbsp; = 'z';<br>&nbsp;}<br>&nbsp;else if(argc == 3)<br>&nbsp;{<br>&nbsp;&nbsp;start = (int)argv[1][0];<br>&nbsp;&nbsp;end&nbsp;&nbsp; =&nbsp; start+atoi(argv[2]);<br>&nbsp;}<br>&nbsp;else<br>&nbsp;{<br>&nbsp;&nbsp;printf("The command parameter error!\n");<br>&nbsp;}</p>
<p>&nbsp;&nbsp;for(int i=start; i&lt;end; i++)<br>&nbsp;{<br>&nbsp;&nbsp; if(i&gt;'z')<br>&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; printf("\n");<br>&nbsp;&nbsp;&nbsp; end-=26;<br>&nbsp;&nbsp;&nbsp; i='a';<br>&nbsp;&nbsp; }<br>&nbsp;&nbsp; printf("%c",i);<br>&nbsp;}<br>&nbsp;printf("\n");<br>&nbsp;<br>&nbsp;return 0;<br>}</p>
<img src ="http://www.cppblog.com/yaoming/aggbug/37680.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yaoming/" target="_blank">姚明</a> 2007-12-03 13:48 <a href="http://www.cppblog.com/yaoming/archive/2007/12/03/37680.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C/S模式考试程序制作详解</title><link>http://www.cppblog.com/yaoming/archive/2007/10/26/35185.html</link><dc:creator>姚明</dc:creator><author>姚明</author><pubDate>Thu, 25 Oct 2007 16:43:00 GMT</pubDate><guid>http://www.cppblog.com/yaoming/archive/2007/10/26/35185.html</guid><wfw:comment>http://www.cppblog.com/yaoming/comments/35185.html</wfw:comment><comments>http://www.cppblog.com/yaoming/archive/2007/10/26/35185.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/yaoming/comments/commentRss/35185.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yaoming/services/trackbacks/35185.html</trackback:ping><description><![CDATA[<table cellSpacing=0 cellPadding=0 border=0>
    <tbody>
        <tr>
            <td><span id=docinfo>[ <font color=#009900>原创文档</font> 本文适合高级读者 已阅读19451次 ]</span></td>
            <td align=right>&nbsp;</td>
        </tr>
    </tbody>
</table>
<table cellSpacing=0 cellPadding=0 border=0>
    <tbody>
        <tr>
            <td>
            <p align=center><strong>大型作业答辩：C/S考试系统程序制作详解<br></strong><br><br>作者：<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#121;&#97;&#111;&#109;&#105;&#110;&#103;&#109;&#97;&#105;&#108;&#64;&#115;&#105;&#110;&#97;&#46;&#99;&#111;&#109;"><font color=#0000ff><u>姚明</u></font></a></p>
            <p><a href="http://www.vckbase.com/code/downcode.asp?id=2228"><u><font color=#800080>下载源代码</font></u></a><br><br><br><img src="http://www.vckbase.com/document/image/paragraph.gif"> 程序组成结构<br><br>一、服务器程序
            <ol>
                <li>采用了WinSocket32的完成端口模型(I/O completion ports)
                <li>WIN32多线程技术
                <li>ODBC APIS 进行数据库操作 </li>
            </ol>
            二、客户端程序<br><br>用Win32 API函数构造主窗体和界面元素，如图一所示：<br><br><img style="WIDTH: 380px; HEIGHT: 512px" height=512 src="http://www.vckbase.com/document/journal/vckbase27/images/csexamsys1.gif" width=380 border=0><br>图一 程序组织结构<br><br><img src="http://www.vckbase.com/document/image/paragraph.gif"> 服务器程序详解<br><br>一、完全端口模型(I/O completion ports)是迄今为止最为复杂的一种I/O模型，假如一个程序需要管理为数众多的套接字，那么采用这种模型往往可以达到最佳的系统性能，不幸的是该模型只适用与WIN2000和WINNT操作系统，因其设计的复杂性，只有在你的应用程序需要同时管理数百乃至上千个套接字的时候，而且希望随着系统内安装的CPU的数量增多，应用程序的性能也可以线性的提升，才考虑采用&#8220;完成端口模型&#8221;(WEB服务器便是这方面的典型例子)。I/O completion ports是唯一适用于高负载服务器的一个技术，它利用一些线程帮助平衡&#8220;I/O请求&#8221;所引起的负载，这样的构架特别适合应用在SMP系统中产生所谓的&#8220;Scalable&#8221;服务器，(Scalable是指能够籍着增加RAM或磁盘空间，CPU个数而提升应用程序效能的一种系统)。<br><br>二、完全端口模型的具体实现<br>　　为了使用&#8220;完成端口模型&#8221;，我产生了一堆线程在端口上等待，线程数量=CPU个数x2+2，我将每个客户端产生的文件句柄与I/O completion ports端口相关联，建立了这种关系之后，任何客户端发出操作请求，便会导致I/O completion packet被送到&#8220;完成端口&#8221;去，这个步骤是操作系统完成的，为了回应I/O completion packet，我让I/O completion释放一个等待中的线程，如果目前没有线程正在等待，它不会为这个客户端N产生新的线程, 当作用中的线程处理完相应客户端的&#8220;overlapped I/O&#8221;后，将返回I/O completion端口进行等待，客户端N这时才能够被处理，这样就保证了我的Workers线程总是保持一个稳定的数量(CPU个数x2+2)。如图二所示：<br><br><img style="WIDTH: 347px; HEIGHT: 338px" height=338 src="http://www.vckbase.com/document/journal/vckbase27/images/csexamsys2.gif" width=347 border=0><br>图二　完全端口线程模型示意图<br><br>三、数据库的操作实现<br>　　这部分功能主要是通过WinSocket32 API和ODBC API结合使用来实现的,服务端进入监听状态后,为每个客户端提供相应线程处理发过来的指令,通过分析指令,作出以下相应的操作：<br>客户端发送的指令(自定义的):
            <pre>      login: 登陆校验 参数:用户名,科目,密码
            Srecv:ScanTm: 检查服务器时间校对试卷修改试卷状态,抛出计数值
            Srecv:GetSta: 获取试卷状态
            Srecv:GetRlt: 获取上次做答
            Srecv:GetNum: 获得试卷相关信息(总题数,开考时间,结束时间)
            Srecv:GetQue: 获取试卷题目内容.
            Srecv:SaveDt: 保存试卷
            Srecv:ChanST: 修改试卷状态.      </pre>
            四、服务器程序总结<br>　　数据库被单独存放在一个服务器中可以保证数据安全性，程序会将客户端的一切操作显示在窗口中，用户可以通过观察窗口,知道所有客户端的动作。这个程序采用&#8220;完成端口&#8221;模型，可以满足大规模的考试需求。<br><br><img src="http://www.vckbase.com/document/image/paragraph.gif"> 客户端程序详解<br>一、窗口完全采用Win32API函数生成<br>主要包含一下标准控件：
            <pre>      static控件
            Edit控件
            Button控件
            Scroll控件
            窗口元素全部采用计算后的相对坐标定位,所以800X600和1024X768下均能正常显示，      </pre>
            二、试卷的初始化<br>　　考虑到每张试卷的题目数量都不同，为了节约内存空间，所以我在堆中动态生成了一个试卷结构体，通过向服务器程序发送GetNum:指令来获得试卷总题数QuestionNum,然后使用TestPaper=new TestRubric [QuestionNum]
            <pre>/*结构体定义*/
            //试卷每道题的结构
            struct Questions{
            BOOL state;
            char Text [512];
            };
            struct SelectObject{
            BOOL state;
            char Text[256];
            };
            struct TestRubric{
            struct Questions Tile;
            struct SelectObject choose [4];
            };
            </pre>
            由于TextOut函数不支持自动换行,所以换行操作必须由我自己完成.因此我用同样的方法在堆中创建了一个Screen用作屏幕显示的结构体<br>
            <pre>Screen=new  Lines[LINES]
            struct Lines{
            int earmark; //用来存储Button的ID
            BOOL color1;//置颜色标志
            BOOL color2;//置颜色标志
            char Line [512];
            };      </pre>
            LINES=扫描TestPaper中超过屏幕宽度的行数+ QuestionNum*5+QuestionNum*3<br>屏幕宽度=客户区的宽/每个文字的宽度/2*2<br>屏幕高度=客户区的高/每个文字的高度<br>为每一体产生4个互斥的按钮<br>按钮总数= QuestionNum*4<br>在堆中生成hWndList数组保存按钮handle<br>hWndList=new hWnd [QuestionNum*4]<br>按钮ID=题号*10+选项号<br>Screen.earmark=按钮ID<br><br><img src="http://www.vckbase.com/document/journal/vckbase27/images/csexamsys3.gif" border=0><br>图三 <br><br>　　将TestPaper中的内容经过换行处理之后Copy到Screen结构中，并设置好Screen.earmark，Screen.Color1, Screen.Color2。在主窗口消息循环的WM_PAINT消息中将Screen.Line显示在窗口中：
            <pre>      TextOut(hdc,x,cyhar*i,Screen.Line,strlen(Screen.Line));      </pre>
            并检查Screen.earmark中是否为零,不为零就：
            <pre>      ShowWindow(hWndList[Sreen.earmark/10-1] [Screen.earmark%10-1],1);      </pre>
            <p>Screen.Color1, Screen.Color2是否为1,如果为1，则改变颜色显示。<br><br>三、换行中存在的问题<br>行宽=客户区的象素宽/每个文字的宽度/2*2是偶数；<br>汉字占用双字节，字母和标点符号占用单字节；<br>一行文字=字母+标点+汉字 (有可能产生奇数宽)；<br>当一行文字产生一个奇数宽，最后一个字符又是汉字的时,就会把这个汉字切成两份，另一半会在下一行中显示,这就造成了乱码；<br>　　我的解决办法是在换行时增加一个变量HanChar=0，当扫描到字母或是标点时，就HanChar++。一行文字扫描完后需要另起一行时，判断HanChar的奇偶性，当为奇数时行宽往里缩进一个字节，以避免以上情况。<br><br>四、客户端程序总结<br>　　由于客户端界面采用大量计算，显示的内容不会是固定的模式，他会根据题目的长短变化作出相应调整，以达到最好的显示效果。<br>　　当用户登陆验证成功之后，服务器会抛一个时间计数，客户端通过一个定时器，每隔1秒钟将计数减1，并显示倒计时在界面上，直到计数为0，表明考试结束，程序自动保存数据退出。这样做的好处是用户更改客户端的时间，不会影响程序的正常计时。<br>　　客户端每隔10秒钟自动保存一次数据，以防突然死机之类的情况，死机后再次登陆，程序会自动加载你先前保存的作答。但点击&#8220;提交试卷&#8221;后就无法登陆了。<br><br><img src="http://www.vckbase.com/document/image/paragraph.gif"> 对例子程序的说明<br>随付的程序和源码是我大型作业的作品，运行时先运行服务器程序，再运行服务端程序.</p>
            <p><img src="http://www.cppblog.com/images/cppblog_com/yaoming/production1.jpg" border=0>&nbsp;&nbsp;<img src="http://www.cppblog.com/images/cppblog_com/yaoming/sever.jpg" border=0><br><br><br>帐号:姚明<br>密码:1981922<br><br>运行之前请先调整数据库的试卷信息表的开考时间和结束时间。还要确保学生试卷成绩表里面&#8220;姚明&#8221;那一行中试卷状态为1。<br><br><img src="http://www.vckbase.com/document/image/paragraph.gif">　作者信息<br>姚明/Ym<br>邮箱:yaomingmail@sina.com<br>QQ:31547735<br>另外我不会打篮球 :-)<br><br>[代码性质] VC完整应用程序代码<br>[代码作者] 姚明/Ym<br>[文件大小] 162K <br>[更新日期] 2004-1-17 19:43:00 <br>[下载次数] 13112 <a href="http://www.vckbase.com/code/downcode.asp?id=2228" target=_blank><img height=9 alt=下载 src="http://www.vckbase.com/code/image/down.gif" width=61 border=0></a><br><br>（END）<br></p>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.cppblog.com/yaoming/aggbug/35185.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yaoming/" target="_blank">姚明</a> 2007-10-26 00:43 <a href="http://www.cppblog.com/yaoming/archive/2007/10/26/35185.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>