程序高手来

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了程序高手来相关的知识,希望对你有一定的参考价值。

想学一点编程的知识,不晓得用什么软件,从哪个网站学习或者买什么书 新手 麻烦指点一下

如果您想学习编程,却又不知从何入手,那么您不妨看看下面的几种学习方案,可能会给您一些启示吧!
==============================================
方案一 Basic语言 & Visual Basic

优点
(1)Basic 简单易学,很容易上手。
(2)Visual Basic 提供了强大的可视化编程能力,可以让你轻松地做出漂亮的程序。
(3)众多的控件让编程变得象垒积木一样简单。
(4)Visual Basic 的全部汉化让我们这些见了English就头大的人喜不自禁。

缺点
(1)Visual Basic 不是真正的面向对象的开发文具。
(2)Visual Basic 的数据类型太少,而且不支持指针,这使得它的表达能力很有限。
(3)Visual Basic 不是真正的编译型语言,它产生的最终代码不是可执行的,是一种伪代码。它需要一个动态链接库去解释执行,这使得Visual Basic 的编译速度大大变慢。 (Visual Basic 5以及以前的版本产生的代码是伪代码,Visual Basic 6 编译出来的代码是真正的可执行代码。)

综述:方案一适合初涉编程的朋友,它对学习者的要求不高,几乎每个人都可以在一个比较短的时间里学会vB编程,并用VB 做出自己的作品。对于那些把编程当做游戏的朋友来说,VB 是您最佳的选择。

Basic/Visual Basic简介
==============================================
方案二 Pascal语言 & Delphi

优点
(1)Pascal语言结构严谨,可以很好地培养一个人的编程思想。
(2)Delphi是一门真正的面向对象的开发工具,并且是完全的可视化。
(3)Delphi使用了真编译,可以让你的代码编译成为可执行的文件,而且编译速度非常快。
(4)Delphi具有强大的数据库开发能力,可以让你轻松地开发数据库。

缺点
Delphi几乎可以说是完美的,只是Pascal语言的过于严谨让人感觉有点烦。

综述: 方案二比较适合那些具有一定编程基础并且学过Pascal语言的朋友。

Pascal语言简介
Delphi简介
==============================================
方案三 C语言 & Visual C++

优点
(1)C语言灵活性好,效率高,可以接触到软件开发比较底层的东西。
(2)微软的MFC库博大精深,学会它可以让随心所欲地进行编程。
(3)VC是微软制作的产品,与操作系统的结合更加紧密。

缺点
对使用者的要求比较高,既要具备丰富的C语言编程经验,又要具有一定的WINDOWS编程基础,它的过于专业使得一般的编程爱好者学习起来会有不小的困难。

综述: VC是程序员用的东西。如果你是一个永不满足的人,而且可以在编程上投入很大的精力和时间,那么学习VC你一定不会后悔的。

C语言简介
==============================================
方案四 C++语言 & C++ Builder

优点
(1)C++语言的优点全部得以继承。
(2)完全的可视化。
(3)极强的兼容性,支持OWL、VCL和MFC三大类库。
(4)编译速度非常快。

缺点
由于推出的时间太短,关于它的各种资料还不太多。

综述:我认为C++ Builder 是最好的编程工具。它既保持了C++语言编程的优点,又做到了完全的可视化。

C语言简介
==============================================

方案五 SQL语言 & Power Builder

对于一些传统的数据开发人员来说,Foxpro系列也许让他们感到更加熟悉。但是对于初学者来说,PowerBuilder也许是最好的数据库开发工具。各种各样的控件,功能强大的PowerBuilder语言都会帮助你开发出自己的数据库应用程序。
方案五 SQL语言 & Power Builder

对于一些传统的数据开发人员来说,Foxpro系列也许让他们感到更加熟悉。但是对于初学者来说,PowerBuilder也许是最好的数据库开发工具。各种各样的控件,功能强大的PowerBuilder语言都会帮助你开发出自己的数据库应用程序。

[NextPage]
JSP简介

