c闲人 c闲人
关注数: 0 粉丝数: 399 发帖数: 499 关注贴吧数: 0
职业编程的乐趣与苦恼 职业的乐趣: 编程为什么有趣?作为回报,它的从业者期望得到什么样的快乐? 首先,这种快乐是一种创建事物的纯粹快乐,如同小孩在玩泥巴时感到快乐一样,成年人喜欢创建事物,特别是自己进行设计,我想这种快乐是上帝创造世界的折射,一种呈现在每片独特,崭新的树叶和雪花上的喜悦。 其次,这种快乐来自于开发对他人有用的东西。内心深处,我们期望我们的劳动成果能够被他人使用,并能对他们有所帮助。从这一角度而言,这同小孩用粘土为“爸爸的办公室”捏制铅笔盒没有任何本质的区别。 第三,快乐来自于整个过程体现出的一股强大的魅力--------将相互啮合的零部件组装在一起,看到它们以精妙的方式运行着,并收到了预先所希望的效果。比起弹球游戏机或自动电唱机所具有的迷人魅力,程序化计算机毫不逊色。 第四,这种快乐是持续学习的快乐,它来自于这项工作的非重复特性。人们所面临的问题总有这样那样的不同,因而解决问题的人可以从中学习新的事物:有时是实践上的,有时是理论上的,或者兼而有之。 最后,这种快乐还来自于在易于驾驭的介质上工作。程序员,就像诗人一样,几乎是仅仅工作在单纯的思考中。程序员凭空地运用自己的想象,来建造自己的“城堡”。很少有创造介质如此灵活,如此易于精炼和重建,如此容易实现概念上的设想(不过我们将会看到,容易驾驭的特性也有它自己的问题)。 然而程序毕竟同诗歌不同:它是实实在在的东西;它可以移动和运行,能独立产生可见的输出;它能打印结果,绘制图形,发出声音,移动支架。神话和传说中的魔术在我们的时代已变成了现实。在键盘上键入正确的咒语,屏幕会活动,变幻,显示出前所未有的也不可能存在的事情。 编程的快乐在于它不仅满足了我们内心深处进行创造的渴望,而且还唤醒了每个人内心的情感。职业的苦恼: 然而这个过程并不全都是快乐。我们只有事先了解一些编程固有的苦恼,这样,当它们真的出现时,才能更加坦然地面对。 首先,苦恼来自追求完美(如大家感兴趣我会深入的将解完美主义者和现实主义者的差别)。因为计算机是以这样的方式来变戏法的:如果咒语中的一个字符,一个停顿,没有与正确的形式一致,魔术就不会出现(现实中,很少的人类活动要求完美,所以人类对它本来就不习惯)。实际上,我认为,学习编程最困难的部分,是将做事的方式向追求完美方向调整。 其次,苦恼来自由他人来设定目标,供给资源,提供信息,编程人员很少能控制工作环境和工作目标。用管理的术语来说,个人的权威和他所承担的责任是不相配的。不过,似乎在所有的领域中,对要完成的工作,很少能提供与责任相一致的正式权威。而现实情况中,实际(相对于形式)的权威来自于每次任务的完成。 对于系统编程人员而言,对其他人的依赖是一件非常痛苦的事情。他依靠其他人的程序,而往往这些程序设计得并不合理,实现拙劣,发布不完整(没有源代码或测试用例),或者文档记录很糟。所以,系统编程人员不得不花费时间去研究和修改,而它们在理想情况下本应该是可靠完整的。 下一个苦恼---------------概念性设计是有趣的,但寻找琐碎的bug却只是一项重复性的活动。伴随着创造性活动的,往往是枯燥沉闷的时间和艰苦的劳动。程序编制工作也不例外。 另外,人们发现调试和查错往往是线性收敛的,或者更糟糕的是,具有二次方的复杂度。结果,测试一拖再拖,寻找最后一个错误比第一个错误将花费更多的时间。 最后一个苦恼,有时也是一种无奈---------当投入了大量辛苦的劳动,产品在即将完成或者终于完成的时候,却已现得陈旧过时。可能是同事和竞争对手已在追逐新的,更好的构思;也许替代方案不仅仅是在构思,而且已经在安排了。 现实情况比上面所说的通常要好一些。 当产品开发完成时,更优秀的新产品通常还不能投入使用,而仅仅是大家谈论而已。另外,它同样需要数月的开发时间。事实上,只有实际需要时,才会用到最新的设想,因为所实现的系统已经能满足要求,并体现了回报。 诚然,产品开发所基于的技术在不断地进步。一旦设计被冻结,在概念上就已经开始陈旧了。不过,实际产品需要一步一步按阶段实现。实现落后与否的判断应根据其他已有的系统,而不是未实现的概念。因此,我们所面临的挑战和任务是在实际的进度和有效的资源范围内,寻找解决实际问题的切实可行方案。 这,就是编程,一个许多人痛苦挣扎的焦油坑以及一种乐趣和苦恼共存的创造性活动。对于许多人而言,其中的快乐远远大于苦恼。
不会表达的爱情方式 在一个寒冷的冬夜,在一个电话厅里,有一个男孩正在打电话“你今天好漂亮啊,对了你今天的粉色围巾好配你的衣服。。。。。。。。”电话厅里有一个女孩是一个非常漂亮的女孩她的脖子上同样也,围着粉色的围巾她无意的听到了男孩说的话“今天好冷啊,你记得要多穿点衣服,知道么。。。。。。”说完男孩放下电话,交了钱走了第二天同样的时间,同样的地点,男孩又来了,说着同样的话。女孩心想,他真的很爱他的女朋友啊,我要有一个对我这么好的男朋友多好啊,女孩陷入了沉思。第三天,男孩又准时的来了,只听见他说:“你今天怎么了,不舒服么?怎么脸色那么难看?”而女孩的脸色也同样非常难看(因为昨天下班晚了,穿的又不多,所以今天感冒了)男孩说:“你知道么?我看见你生病,我心理非常难受。。。。女孩又陷入了沉思,电话打完男孩走了,下班的时候女孩发现电话厅里有件羽毛服,女孩这才想起来,这是男孩穿的那件难道他。。。。。第四天男孩没有来连的三天男孩都没有来。。。女孩有点担心了她突然想到。。。。。她赶紧查看男孩所拨打的电话号码xxxxxxxx“嘟嘟嘟您拨打的电话号码是空号,请核对后在拨。。。。”女孩呆住了。又过了两天男孩来了,他熟练的拨打起电话号码xxxxxxxx电话的另一边,有个声音非常好听的女孩说:“怎么好几天都没有见到你?你是不是生病了?”男孩呆了,他看了看收费处里的女孩,发现正是她在说话原来,女孩去把号码改成男孩所拨打的电话。。。。。。后来女孩问男孩:你爱我么?男孩反问:你说我爱自己么?女孩说:当然爱了男孩说:我把你当成我自己的一部分,你说我爱你么?。。。。。。。。。。。。献给“今天狂风,小vc99,和assiss"
初学者天地游戏制作--赛车游戏的完整图 以下是一个用线和矩形绘制的简单赛车#include #include void main(void){ int gdriver=DETECT,gmode; initgraph(&gdriver,&gmode, ""); setbkcolor(7); setwritemode(XOR_PUT); setcolor(BLUE); setlinestyle(SOLID_LINE,0,3); rectangle(280,350,320,390); rectangle(270,340,330,350); rectangle(290,320,310,340); rectangle(270,390,330,400); setcolor(5); line(290,350,290,390); line(300,300,300,320); line(300,350,300,390); line(310,350,310,390); line(285,300,315,300); getch(); closegraph();}接下来我们试着绘制赛道,周围的绿化树木和简单的集装箱车代码如下:#include #include #include #include #include constint u = 26;int i = 2;int j = 3;void road(void){int h;for(h=0;h<4;h++)line(150+h*100,0,150+h*100,472);for(h=0;h<3;h++){setlinestyle(3,0,1);line(200+h*100,0,200+h*100,472);settextstyle(1,HORIZ_DIR,3);}}void tree(void){int w;int poly[14];setcolor(10);setlinestyle(SOLID_LINE,0,3);for (w=-3;w<3;w=w+2){line(85 , -25+u*15+w*157 , 85 , 35+u*15+w*157);line(95 , -25+u*15+w*157 , 95 , 35+u*15+w*157);line(105 , -25+u*15+w*157 , 105 , 35+u*15+w*157);line(115 , -25+u*15+w*157 , 115 , 35+u*15+w*157);line(75 , -9+u*15+w*157 , 75 , 19+u*15+w*157);line(125 , -9+u*15+w*157 , 125 , 19+u*15+w*157);} for (w=-2;w<3;w=w+2) {poly[0] = 530;poly[1] = u*15+w*157;poly[2] =515;poly[3] = 25+u*15+w*157;poly[4] =485;poly[5] =25+u*15+w*157 ;poly[6] =470;poly[7] =u*15+w*157 ;poly[8] =485;poly[9] =-25+u*15+w*157;poly[10] =515;poly[11] =-25+u*15+w*157 ;poly[12] = poly[0];poly[13] = poly[1];drawpoly(7,poly); }}void truck(void){setcolor(2);setlinestyle(SOLID_LINE,0,3);rectangle(170+i*100,j*10,230+i*100,60+j*10);rectangle(160+i*100,70+j*10,240+i*100,260+j*10);line(180+i*100,70+j*10,180+i*100,260+j*10);line(200+i*100,70+j*10,200+i*100,260+j*10);line(220+i*100,70+j*10,220+i*100,260+j*10);}void car(void){setcolor(BLUE);setlinestyle(SOLID_LINE,0,3);rectangle(280,350,320,390);rectangle(270,340,330,350);rectangle(290,320,310,340);rectangle(270,390,330,400);setcolor(5);line(290,350,290,390);line(300,300,300,320);line(300,350,300,390);line(310,350,310,390);line(285,300,315,300);}void main(void){int gdriver = DETECT , gmode,w; initgraph(&gdriver, &gmode, "");setbkcolor(7);setcolor(WHITE);setwritemode(XOR_PUT);road();tree();truck();car();getch();closegraph();}
INT10中断号 视频服务程序00H(设置视频模式)输入: AH=00H AL=视频模式输出: 无 说明:视频服务程序00H用来设置视频配置为表10-l中列出之一。AL寄存器给定所需视频模式。若设置了新视频模式,则清除屏幕。 视频服务程序0lH(设置光标大小)输入: AH=01H CH=光标开始扫描行 CL=光标结束扫描行输出: 无说明:该服务程序用于正文模式。在一个字符单元内由一行或几行组成的光标将在字符显示位置得闪烁。该服务程序定义光标的显示行数。对CGA模式,8扫描行(0~7)用于光标。对EGA模式,使用14行(0~13)。MCGA和VGA适配器,光标可具有16扫描行(0~15)高。缺省设置如下: CGA: CH=6,CL=7 EGA: CH=ll,CL=12 MCGA和VGA: CH量13,CL=1 视频服务程序02H(设置光标位置)输入: AH=02H BH=光标页号 DH=光标行号 DL=光标列号输出: 无说明:该服务器序用于将光标移到指定行和列位置。该服务程序即可用于正文模式也可用于图形模式;然而,仅在正文模式下才显示光标。屏幕左上角为坐标系统的原点。对支持多页的正文和图形模式,则必须指定页号,以保证光标位置正确。视频服务程序03H(读光标位置)输入: AH=03H BH=页号输出: CH=光标开始行 CL=光标结束行 DH=行号 DL=列号说明:该服务程序用于获取光标大小和位置。BH给定了页号。CH中存放光标开始扫描行,而CL中为光标结束扫描行。DH中存放行位置,DL中为列位置。视频服务程序05H(设置活动显示页)输入: AH=05H AL=活动页号输出: 无 说明:该服务程序为正文和图形模式用来设置活动显示页号。AL指定所需页号。对多数正文模式,页号范围为0一7。对具有足够视频缓冲EGA和VGA适配器,可支持多页图形。对所有正文和图形模式,缺省为0页。视频服务程序06H(向上翻滚活动窗口)。输入:AH=06HAL=翻滚行数BH=空白行属性CH左上角行号CL=左上角列号 DH=右下角行号 Dl=右下角列号输出: 无 说明:该服务程序用来创建和翻滚一正文窗口。CH和CL中给出了正文窗口左上角坐标,DH和DL中给出了正文窗口右下角坐标。AL中定义了翻滚的行数。若AL=00H,则正文窗口为空白。当滚动窗口时,底部行是空白行,其属性由BH中指定。视频服务程序07H(向下翻滚窗口)输入:AH=07HAL=翻滚行数BH=空白行属性CH=左上角行号CL=左上角列号DH=右下角行号DL=右下角列号输出: 无说明:该服务程序用来创建和翻滚一正文窗口。CH和CL中给出了正文窗口左上角坐标,DH和DL中给出了正文窗口右下角坐标。AL中定义了翻滚的行数。若AL=00H,则正文窗口为空白。当滚动窗口时,顶部行为空白,其属性由BH中指定。视频服务程序08H(读字符和属性)输入: AH=08H BH=活动页号输出: AH=字符属性 AL=字符码说明:该服务程序用于读取正文或视频模式下,光标所在处字符。在图形模式下,获取的字符同图形模式下使用的字符生成表有关。在正文模式下,将获得字符的ASCII码。字符属性存放在AH中,字符ASCII码存放在AL中。图形模式下,AH中内容无意义.视频服务程序09H(写字符和属性)输入: AH=09H AL=写字符的ASCII码 BL=写字符的属性 BH=活动页号 CX=重复写字符和属性次数输出: 无 说明:该服务程序写一个字符到屏幕当前光标处。AL中指定字符码。正文模式下,BL中指定字符属性。图形模式下,BL指定背景颜色。字符可重复写。CX为写字符及属性的次数。视频服务程序0FH(取当前视频模式)输入: AH=0FH输出: AH=每行字符数 AL=当前显示模式 BH=活动页号说明:该服务程序用来获取当前视频模式,屏幕宽(以字符计),以及活动显示页号;视频显示模式存放在AL中。屏幕宽度(以字符计)存放在AH中,活动页号存放在BH中。
c语言怎么编游戏 纯真童趣的《泡泡堂》,还有武林情仇,笑傲江湖的《剑侠情缘online》.它是e时代常谈的话题,是交互式娱乐的主力军,是一种高层次的综合艺术,更是一个民族的文化,世界观的全新传播方式.作为游戏玩家的我们,是不是想设计一个属于自己的游戏呢?爱玩是人的天性,而C语言是我们计算机专业都要学习的一门基础学科.一般来说,是比较枯燥的.那么,我们能不能通过编一些小游戏来提高它的趣味性呢?这样学习程序设计,就不会是一件艰苦,枯燥的事,它变得象电脑游戏一样充满好奇,富有乐趣.这正是我发贴的目的.1, 总是从Hello,world开始学习编程的第一个程序,一般就是打印一个亲切的词语——"Hello,world!".让我们来看看这个最简单的C程序:#incolude /*把输入输出函数的头文件包含进来*/int main(){printf("Hello, world!");/*在屏幕上输出字符串"Hello,world!"*/return 0;/*退出main函数,并返回0*/}下面我们发现几个值得改进的地方,1,程序的运行结果一闪而过.2,每执行这个程序一次都能看见上次运行留下的字符.3,我们还希望屏幕输出一个笑脸来欢迎我们.(大家不要小看了这个笑脸曾经有人发贴专门问呢)让我们来改进一下这个程序吧!1,在return语句的前面加一句:getch ();,表示按任意键结束.2,在printf语句前用clrscr函数清屏,要使用这个函数和getch函数,需要在程序开头再包含头文件conio.h.3,ASCII码也有许多非常好玩的字符,比如ASCII码值为2的就是一个笑脸,我们可以用printf("%c", 2)来输出一个笑脸.现在我们把Hello,world程序改成一个更好看的Hello,world了.下面让我们开始做游戏吧!2, 心动的开始,一个运动中的笑脸大家小时侯喜欢看动画片吗?哈哈,我猜你们都喜欢吧!下面就让我们来做一个小动画吧.在屏幕上显示一个运动的小笑脸,而且当它到达屏幕的边缘时会自动弹回来.先在程序定义一个在屏幕中运动的点的结构:struct move_point{ int x, y;/*该点的位置,包括x坐标和y坐标*/ int xv, yv;/*该点在x轴,y轴的速度*/};运动的原理是,先擦去物体先前的轨迹,让物体按其速度移动一段距离,再画出该物体.让我们看到以下代码:gotoxy(man.x, man.y);/*把光标移到指定的坐标*/printf(" ");/*输出一个空格,把先前的字符擦去*/然后我们让物体按其速度运动:man.x += man.xv;/*水平方向按x轴的速度运动*/man.y += man.yv;/*垂直方向按y轴的速度运动*/运动后还要判断物体是否出界,如果出了界,就令物体反弹,即让它下一刻的速度等于现在的速度的相反数.最后打印出这个笑脸:gotoxy(man.x, man.y);printf("%c\b", 2); /*输出ASCII码值为2的"笑脸"字符*/怎么样?是不是很有趣呢?不过这个笑脸一直是自己运动,能不能让我们来控制它运动呢?答案是肯定的,让我们继续往下学吧!3, 交互的实现——让我们来控制笑脸运动这个程序的主要功能是接受按键,如果接收的是方向键,就让笑脸顺着方向移动,如果接收的是ESC键就退出程序,其他按键则忽略处理.接受按键我们用以下两条语句:while (bioskey(1) == 0);/*等待按键*/key = bioskey(0);/*把接收的按键的键盘码赋给变量key*/然后用switch语句来判断按键以及执行相关操作,如下:switch (key) /*对变量key的值进行判断*/{case UP: /*如果按的是向上键*/ … break; /*让物体向上运动,并退出switch*/case DOWN: /*如果按的是向下键*/ … break; /*让物体向下运动,并退出switch*/case LEFT: /*向左键*/ … break;;/*向左运动*/case RIGHT: /*向右键*/ … break;/*向右运动*/
学c容易常出的错误 C语言的最大特点是:功能强,使用方便灵活.C编译的程序对语法检查并不象其它高级语言那么严格,这就给编程人员留下"灵活的余地",但还是由于这个灵活给程序的调试带来了许多不便,尤其对初学C语言的人来说,经常会出一些连自己都不知道错在哪里的错误.看着有错的程序,不知该如何改起,本人通过对C的学习,积累了一些C编程时常犯的错误,写给各位学员以供参考. 1.书写标识符时,忽略了大小写字母的区别.main(){ int a=5; printf("%d",A);} 编译程序把a和A认为是两个不同的变量名,而显示出错信息.C认为大写字母和小写字母是两个不同的字符.习惯上,符号常量名用大写,变量名用小写表示,以增加可读性. 2.忽略了变量的类型,进行了不合法的运算.main(){ float a,b; printf("%d",a%b);} %是求余运算,得到a/b的整余数.整型变量a和b可以进行求余运算,而实型变量则不允许进行"求余"运算. 3.将字符常量与字符串常量混淆.char c;c="a"; 在这里就混淆了字符常量与字符串常量,字符常量是由一对单引号括起来的单个字符,字符串常量是一对双引号括起来的字符序列.C规定以"\"作字符串结束标志,它是由系统自动加上的,所以字符串"a"实际上包含两个字符:'a'和'\',而把它赋给一个字符变量是不行的. 4.忽略了"="与"=="的区别. 在许多高级语言中,用"="符号作为关系运算符"等于".如在BASIC程序中可以写if (a=3) then … 但C语言中,"="是赋值运算符,"=="是关系运算符.如:if (a==3) a=b; 前者是进行比较,a是否和3相等,后者表示如果a和3相等,把b值赋给a.由于习惯问题,初学者往往会犯这样的错误. 5.忘记加分号. 分号是C语句中不可缺少的一部分,语句末尾必须有分号.a=1b=2 编译时,编译程序在"a=1"后面没发现分号,就把下一行"b=2"也作为上一行语句的一部分,这就会出现语法错误.改错时,有时在被指出有错的一行中未发现错误,就需要看一下上一行是否漏掉了分号.{ z=x+y; t=z/100; printf("%f",t);} 对于复合语句来说,最后一个语句中最后的分号不能忽略不写(这是和PASCAL不同的). 6.多加分号. 对于一个复合语句,如:{ z=x+y; t=z/100; printf("%f",t);}; 复合语句的花括号后不应再加分号,否则将会画蛇添足. 又如:if (a%3==0);I++; 本是如果3整除a,则I加1.但由于if (a%3==0)后多加了分号,则if语句到此结束,程序将执行I++语句,不论3是否整除a,I都将自动加1. 再如:for (I=0;I<5;I++);{scanf("%d",&x);printf("%d",x);} 本意是先后输入5个数,每输入一个数后再将它输出.由于for()后多加了一个分号,使循环体变为空语句,此时只能输入一个数并输出它.又如:输入变量时忘记加地址运算符"&".int a,b;scanf("%d%d",a,b);这是不合法的.Scanf函数的作用是:按照a,b在内存的地址将a,b的值存进去."&a"指a在内存中的地址. 输入数据的方式与要求不符.①scanf("%d%d",&a,&b);输入时,不能用逗号作两个数据间的分隔符,如下面输入不合法:3,4输入数据时,在两个数据之间以一个或多个空格间隔,也可用回车键,跳格键tab.②scanf("%d,%d",&a,&b);C规定:如果在"格式控制"字符串中除了格式说明以外还有其它字符,则在输入数据时应输入与这些字符相同的字符.下面输入是合法的:3,4此时不用逗号而用空格或其它字符是不对的.3 4 3:4又如:scanf("a=%d,b=%d",&a,&b);输入应如以下形式:a=3,b=4 9.输入字符的格式与要求不一致.在用"%c"格式输入字符时,"空格字符"和"转义字符"都作为
初学c的建议 C语言的初学者应该首先了解C语言关键的核心概念(结构化,三个执行流程,优先级,指针,文件,共用体,函数,作用域,重载等 ),只有弄明白了这些才能在今后的学习中游刃有余的把握C语言的精髓.这几个概念就像逻辑线一样,把整个C语言的体系贯穿起来,给人一种"结构化"的思想体系.下面我简要谈一下这几个核心概念. 1,从宏观角度来看,结构化是C语言的编程思想基础,就是说C语言每一个功能模块就是一个结构,每一个结构实现一个运算或一个算法,这个结构就用大括号表示"{ }",大括号里面的就是算法.尤其注意的是大括号的"}"括在那里,就决定在哪里结束算法功能.这些是初学者经常犯的错误,往往会把算法功能的结束点弄错. 2, 三个执行流程就是顺序流程,条件流程,循环流程.三个流程都是计算机通用的执行流程,是必须了解的流程,每一个算法都基于这三个流程执行顺序. 3, 优先级是对多个函数并列时候优先算法的特权,没有注意优先级的顺序就会把算法出错,这些优先级是必须记住的. 4, 指针是C语言的重要特点,是对运算速度加快运算的重要精髓.它是对数据地址的操作,而不是对数据的操作. 5,文件和共用体是很简单的概念,不用多说了.文件顾名思义和日常概念一样,学过数据软件的都对共用体了解不是太难. 6,从微观角度来看,函数是C语言的驱动机制,所有的语句都由函数驱动来实现的.记住函数命令和相关的配置参数,就能好好的利用C的优势.注意的是,函数不能记错,不然你将得出错的结果.如果能学会调试,那就会更深一层了解函数功能的作用. 7,作用域就像使用期限一样,说明从那里到那里所起的作用,在这之外的就不起作用了(过期的东西就不值钱一样).把握好作用域的使用方式,就能明确函数的关系,不会在巨大的函数名里面迷失方向. 8,重载就是为了方便用户,使用类似于调用的机制给用户减少写入时间的功能.就像查字典一样,你不懂一个字,就要去查字典(相当于调用别的工具来实现你要做的事),而查字典是你已经学会的东西,就可以做这件事了. 学习C语言从大体上了解还不够,要把各种原理在脑海里模拟一遍,实现把计算机C的功能在人脑里运作,就能从宏观上把握C的步骤.最后希望,大家经常看看assiss发过的tc函数大全里面不仅详细的说明了常用的函数功能而且,有很多初学者经常问的一些题,都在里面
c问题解答2:变量和数据存储 C语言的强大功能之一是可以灵活地定义数据的存储方式.C语言从两个方面控制变量的性质:作用域(scope)和生存期(lifetime).作用域是指可以存取变量的代码范围,生存期是指可以存取变量的时间范围. 作用域有三种: 1. extern(外部的) 这是在函数外部定义的变量的缺省存储方式.extern变量的作用域是整个程序. 2.static(静态的) 在函数外部说明为static的变量的作用域为从定义点到该文件尾部;在函数内部说明为static的变量的作用域为从定义点到该局部程序块尾部. 3.auto(自动的) 这是在函数内部说明的变量的缺省存储方式.auto变量的作用域为从定义点到该局部程序块尾部. 变量的生存期也有三种,但它们不象作用域那样有预定义的关键字名称.第一种是extern和static变量的生存期,它从main()函数被调用之前开始,到程序退出时为止.第二种是函数参数和auto变量的生存期,它从函数调用时开始,到函数返回时为止.第三种是动态分配的数据的生存期,它从程序调用malloc()或calloc()为数据分配存储空间时开始,到程序调用free()或程序退出时为止. 2.1 变量存储在内存(memory)中的什么地方? 变量可以存储在内存中的不同地方,这依赖于它们的生存期.在函数外部定义的变量(全局变量或静态外部变量)和在函数内部定义的static变量,其生存期就是程序运行的全过程,这些变量被存储在数据段(datasegment)中.数据段是在内存中为这些变量留出的一段大小固定的空间,它分为两部分,一部分用来存放初始化变量,另一部分用来存放未初始化变量. 在函数内部定义的auto变量(没有用关键字static定义的变量)的生存期从程序开始执行其所在的程序块代码时开始,到程序离开该程序块时为止.作为函数参数的变量只在调用该函数期间存在.这些变量被存储在栈(stack)中.栈是内存中的一段空间,开始很小,以后逐渐自动增大,直到达到某个预定义的界限.在象DOS这样的没有虚拟内存(virtual memory)的系统中,这个界限由系统决定,并且通常非常大,因此程序员不必担心用尽栈空间.关于虚拟内存 的讨论,请参见2.3. 第三种(也是最后一种)内存空间实际上并不存储变量,但是可以用来存储变量所指向的数据.如果把调用malloc()函数的结果赋给一个指针变量,那么这个指针变量将包含一块动态分配的内存的地址,这块内存位于一段名为"堆(heap)"的内存空间中.堆开始时也很小,但当程序员调用malloc()或calloc()等内存分配函数时它就会增大.堆可以和数据段或栈共用一个内存段(memorysegment),也可以有它自己的内存段,这完全取决于编译选项和操作系统. 与栈相似,堆也有一个增长界限,并且决定这个界限的规则与栈相同. 请参见: 1.1 什么是局部程序块(10calblock)? 2.2 变量必须初始化吗? 2.3 什么是页抖动(pagethrashing)? 7.20 什么是栈(stack)? 7.21 什么是堆(heap)7 . 2.2 变量必须初始化吗? 不.使用变量之前应该给变量一个值,一个好的编译程序将帮助你发现那些还没有被给定一个值就被使用的变量.不过,变量不一定需要初始化.在函数外部定义的变量或者在函数内部用static关键字定义的变量(被定义在数据段中的那些变量,见2.1)在没有明确地被程序初始化之前都已被系统初始化为0了.在函数内部或程序块内部定义的不带static关键字的变量都是自动变量,如果你没有明确地初始化这些变量,它们就会具有未定义值.如果你没有初始化一个自动变量,在使用它之前你就必须保证先给它赋值. 调用malloc()函数从堆中分配到的空间也包含未定义的数据,因此在使用它之前必须先进行初始化,但调用calloc()函数分配到的空间在分配时就已经被初始化为0了.
c扫雷小游戏 #include #include #include #define LEFTPRESS 0xff01#define LEFTCLICK 0xff10#define LEFTDRAG 0xff19#define MOUSEMOVE 0xff08int num[10][10];/*范围*/int p[10][10];/*统计雷的数组*/int loop;/*重新来的标志*/int again=0;/*是否重来的变量*/int scorenum;/*一开始统计有几个雷*/char score[3];/*输出一共有几个地雷*/int Keystate;int MouseExist;int MouseButton;int MouseX;int MouseY;/*鼠标光标形状定义*/typedef struct { unsigned int shape[32]; char hotx; char hoty; }SHAPE;/*箭头型*/SHAPE ARROW={ { 0x3fff,0x1fff,0x0fff,0x07ff, 0x03ff,0x01ff,0x00ff,0x007f, 0x003f,0x00ff,0x01ff,0x10ff, 0x30ff,0xf87f,0xf87f,0xfc3f, 0x0000,0x7c00,0x6000,0x7000, 0x7800,0x7c00,0x7e00,0x7f00, 0x7f80,0x7e00,0x7c00,0x4600, 0x0600,0x0300,0x0300,0x0180 }, 0,0, };/*鼠标光标显示*/void MouseOn() { _AX=0x01; geninterrupt(0x33); }/*鼠标光标掩示*/void MouseOff()/*鼠标光标隐藏*/ { _AX=0x02; geninterrupt(0x33); }void MouseSetXY(int x,int y)/*设置当前位置*/ { _CX=x; _DX=y; _AX=0x04; geninterrupt(0x33); }int LeftPress()/*左键按下*/ { _AX=0x03; geninterrupt(0x33); return(_BX&1); }void MouseGetXY()/*得到当前位置*/ { _AX=0x03; geninterrupt(0x33); MouseX=_CX; MouseY=_DX; } begain()/*游戏开始画面*/{ int i,j; loop: cleardevice(); MouseOn(); MouseSetXY(180,30); MouseX=180; MouseY=30; scorenum=0; setfillstyle(SOLID_FILL,7); bar(190,60,390,290); setfillstyle(SOLID_FILL,8); for(i=100;i<300;i+=20)/*画格子*/ for(j=200;j<400;j+=20) bar(j-8,i+8,j+8,i-8); setcolor(7); setfillstyle(SOLID_FILL,YELLOW);/*画脸*/ fillellipse(290,75,10,10); setcolor(YELLOW); setfillstyle(SOLID_FILL,0); fillellipse(285,75,2,2); fillellipse(295,75,2,2); setcolor(0); bar(287,80,293,81); randomize(); for(i=0;i<10;i++) for(j=0;j<10;j++) { num[i][j]=random(7)+10;/*用10代表地雷算了*/ if(num[i][j]==10) scorenum++; } sprintf(score,"%d",scorenum); setcolor(1); settextstyle(0,0,2); outtextxy(210,70,score); scorenum=100-scorenum;/*为了后面判断胜利*/}gameove()/*游戏结束画面*/{ int i,j; setcolor(0); for(i=0;i<10;i++) for(j=0;j<10;j++) if(num[i][j]==10)/*是地雷的就显示出来*/ { setfillstyle(SOLID_FILL,RED); bar(200+j*20-8,100+i*20-8,200+j*20+8,100+i*20+8); setfillstyle(SOLID_FILL,0); fillellipse(200+j*20,100+i*20,7,7); }}int tongji(int i,int j)/*计算有几个雷*/{ int x=0;/*10代表地雷*/ if(i==0&&j==0) { if(num[0][1]==10) x++; if(num[1][0]==10) x++; if(num[1][1]==10) x++; } else if(i==0&&j==9) { if(num[0][8]==10) x++; if(num[1][9]==10) x++; if(num[1][8]==10) x++; } else if(i==9&&j==0) { if(num[8][0]==10) x++; if(num[9][1]==10) x++; if(num[8][1]==10) x++; } else if(i==9&&j==9) { if(num[9][8]==10) x++; if(num[8][9]==10)
用c做的简单的坦克大战小游戏(给初学者点动力) #include #include #include #include #include #define KEY_ESC 0x01#define KEY_SPACE 0x39#define KEY_UP 0x48#define KEY_LEFT 0x4b#define KEY_RIGHT 0x4d#define KEY_DOWN 0x50/*1石头,2砖块,3水,5老家,8玩家,9敌人*/int map[20][20]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,2,2,2,2,0,0,2,2,2,2,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,2,0,0,2,0,1,1,1,1,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,2,2,2,2,2,2,2,0,0,0,0,0,0,0,2,2,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,1, 1,0,1,1,1,1,3,3,3,3,0,0,0,0,0,0,0,2,0,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,3,3,3,0,1, 1,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,3,3,3,1,1,1,1,1,1,1,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,2,2,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1, 1,0,2,2,0,0,0,0,2,2,2,0,0,0,2,2,0,0,0,1, 1,0,0,0,0,0,0,8,2,5,2,0,0,0,0,0,0,0,0,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};struct f{ int x; int y; int direction;};struct play{ int x;/*行坐标*/ int y;/*列坐标*/ int direction;/*方向*/ struct f fire[5];/*5颗子弹*/ int score;/*分数*/}Playone;struct a{ int x; int y; int color; int direction; int directiontwo;/*用来判断走的路是否往返*/ int fireplay;/*是否攻击的变量,随机生成*/ struct f fire;}amy[5];/*敌人的结构体,其实可以添加不同的颜色来表示不同种类的坦克*/char key_state[128],key_pressed[128];void Init();/*图象驱动开始*/void End();/*图象驱动结束*/void DrawMap();/*画地图*/void DrawWater(int x,int y);/*画水*/void DrawBrick(int x,int y);/*画砖*/void DrawTone(int x,int y);/*画石头*/void DrawHome(int x,int y);/*画老家*/void DrawBlack(int x,int y);/*去除内容*/void DrawPlay(int x,int y);/*画玩家*/void DrawAmy(int x,int y,int i);/*画敌人*/void Score();/*输出分数*/void GamePlay();/*玩游戏过程*/void GameOver();/*游戏失败*/void TimeDelay(unsigned long microsec); /*延时函数 传入微秒数*/int GetKey(int ScanCode);/*这里开始都是按键函数*/void interrupt far (*OldInt9Handler)();void far interrupt NewInt9();void InstallKeyboard();void ShutDownKeyboard();void main(void){ Init(); DrawMap(); GamePlay(); End();}void TimeDelay(unsigned long microsec) /*延时函数 传入微秒数*/{ union REGS r; r.h.ah=0x86; r.x.cx=microsec>>16; r.x.dx=microsec; int86(0x15,&r,&r);}void Init()/*图象驱动开始*/{int gd=DETECT,gm; initgraph(&gd,&gm,"d:\\tc\\tc"); cleardevice(); InstallKeyboard();}void End()/*图象驱动结束*/{ ShutDownKeyboard(); closegraph();}void DrawTone(int x,int y)/*画石头*/{setfillstyle(SOLID_FILL,7);bar(100+x*20-9,50+y*20-9,100+x*20+9,50+y*20+9);
在发窗口界面高手来吧 我上次发的窗口界面看来大家意见挺大啊呵呵我那就在发一个里面的功能懒的做了#include "stdio.h"#include "dos.h"#include "stdlib.h"#include "graphics.h"#define WAITING 0xff00#define LEFTPRESS 0xff01#define LEFTCLICK 0xff10#define LEFTDRAG 0xff19#define MOUSEMOVE 0xff08int Keystate;/*这里的开始都与鼠标有关*/int MouseExist;int MouseButton;int MouseX;int MouseY;void *save;/*储存一块地方用的*/struct time now;/*这里开始的变量都是时间有关*/int old,new;char ss[10];struct caidan/*用来检验是否菜单已经打开*/{ int on;/*菜单打开1,否则0*/ char ml[5][20];/*子目录*/}c[4];/*鼠标光标形状定义*/typedef struct { unsigned int shape[32]; char hotx; char hoty; }SHAPE;/*箭头型*/SHAPE ARROW={ { 0x3fff,0x1fff,0x0fff,0x07ff, 0x03ff,0x01ff,0x00ff,0x007f, 0x003f,0x00ff,0x01ff,0x10ff, 0x30ff,0xf87f,0xf87f,0xfc3f, 0x0000,0x7c00,0x6000,0x7000, 0x7800,0x7c00,0x7e00,0x7f00, 0x7f80,0x7e00,0x7c00,0x4600, 0x0600,0x0300,0x0300,0x0180 }, 0,0, };void TimeDelay(unsigned long microsec); /*延时函数 传入微秒数*/void MouseOn();/*鼠标光标显示*/void MouseOff();/*鼠标光标掩示*/void MouseReset();/*鼠标状态值初始化*/void MouseSetXY(int x,int y);/*设置鼠标当前位置*/int LeftPress();/*获取鼠标按下键的信息*/void MouseGetXY();/*获取鼠标当前位置*/void prtime();/*输出时间的函数*/void cdbegain();/*菜单各参数初始状态*/void Init();/*开始画面*/void delcd();/*先把已有的菜单删除了*/void drawcdml(int n);/*输出菜单中的具体内容*/void drawcd(int l,int u,int r,int d,int n);/*画菜单*/void mouseleft();/*左键按下画菜单具体内容*/void Move();/*测试过程*/void main(void){ Init(); Move(); MouseOff(); closegraph();}void TimeDelay(unsigned long microsec) /*延时函数 传入微秒数*/{ union REGS r; r.h.ah=0x86; r.x.cx=microsec>>16; r.x.dx=microsec; int86(0x15,&r,&r);}void MouseOn()/*鼠标光标显示*/ { _AX=0x01; geninterrupt(0x33); }void MouseOff()/*鼠标光标掩示*/ { _AX=0x02; geninterrupt(0x33); }void MouseReset()/*鼠标状态值初始化*/ { _AX=0x00; geninterrupt(0x33); }void MouseSetXY(int x,int y)/*设置鼠标当前位置*/ { _CX=x; _DX=y; _AX=0x04; geninterrupt(0x33); }int LeftPress()/*获取鼠标按下键的信息*/ { _AX=0x03; geninterrupt(0x33); return(_BX&1); }void MouseGetXY()/*获取鼠标当前位置*/ { _AX=0x03; geninterrupt(0x33); MouseX=_CX; MouseY=_DX; }void prtime()/*输出时间的函数*/{ gettime(&now); new=now.ti_sec; if(abs(new-old)>=1) { setfillstyle(SOLID_FILL,7);/*把原来的老时间给去除*/ bar(500,8,620,18); old=new; sprintf(ss,"%02d:%02d:%02d",now.ti_hour,now.ti_min,now.ti_sec); setcolor(0); outtextxy(500,8,ss); }}void cdbegain()/*菜单各参数初始状态*/{int i; for(i=0;i<4;i++)/*所有菜单都已经关闭*/ c[i].on=0; strcpy(c[0].ml[0],"Open");/*各菜单的各选项*/ strcpy(c[0].ml[1],"New"); strcpy(c[0].ml[2],"Save"); strcpy(c[0].ml[3],"Save as"); strcpy(c[0].ml[4],"Exit");
c语言编程序常见问题解答 本章主要描述C语言一些基本要素.当你开始编写C程序时,你可能对C语言的一些基本问题感到困惑,如C语言所使用的约定,关键字和术语等.本章将回答这方面你经常会遇到的一些问题. 例如,switch语句是最常用的一种C语言构件,本章将回答与它有关的三个常见问题.本章还涉及其它几个问题,如循环,分支,运算符的优先级和程序块技术.在阅读本章时,请注意有关switch语句和运算符优先级的一些问题,这些问题常常会使C语言的初学者感到迷惑. 1.1 什么是局部程序块(local block)? 局部程序块是指一对大括号({})之间的一段C语言程序.一个C函数包含一对大括号,这对大括号之间的所有内容都包含在一个局部程序块中.if语句和swich语句也可以包含一对大括号,每对大括号之间的代码也属于一个局部程序块.此外,你完全可以创建你自己的局部程序块,而不使用C函数或基本的C语句.你可以在局部程序块中说明一些变量,这种变量被称为局部变量,它们只能在局部程序块的开始部分说明,并且只在说明它的局部程序块中有效.如果局部变量与局部程序块以外的变量重名,则前者优先于后者.下面是一个使用局部程序块的例子:#include void main(void);void main(){ / * Begin local block for function main() * / iht test_ var = 10; printf("Test variable before the if statement: %d\n", test_var); if (test_var>5) { / * Begin local block for "if" statement * / int test_ var = 5; printf("Test variable within the if statement: %d\n", test_var); { / * Begin independent local block (not tied to any function or keyword) * / int test_var = 0; printf ( "Test variable within the independent local block: %d\n", test_var) } / * End independent local block * / printf ("Test variable after the if statement: %d\n", test_var);}/*End local block for function main () * /上例产生如下输出结果:Test variable before the if statement: 10Test variable within the if statement: 5Test variable within the independent local block:0Test variable after the if statement: 10 注意,在这个例子中,每次test_var被定义时,它都要优先于前面所定义的test_var变量.此外还要注意,当if语句的局部程序块结束时,程序重新进入最初定义的test_var变量的作用范围,此时test_var的值为10. 请参见: 1.2可以把变量保存在局部程序块中吗? 1.2 可以把变量保存在局部程序块中吗? 用局部程序块来保存变量是不常见的,你应该尽量避免这样做,但也有极少数的例外.例如,为了调试程序,你可能要说明一个全局变量的局部实例,以便在相应的函数体内部进行测试.为了使程序的某一部分变得更易读,你也可能要使用局部程序块,例如,在接近变量被使用的地方说明一个变量有时就会使程序变得更易读.然而,编写得较好的程序通常不采用这种方式来说明变量,你应该尽量避免使用局部程序块来保存变量. 请参见: 1.1 什么是局部程序块? 1.3 什么时候用一条switch语句比用多条if语句更好? 如果你有两个以上基于同一个数字(numeric)型变量的条件表达式,那么最好使用一条switch语句.例如,与其使用下述代码:if (x ==l) printf ("x is equal to one. \n");else if (x ==2)
1 下一页