在Sun正式发布JSP(Java Server Pages)之后,这种新的Web应用开发技术很快引起了人们的关注。JSP为创建高度动态的Web应用提供了一个独特的开发环境。按照 Sun 的说法,JSP能够适应市场上包括Apache WebServer 、IIS4.0在内的85%的服务器产品。

JSP与ASP的简单比较

JSP与Microsoft的ASP技术非常相似。两者都提供在html代码中混合某种程序代码、由语言引擎解释执行程序代码的能力。在ASP或JSP环境下,HTML代码主要负责描述信息的显示样式,而程序代码则用来描述处理逻辑。普通的HTML页面只依赖于Web服务器,而ASP和JSP页面需要附加的语言引擎分析和执行程序代码。程序代码的执行结果被重新嵌入到HTML代码中,然后一起发送给浏览器。ASP和JSP都是面向Web服务器的技术,客户端浏览器不需要任何附加的软件支持。

ASP的编程语言是VBScript之类的脚本语言,JSP使用的是Java,这是两者最明显的区别。

此外,ASP与JSP还有一个更为本质的区别:两种语言引擎用完全不同的方式处理页面中嵌入的程序代码。在ASP下,VBScript代码被ASP引擎解释执行;在JSP下,代码被编译成Servlet并由Java虚拟机执行,这种编译操作仅在对JSP页面的第一次请求时发生。

运行环境

执行 JSP 代码需要在服务器上安装 JSP 引擎。此处我们使用的是 Sun 的 JavaServer Web Development Kit ( JSWDK )。为便于学习,这个软件包提供了大量可供修改的示例。安装 JSWDK 之后,只需执行 startserver 命令即可启动服务器。在默认配置下服务器在端口 8080 监听,使用 http://localhost:8080 即可打开缺省页面。

在运行 JSP 示例页面之前,请注意一下安装 JSWDK 的目录,特别是" work "子目录下的内容。执行示例页面时,可以在这里看到 JSP 页面如何被转换成 Java 源文件,然后又被编译成 class 文件(即 Servlet )。 JSWDK 软件包中的示例页面分为两类,它们或者是 JSP 文件,或者是包含一个表单的 HTML 文件,这些表单均由 JSP 代码处理。与 ASP 一样, JSP 中的 Java 代码均在服务器端执行。因此,在浏览器中使用"查看源文件"菜单是无法看到 JSP 源代码的,只能看到结果 HTML 代码。所有示例的源代码均通过一个单独的" examples "页面提供。

Java Servlet是一种开发Web应用的理想构架。 JSP以Servlet技术为基础,又在许多方面作了改进。JSP页面看起来象普通HTML页面,但它允许嵌入执行代码,在这一点上,它和ASP技术非常相似。利用跨平台运行的JavaBean 组件,JSP为分离处理逻辑与显示样式提供了卓越的解决方案。JSP必将成为ASP技术的有力竞争者。

[NextPage]
SQL语言简介

SQL全称是“结构化查询语言(Structured Query Language)”,最早的是IBM的圣约瑟研究实验室为其关系数据库管理系统SYSTEM R开发的一种查询语言,它的前身是SQUARE语言。SQL语言结构简洁,功能强大,简单易学,所以自从IBM公司1981年推出以来,SQL语言,得到了广泛的应用。如今无论是像Oracle ,Sybase,Informix,SQL server这些大型的数据库管理系统,还是像Visual Foxporo,PowerBuilder这些微机上常用的数据库开发系统,都支持SQL语言作为查询语言。

Structured Query Language包含4个部分:

数据查询语言DQL-Data Query Language SELECT
数据操纵语言DQL-Data Manipulation Language INSERT, UPDATE, DELETE
数据定义语言DQL-Data Definition Language CREATE, ALTER, DROP
数据控制语言DQL-Data Control Language COMMIT WORK, ROLLBACK WORK
SQL的历史

在70年代初,E.E.Codd首先提出了关系模型。70年代中期,IBM公司在研制 SYSTEM R关系数据库管理系统中研制了SQL语言,最早的SQL语言(叫SEQUEL2)是在1976 年 11 月的IBM Journal of R&D上公布的。

1979年ORACLE公司首先提供商用的SQL,IBM公司在DB2 和SQL/DS数据库系统中也实现了SQL。

1986年10月,美国ANSI采用SQL作为关系数据库管理系统的标准语言(ANSI X3. 135-1986),后为国际标准化组织(ISO)采纳为国际标准。

1989年,美国ANSI采纳在ANSI X3.135-1989报告中定义的关系数据库管理系统的SQL标准语言,称为ANSI SQL 89, 该标准替代ANSI X3.135-1986版本。该标准为下列组织所采纳:

● 国际标准化组织(ISO),为ISO 9075-1989报告“Database Language SQL With Integrity Enhancement”
● 美国联邦政府,发布在The Federal Information Processing Standard Publication(FIPS PUB)127

目前,所有主要的关系数据库管理系统支持某些形式的SQL语言, 大部分数据库打算遵守ANSI SQL89标准。

SQL的优点

SQL广泛地被采用正说明了它的优点。它使全部用户,包括应用程序员、DBA管理员和终端用户受益匪浅。

(1) 非过程化语言

SQL是一个非过程化的语言,因为它一次处理一个记录,对数据提供自动导航。SQL允许用户在高层的数据结构上工作,而不对单个记录进行操作,可操作记录集。所有SQL 语句接受集合作为输入,返回集合作为输出。SQL的集合特性允许一条SQL语句的结果作为另一条SQL语句的输入。 SQL不要求用户指定对数据的存放方法。 这种特性使用户更易集中精力于要得到的结果。所有SQL语句使用查询优化器,它是RDBMS的一部分,由它决定对指定数据存取的最快速度的手段。查询优化器知道存在什么索引,哪儿使用合适,而用户从不需要知道表是否有索引,表有什么类型的索引。

(2) 统一的语言

SQL可用于所有用户的DB活动模型,包括系统管理员、数据库管理员、 应用程序员、决策支持系统人员及许多其它类型的终端用户。基本的SQL 命令只需很少时间就能学会,最高级的命令在几天内便可掌握。 SQL为许多任务提供了命令,包括:

● 查询数据
● 在表中插入、修改和删除记录
● 建立、修改和删除数据对象
● 控制对数据和数据对象的存取
● 保证数据库一致性和完整性

以前的数据库管理系统为上述各类操作提供单独的语言,而SQL 将全部任务统一在一种语言中。

(3) 是所有关系数据库的公共语言

由于所有主要的关系数据库管理系统都支持SQL语言,用户可将使用SQL的技能从一个RDBMS转到另一个。所有用SQL编写的程序都是可以移植的。

[NextPage]
Java语言简介

一. Java的由来

当1995年SUN推出Java语言之后,全世界的目光都被这个神奇的语言所吸引。那么Java到底有何神奇之处呢?

Java语言其实最是诞生于1991年,起初被称为OAK语言,是SUN公司为一些消费性电子产品而设计的一个通用环境。他们最初的目的只是为了开发一种独立于平台的软件技术,而且在网络出现之前,OAK可以说是默默无闻,甚至差点夭折。但是,网络的出现改变了OAK的命运。

在Java出现以前。Internet上的信息内容都是一些乏味死板的HTML文档。这对于那些迷恋于WEB浏览的人们来说简直不可容忍。他们迫切希望能在WEN中看到一些交互式的内容,开发人员也极希望能够在WEB上创建一类无需考虑软硬件平台就可以执行的应用程序,当然这些程序还要有极大的安全保障。对于用户的这种要求,传统的编程语言显得无能为力,面SUN的工程师敏锐地察觉到了这一点,从1994年起,他们开始将OAK技术应用于WEB上,并且开发出了HotJava的第一个版本。当SUN公司1995年正式以Java这个名字推出的时候,几乎所有的WEB开发人员都想到:噢,这正是我想要的。于是Java成了一颗耀眼的明星,丑小鸭一下了变成了白天鹅。
二. Java的定义

Java是一种简单的,面象对象的,分布式的,解释的,健壮的安全的,结构的中立的,可移植的,性能很优异的多线程的,动态的语言。

Java的开发环境有不同的版本,如sun公司的Java Developers Kit, 简称 JDK。后来微软公司推出了支持Java规范的Microsoft Visual J++ Java开发环境,简称 VJ++。

三. Java的特点

1. 平台无关性

平台无关性是指Java能运行于不同的平台。Java引进虚拟机 原理,并运行于虚拟机,实现不同平台的Java接口之间。使 用Java编写的程序能在世界范围内共享。Java的数据类型与 机器无关,Java虚拟机(Java Virtual Machine)是建立在 硬件和操作系统之上,实现Java二进制代码的解释执行功能, 提供于不同平台的接口的。

2. 安全性

Java的编程类似C++,学习过C++的读者将很快掌握Java的精 髓。Java舍弃了C++的指针对存储器地址的直接操作,程序 运行时,内存由操作系统分配,这样可以避免病毒通过指 针侵入系统。Java对程序提供了安全管理器,防止程序的 非法访问。

3. 面向对象

Java 吸取了C++面向对象的概念,将数据封装于类中,利用类 的优点,实现了程序的简洁性和便于维护性。类的封装性、 继承性等有关对象的特性,使程序代码只需一次编译,然后 通过上述特性反复利用。程序员只需把主要精力用在类和接 口的设计和应用上。Java 提供了众多的一般对象的类,通 过继承即可使用父类的方法。在 Java 中,类的继承关系是单一的非多重的,一个子类 只有一个父类,子类的父类又有一个父类。Java 提供的 Object 类及其子类的继承关系如同一棵倒立的树形,根类 为 Object 类, Object 类功能强大,经常会使用到它及其 它派生的子类。

4. 分布式

Java建立在扩展TCP/IP网络平台上。库函数提供了用HTTP和FTP协议传送和接受信息的方法。这使得程序员使用网络上的文件和使用本机文件一样容易。

5. 键壮性

Java致力于检查程序在编译和运行时的错误。类型检查帮助检查出许多开发早期出现的错误。Java自己操纵内存减少了内存出错的可能性。Java还实现了真数组,避免了覆盖数据的可能。这些功能特征大大提高了开发Java应用程序的周期。Java提供: Null指针检测、 数组边界检测、 异常出口、 Byte code校验。

四. Java与C/C++语言

Java提供了一个功能强大语言的所有功能,但几乎没有一点含混特征。C++安全性不好,但C和C++被大家接受,所以Java设计成C++形式,让大家很容易学习。

Java去掉了C++语言的许多功能,让Java的语言功能很精炼,并增加了一些很有用的功能,如自动收集碎片。

Java去掉了以下几个C和C++功能:
指针运算
结构
typedefs
#define
需要释放内存

这将减少了平常出错的50%。而且,Java很小,整个解释器只需215K的RAM。

面象对象:Java实现了C++的基本面象对象技术并有一些增强,(为了语言简单,删除了一些功能)。Java处理数据方式和用对象接口处理对象数据方式一样。

五. Java与Internet

我们知道,早先的 www 仅可以传送文本和图片,Java的出现实现了互动的页面,是一次伟大的革命。

Java并不是为 Internet,WWW而设计的,它也可以用来编写独立的应用程序。Java 是一种面向对象语言。Java 语言类似于 C++ 语言,所以已熟练掌握 C++语言的编程人员,再学习 Java 语言就容易得多!Java 程序需要编译。实际上有两种 Java 程序:一种 Java 应用程序是一个完整的程序,如 Web 浏览器。一种 Java 小应用程序是运行于 Web 浏览器中的一个程序.

Java程序和它的浏览器HotJava,提供了可让你的浏览器运行程序的方法。你能从你的浏览器里直接播放声音。你还能播放页面里的动画。Java还能告诉你的浏览器怎样处理新的类型文件。当我们能在2400 baud线上传输视频图象时,HotJava将能显示这些视频。
当今Internet的一大发展趋势是电子商务,而Internet的安全问题是必须解决的问题,通常大的部门应设置防火墙,阻止非法侵入。

电子商务是当今的热门话题,然而传统的编程语言难以胜任电子商务系统,电子商务要求程序代码具有基本的要求:安全、可靠、同时要求能 与运行于不同平台的机器的全世界客户开展业务。Java以其强安全性、平台无关性、硬件结构无关性、语言简洁同时面向对象,在网络编程语言中占据无可比拟的优势,成为实现电子商务系统的首选语言。

Java程序被放置在Internet服务器上,当用户访问服务器时,Java程序被下载到本地的用户机上,由浏览器解释运行。

[NextPage]
PowerBuilder简介

PowerBuilder的产生

PowerBuilder是美国著名的数据库应用开发工具生产厂商PowerSoft推出的成功产品,其第一版于1991年6月正式投入市场。它是完全按照客户/服务器体系结构研制设计的,采用面向对象技术,图形化的应用开发环境,是数据库的前端开发工具。

PowerBuilder的特点

它支持应用系统同时访问多种数据库,其中既包括Oracle,Sybase之类的大型数据库,又包括FOXPRO之类支持ODBC接口的小型数据库,PowerBuilder是完全可视化的数据库开发工具,它提供了大量的控件,大大加快了项目的开发速度,也使开发者更容易掌握数据库的开发。

它使用的编程语言叫做工PowerScripr,它也是一种高级的,结构化的编程语言。PowerScript提供了一套完整的嵌入式SQL语句,开发人员可以像使用其它语句一样自由地使用SQL语言,这样就大大增强了程序操纵和访问数据库的能力。可以说PowerBuilder既适合初学者快速学习数据库的开发,又可以让有经验的开发人员开发出功能强大的数据库,是一种适用面非常广的开发工具。

PowerBuilder是一个用来进行客户/服务器开发的完全的可视化开发环境。使用PowerBuilder,你可以用一种可视的直观的方式来创建应用程序的用户界面和数据库接口。这是一个总的概念,实际上是开发人员使用PowerBuilder去开发应用程序,由于所开发的各种应用程序充分利用了图形用户接口(GUI)的优点,所以PowerBuilder被认为是一个图形工具。

在客户/服务器结构的应用中,PowerBuilder具有描述多个数据库连接与检索的能力。特别是PowerBuilder能从大多数流行的RDBMS中存取数据,且不管数据存放在什么地方;另外,各种应用程序又可以独立于RDBMS,因为PowerBuilder可以使用数据库的标准操作语言SQL(结构化查询语言)进行。

使用PowerBuilder,可以很容易地开发出功能强大的图形界面的访问服务器数据库的应用程序,PowerBuilder提供了建立符合工业标准的应用程序(例如订单登记、会计及制造系统)所需的所有工具。

PowerBuilder应用程序由窗口组成,这些窗口包含用户与之交互的控件。开发人员可以使用所有标准空间(如按钮、复选框、下拉式列表框或编辑框)以及PowerBuilder提供的特殊的使应用程序更易于开发和使用的控件。

通常人们把PowerBuilder看成是一种开发工具,实际上它比其他工具强得多,是一种强有力的开发环境。开发人员不仅能用它来开发用户容易使用的各种应用程序还可以通过PowerBuilder修改数据库,利用400多个内部定义函数,可以开发能和其他应用程序进行的各种应用程序。

PowerBuilder正在成为客户/服务器应用开发的标准。相对于其他任何客户/服务器开发环境,PowerBuilder使开发人员的工作更快、成本更低、质量更高、功能更强。

PowerBuilder为应用开发提供了全面综合性的支持,可以分别概括为如下几点:

事件驱动的应用程序
功能强大的编程语言与函数
面向对象的编程
跨平台开发
开放的数据库连结系统

PowerBuilder开发环境

PowerBuilder开发环境由一系列集成的图形画板(Painter)组成,应用开发人员通过简单的鼠标操作即可设计、建立、交互检验和测试客户/服务器应用程序。
[NextPage] \

推荐学java

http://tieba.baidu.com/f?kz=424293485

参考资料:http://tieba.baidu.com/f?kw=%B1%E0%B3%CC

参考技术A 好学的VB
实用的VC
网页学JAVA (script)
FLASH 中加代码叫Action script
看你想学哪个方面了
编程其实很好学
参考技术B 要想学编程,你最好先学c语言
c 语言很重要. 也是基础.考计算机三级,网络工程,等好多方面的证都要用c语言来写程序的.
另外,java c++ flash中的(as) 等等都是基于c 语言.
而且c 语言比较容易学.
学好了c 语言.对了编程来说,你以后想要再学其它的语言.你都是一通百通.
其实都差不多.就是格式上,有点区别.
但是汇编语言比较难学的.
而且作为一般的程序员来说,也用不太上.
但学了很有用.因为对计算机原理.微机原理.接口技术.的理解很有帮助.
参考技术C 先到书店浏览挑选一本BASIC语言、C++程序设计之类的书看看再说 参考技术D c语言是入门的用c++
学java的话用jbuilder或者myeclipse
学.net的话用VB、C#
第5个回答  2008-12-21 什么目的?
如果仅仅是兴趣的话,先看个c语言的书吧。因为c语言现在已经沦为教学语言了,其他很多流行的语言的语法都是以那个为基础的,比如c++,java等

成为C++高手之提高可维护性

思路

当前的Poker工程还能进一步改进:把只与扑克相关的各种声明和定义单独拿出来,放到单独的文件中;把只与玩家相关的东西拿出来,放到单独的文件中,而main函数里只是使用这些定义或声明,于是变成了三个文件:poker.c、player.c,main.c。这样带来什么好处呢?一是要查看或修改poker相关的功能,我们只需打开poker.c。现在由于程序小,感觉不出分开的优势,但当写一个程序要处理几十上百种结构时,如果不分开,面对一个上万行代码的main文件,相信一般人都会头晕。二是当别人要写一个poker游戏时,发现我们的poker.c中已经把操作一副牌的功能都实现了,于是他们只需把poker.c文件复制到自己的工程中用就OK了。通过分散到多个文件中,我们提高了代码的可维护性和可重用性。

下面我们就来研究一下代码中的东西该归各处:

  • Card结构,表示一张牌,肯定要放到poker.c中。
  • 定义一副牌数量的宏CARD_COUNT只与扑克有关,放到poker.c中。
  • 定义poker花色的枚举,与宏CARD_COUNT一样,放到poker.c中。
  • 比较函数,只与扑克相关,放到poker.c中。
  • 比较函数类型定义,跟着比较函数走,放到poker.c中。
  • 构造一副牌的函数initOnePack,放到poker.c中。
  • 洗牌函数shuffle,只操作Card结构,放到poker.c中。
  • 排序函数,只排扑克的序,放到poker.c中。
  • 获取牌名字的函数,只操作扑克,放到poker.c中。
  • 结构Player,肯定放到player.c中。
  • 存放原始一副牌的数组pokers,放到poker.c中。
  • 分牌函数,操做了Player和Card两个结构,放在main.c中可以,
  • 是从人思维角度讲,是人发牌,所以把它放到 player.c中也没问题。这个随意吧,但是我个人的话感觉放到player.c文件中比较好,所以我放到player.c中。
  • 函数声明们跟着函数定义走。

现在是不是可以在main.c里include这两个文件然后就能编译出结果呢?有个问题先说明一下:c文件也是可以被include的,因为include的实质就是将被include的文件的内容复制到include行的位置。但include之后会产生一大堆错误,编译是不会成功的。这些错误的描述大都是说类型或标志符重复定义。这些错误是怎么造成的,后面再说,先说怎么解决。解决方法很简单:将poker.c和player.c从编译中排除,即不再编译poker.c和player.c。它们的内容会被插入main.c中,形成完整的main.c,此时poker.c和player.c不需要编译了。如果编译的话,就会产生重复定义,其原因后面的“编译过程详解”(请期待)一节有解释。所以要把这两个文件从工程中删掉,但不能删除实际的文件哦,只是从工程中删除对它们的引用,如果删掉了实际的文件,include就是找不到文件了。

删除一个文件的引用,在QTCreator中是这样的,如图,不要选中check按钮:

这里写图片描述

现在三个文件是这样的:

poker.c

#include <stdio.h>
//一副牌的数量
#define CARD_COUNT 54
//定义扑克的花色
enum Suit{
    heart,
    spade,
    diamond,
    club,
    joker1,
    joker2
};
//定义扑克
typedef struct Card{
    int value;//牌的点数从1开始
    enum Suit suit;//花色
}Card;
//定义比较函数的类型
typedef int (*COMPARE)(Card* ,Card*);
//原始一副牌所在的数组
Card pokers[CARD_COUNT];
//构造一副牌
void initOnePack(){
    int i=0;
    //前52张
    for(;i<CARD_COUNT-2;i++){
        pokers[i].value=i/4+1;
        pokers[i].suit = i%4;
    }
    //剩下的两张:大王和小王
    //joker1
    pokers[i].value=i/4+1;
    pokers[i].suit=joker1;
    //joker2
    pokers[i+1].value=i/4+2;
    pokers[i+1].suit=joker2;
}
//洗牌,参数是原始的一副牌,返回洗完后的牌
Card** shuffle(const Card* pokers){
    int i;
    //分牌返回牌数组的内存空间
    Card** retPokers = malloc(CARD_COUNT*sizeof(Card*));
    //为了不改动原始的一副牌,另建一个数组,保存原始牌的指针(注意每项不是牌,而是牌的指针)
    Card** pokers2 = malloc(CARD_COUNT*sizeof(Card*));
    for(i=0;i<CARD_COUNT;i++){
        pokers2[i] = &pokers[i];
    }
    //种下随机种子。种子取的是当前时间,
    //所以保证了每次运行程序时,产生的随机数序列不同
    srand(time(NULL));
    //取得随机序号,从pokers2取出序号所指的项,把它依次加到retPokers中。
    for(i=0;i<CARD_COUNT;i++){
        unsigned int index = rand()%CARD_COUNT;
        if(pokers2[index] != NULL){
            retPokers[i] = pokers2[index];
            pokers2[index]=NULL;
        }else{
            i--;
        }
    }
    free(pokers2);
    //返回洗完后的数组
    return retPokers;
}
//排序函数
//cards是要排序的牌,每一项是牌的指针
//cardsCount是牌的数量
//compare_func是比较函数
void sort(Card** cards,int cardsCount,COMPARE compare_func){
    int i;
    for(i=0;i<cardsCount-1;i++){
        int j;
        for(j=0;j<cardsCount-i-1;j++){
            if(compare_func(cards[j],cards[j+1])){
                int tmp=cards[j];
                cards[j]=cards[j+1];
                cards[j+1]=tmp;
            }
        }
    }
}
//比较函数,先比较点数再比较花色
int compare1(Card* a,Card* b){
    if(a->value > b->value){
        return 1;
    }else if(a->value < b->value){
        return 0;
    }else{
        if(a->suit > b->suit)
            return 1;
        else
            return 0;
    }
}
//比较函数,先比较点数再比较花色
int compare2(Card* a,Card* b){
    if(a->value > b->value){
        return 0;
    }else if(a->value < b->value){
        return 1;
    }else{
        if(a->suit > b->suit)
            return 0;
        else
            return 1;
    }
}
//获取牌的名字
//返回牌的名字字符串,调用者用完后需要free()之。
char* getCardName(const Card* card){
    //存放花色名字
    char suitStr[16]={0};//0=='\\0'
    switch (card->suit) {
    case heart:
        strcpy(suitStr,"红桃");
        break;
    case spade:
        strcpy(suitStr,"黑桃");
        break;
    case diamond:
        strcpy(suitStr,"方块");
        break;
    case club:
        strcpy(suitStr,"梅花");
        break;
    }
    //存放点数名字
    char valueStr[16];
    switch(card->value){
    case 1:
        strcpy(valueStr,"A");
        break;
    case 11:
        strcpy(valueStr,"J");
        break;
    case 12:
        strcpy(valueStr,"Q");
        break;
    case 13:
        strcpy(valueStr,"K");
        break;
    case 14:
        strcpy(valueStr,"小王");
        break;
    case 15:
        strcpy(valueStr,"大王");
        break;
    default:
        sprintf(valueStr,"%d",card->value);
        break;
    }
    //动态分配足够的空间
    char * ret = malloc(16);
    //将两个名字合并到ret中
    sprintf(ret,"%s%s",suitStr,valueStr);
    return ret;
}

player.c:

//定义玩家
typedef struct Player{
    char name[64];//玩家的名字
    Card ** cards;//玩家分到的牌。每项是一个指针,指向原始一副牌数组中的一项,这样可以节省空间
    int cardsCount;//玩家分到的牌的数量
}Player;
//发牌
//players是玩家数组
//playerCount是玩家数量
//shuffledCards是洗完后的一副牌
void dispatchCards(Player** players,int playerCount,const Card** shuffledCards){
    //计算每个玩家手中牌的数组的容量,如果每个玩家手中的牌不一样,
    //最多就差一张,加1是为了保证数组分配的空间足够容纳分到的牌。
    int numberCards = CARD_COUNT/playerCount+1;
    //为每个玩家的牌数组分配空间
    int i;
    for(i=0;i<playerCount;i++){
        Card* cards = malloc(numberCards*sizeof(Card*));
        players[i]->cards = cards;
    }
    //轮流向每个玩家发牌
    for(i=0;i<CARD_COUNT;i++){
        //取当前玩家
        Player *curPlayer = players[i%playerCount];
        //向玩家发牌
        curPlayer->cards[curPlayer->cardsCount] = shuffledCards[i];
        //玩家手中实际的牌数增加
        curPlayer->cardsCount++;
    }
}

main.c:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "poker.c"
#include "player.c"
//函数声明们
//char* getCardName(const Card*);
//Card** shuffle(const Card*);
//void dispatchCards(Player** ,int ,const Card** );
//void sort(Card**,int,COMPARE);
//int compare1(Card* ,Card*);
//int compare2(Card* ,Card*);
//void initOnePack();
//原始一副牌所在的数组
Card pokers[CARD_COUNT];
//入口函数
int main(void)
{
    //初始化一副牌
    initOnePack();
    //洗牌,shuffledPokers保存洗后的牌们
    Card** shuffledPokers = shuffle(pokers);
    //构建三个玩家
    Player player1;
    strcpy(player1.name,"隔壁老王");
    player1.cards=NULL;
    player1.cardsCount=0;
    Player player2;
    strcpy(player2.name,"小明");
    player2.cards=NULL;
    player2.cardsCount=0;
    Player player3;
    strcpy(player3.name,"田中龟孙");
    player3.cards=NULL;
    player3.cardsCount=0;
    //把三放到一个数组中,以传入发牌函数中
    Player* players[]={&player1,&player2,&player3};
    //发牌
    dispatchCards(players,sizeof(players)/sizeof(Player*),shuffledPokers);
    //洗后的牌用完了,释放之
    free(shuffledPokers);
    int i;
    //打印出每个玩家手中的牌
    for(i=0;i<sizeof(players)/sizeof(Player*);i++){
        //先打印玩家的名字
        printf("%s\\n",players[i]->name);
        //需要对玩家手中的牌排序
        sort(players[i]->cards,players[i]->cardsCount,compare1);
        //打印玩家手中所有的牌
        int j;
        for(j=0;j<players[i]->cardsCount;j++){
            char * name = getCardName(players[i]->cards[j]);
            printf("%s ",name);
            free(name);
        }
        //每个玩家都需要换一次行
        printf("\\n");
    }
    //释放玩家手中牌的数组
    for(i=0;i<sizeof(players)/sizeof(Player*);i++){
        free(players[i]->cards);
    }
    return 0;
}

上一篇:成为C++高手之实战项目
下一篇:成为C++高手之头文件与条件编译

以上是关于程序高手来的主要内容,如果未能解决你的问题,请参考以下文章

Qt 编程无法编译,高手来!

快。编程高手来指点我一下~~~~

delphi高手来!!! WM_MOUSEMOVE

高手JAVA程序员面试总结

JAVA程序员面试总结,高手整理加强版

那位高手就加工中心的宏程序的一些要领给我点答案