首页> 程序语言

程序语言 存档

一个容易犯错的运算优先级问题

2012年01月12日 分类目录 :程序语言 0

      由于工作需要,在接受过系统Java培训的情况下,现在又开始学习起了C语言。虽说语言有着其共通的地方,但也会有着各式各样的差异,因此,在学习的过程中转变前一种语言的固有思维以适应新语言的规范就成了重中之重,而这也是最难的部分。

      今天在新人C语言研讨会(由于主讲非专业讲师,因此称之为授课有点对不住“教师”这个称号)上讨论到运算结合律的时候,有一个案例是自真、自减的优先级演示。这是一个很坑爹的表达式,但是我们都能较为轻松地得出结果:

#include <iostream.h>
int main(){
     int i = 3;
     cout<<(i++)+(i++)+(i++)<<endl;
}

之后,一位同学&同事提出了更为自虐的式子,即将i++改为++i,顿时全都傻眼。当在VS中编译运行后得到的结果和我们认为的答案完全不一样,即使是作为主讲的一资深编码师也没能弄清如何得出这样一个答案的。

int main(){
     int i = 3;
     cout<<(++i)+(++i)+(++i)<<endl;
}

先说一下这个式子的答案,它将输出的结果是16(不知道你能算出这个答案吗?)

好了,现在开始解构这个坑人的式子:

      由于编译器在解析运算式(从整体来看,忽略内含运算符的优先级别)的时候一般是按照“自左向右”的顺序来的,所以在这个式子中,我们先计算第一个++i,由于++在前表示的是先自增,后使用,所以这里i就自增为4。

      然后我们来看(++i)+(++i)部分,在运算优先级这个问题上,虽然我们无法完全记住所有的运算符优先情况,但是自增优先级高于加法是肯定能记住的,所以此时先跳过加法,计算第二个++i,又由于第一个++i已经将i自增为了4,所以再经过一次自增会使得i变成5。且由于同一块内存区域无法同时用来存储2个常量,所以后来的常量会覆盖前面的常量,于是这部分式子在算术上就变成了5+5=10。

     然后再继续看这个式子,经过前面的运算,我们已经可以把整个式子演变成 10 +(++i)了,此时,同样利用自增优先级高于加法的规则先进行++i的计算,由于前面的自增行为将i自增到了5,所以此次自增之后就得到i=6了。

     最后10 + 6 就是16了。

      经过这番解构,我们会发现似乎它是很基本的运算优先级的问题,每一个学过程序语言(无论是哪种具体的语言),都应该对它很熟悉,甚至很熟练。但是,事实上并非如此,当我们真的面对这样的式子的时候,我们根本无法熟练的使用优先级来做出正确的答案。最近在CSDN上看到很多帖子,都是新人想了解如何速成的方法,包括我也是,在仅知道些皮毛(虽说接受Java培训已有1年了)的情况下,就很想入手写代码,做程序了。但是,事实上,对于做程序来说,我们完全只是三角猫功夫,很容易就能被打回原型。咱有“冰冻三尺非一日之寒”之说,西方有“罗马不是一天建成的”的说法;咱又有“千里之行,始于足下”之说,所以说,当我们连基础都没打扎实的情况下,就想超前上项目,那就是白日做梦。——以上一段为自我批评,给自己的警示之言,也愿各位共勉。

Eclipse项目快速加载多个第三方架包

2011年11月21日 分类目录 :程序语言 1

       之前的日志《让eclipse创建Java下面股时自动加载第三方架包》提到了通过将架包复制到如java\lib、tomcat\lib目录下来实现创建项目时自动加载第三方架包,但是由于这种方法会使得创建的每一个新项目都会加载所有复制到相关目录下的架包,因此只适用于如jdbc、log4j之类使用率较大的架包。而对于其他一些架包,如若希望能够快速添加,则建议通过eclipse的配置实现。

       也许我们会有这样的经历:手头上的几个项目需要用到多个架包,而这些架包又放在不同的文件夹中,当我们为这些项目添加架包时,需要多次进入这些文件夹将架包添加进项目中,而这些工作都是重复的,会消耗不少时间的。因此,如若我们实现创建好一个架包库,那么每次都只需要添加这个库就能够将分属于不同文件夹的架包一次性加入进来了。以优秀的ORM框架Hibrenate为例,当我们从官网上下载好压缩包并解压后,我们可以看到在根目录下有一个hibrenate3.jar,此外还有一个lib文件夹,该文件夹内又有4个子文件夹,内有各类必须使用的和可选用的架包,当创建Hibrenate项目时,就需要将不同文件夹中的架包逐个添加进来。

       幸好,eclipse的配置中有用户库(user library),可以让我们创建不同的架包集合,以提升加包效率。

user library配置过程

1.点击菜单栏Window->Preferences进入配置界面。

2.依次展开java->build path->user library,在右侧配置界面中点New…

3.在弹出的交互窗口中填入自定义的库名,此处以hibernate3为例,然后点确定。(复选框建议不要选中)

4.现在我们就可以看到列表中出现了刚刚添加的库,选中该库,然后点Add JARs…

5.在弹出的文件选择框中将各相关架包加进来。

PS:需要将多个文件夹中的架包添加进来则重复4、5两步。

user library的使用

        当我们创建好库之后,就可以方便的在项目中添加架包了。这里我们创建了一个名为Test的Java项目以作示例:

1.在package explorer界面中右键该项目,在弹出菜单中展开build path菜单项,点击Add library开始添加架包库。

2.此时会弹出一个对话框,可以选择不同类型的架包库,由于我们之前创建的是user library,因此这里选择user library

3.现在会弹出一个对话框里面有所有我们创建的user library,选中需要使用的架包集合,然后点Finish。

4.这样一来,相关的架包就都被加入到该项目的构建路径中去了。

总结

        这个方法可以极大简化我们的工作,但是也有一点缺陷,由于通过这个方法添加的架包是直接进入构建路径,因此当我们把项目导出的时候,相关架包并不会一起导出来,也就是说,当我们在其他电脑上打开该项目的时候,我们必须重新配置一下user library。

, ,

让eclipse创建java项目时自动加载第三方架包

2011年11月05日 分类目录 :程序语言 1

      在开发java项目时,总有那么一些第三方类是需要经常使用的,如dom4j.jar、log4j.jar、数据库连接类等。通常,我们需要在eclipse里新建好项目之后,再手动将这些需要用到的包加入到项目中。对于开发产品的人来说,因为不需要频繁新建项目,即使是手动加入也就一次性的事情;但是对于学习者来说,由于要频繁创建新的练习项目,这么一来,就需要多次加包了,有时更会忘记把包加入到构建路径中。那么,是否能够有一个机制,让我们新建项目时,可以自动加入这些包呢? 

      在新建项目时,我们会在项目资源列表中看到一堆jar包,这些都是javaSE自带的包,如果看过jdk文件夹的话就会发现这些包都放在%java_home%/lib中;而当我们创建java web项目时,又会有一些javaEE的jar包,而它们则通常位于使用的web容器的lib目录下(如果tomcat/lib)。既然这样,也就是说,如果我们把常用的包放入这些目录,那么当我们新建项目时,也就会一并加入这些包了。比如说,我们可以把数据库连接的jar包放入tomcat/lib中,那么在新建web项目时就会加入,而java项目不会。 

       对于使用windows作为开发环境的开发者来说,只要直接将jar包放入相应的文件夹就可以了,没有任何技术含量。而用linux作为开发环境的开发者就相对麻烦了点,但是,作为一个开发者来说,如果这些小事都不愿意去做,那么又如何能够成功呢? 

      当我们观察jdk或tomcat的文件夹时,我们会发现lib目录下的那些jar包其实只是一个链接,Linux有着一套非常规范的文件归类体系。因此,通过软件源获取到的所有jar包都会统一放置在/usr/share/java/中,然后在需要用到它的地方安置链接。清楚了这点,我们就可以来进行操作了。 

      照例打开终端(Linux中很多操作都得用它来完成,还是趁早习惯地好),输入相关命令:

sudo cp your-jar-file-path /usr/share/java/


sudo ln -s /usr/share/java/your-jar-file /usr/tomcat*/lib/your-jar-file


      至此,基本的设置就完成了,接下来创建的新项目中不出意外就会自动加入我们设置了的第三方jar包了。 
      在不清楚其中的执行流程的情况下,我们可能无从下手,但是一旦找到了突破口,那就将势如破竹,一帆风顺。


>

, , ,

Ubuntu中安装配置tomcat

2011年10月19日 分类目录 :linux&软件技术| 程序语言 0

正如上一篇日志所说,我又开始使用Ubuntu了,照例仍需将Java编程环境搭建出来,而tomcat则是不可或缺的一环。因此,这篇日志就来说说tomcat的安装配置。

在Ubuntu中,tomcat有两套安装方案:其一是从tomcat官方网站下载压缩包,解压后直接配置使用;其二是从软件源中安装使用。两套方案的效果基本相同,唯一不同的是,第一套方案得到的tomcat包含在同一个文件目录下,而第二套方案得到的tomcat则将文件分别放置在了两个不同的目录中(这是由于Linux的文件结构习惯所致)。至于使用哪一套方案就看个人喜好了,不过对于使用Eclipse作为开发环境的(Linux新手)开发者来说,第一套方案由于在配置过程中与Windows中基本无异,因此相对更简单、适合。由于我比较喜欢折腾同时对Linux的文件结构思想比较认同,因此选择了第二套方案。

安装tomcat

打开终端,输入命令:sudo apt-get install tomcat6(6较稳定,如果喜欢尝鲜,也可以安装tomcat7,我就是安装的7)

然后在询问是否下载安装时根据提示敲击“Y”即可,稍等一会就能够完成安装了。

 

如果嫌用终端麻烦,则从官网下载压缩包解压即可。

配置tomcat

在配置前需要注意,是否已经配置好java编译环境,如果不确定是否已经配置好,可以在终端输入java -version来查看,如果提示类似找不到命令java之类的提示的话,则说明系统中并无安装任何jdk,这时可以选择安装openJDK或oracle官方JDK,他们的效果其实基本一样,同样全看个人喜好。关于Java的配置,这里就不再累赘,可以参看旧文《配置Java编译环境》。在我的实际操作中发现,似乎从源中安装的openJDK无需配置系统环境即可使用?不过为了确保安全,仍然配置了一下,反正不会出错。

言归正传,tomcat主要有3个需要配置的地方:它们分别是server.xml、tomcat-users.xml、以及系统环境。

server.xml位于/var/lib/tomcat7/conf目录下,这个文件主要是修改tomcat服务器配置的,我们需要修改的是catalina的端口号,由于默认使用的是8080,而它是大路货,很有可能与其他应用冲突,因此需要修改为一个罕见的端口以避免可能出现的冲突,我这里照习惯修改为了8088。

tomcat-users.xml同样位于该目录下,这个文件主要是创建tomcat的用户配置。在<tomcat-users>和</tomcat-users>之间输入两句语句:<role rolename=”admin”/>、<user username=”用户名” password=”密码” roles=”admin,manager”/>。其中第二句语句在tomcat7环境下需要改为:<user username=”admin” password=”CWQ@wangqige” roles=”manager-gui,admin,manager-script” />。

然后则是系统环境的配置,在终端中使用命令sudo gedit /etc/environment,在其中写入以下配置项:

 

CATALINA_HOME=”/usr/share/tomcat6″

CATALINA_BASE=”/var/lib/tomcat6″

 

 

至此,基本的配置就完成了,此时可以尝试在终端中使用命令:sudo /etc/init.d/tomcat6 start启动tomcat看看(使用第一套方案的则先cd /path/tomcat/bin进入该目录,其中path是放置tomcat的目录,tomcat则是解压后获得的tomcat目录名,然后使用命令./startup.sh来启动服务)。当看到如下文字则说明tomcat已经启动成功,Starting Tomcat servlet engine tomcat7                                [ OK ] 。然后可以在浏览器中输入地址http://localhost:8088(端口号请根据自己的配置修改),如果看到该页面则说明已经大功告成:

注:此图为tomcat7环境下所截,tomcat6下的效果是否一致不得而知了。

 

然后可以进一步访问http://localhost:8088/manager/html来登陆访问tomcat控制面板。

配置eclipse的tomcat服务器

在开始配置eclipse的tomcat服务器之前,需要注意的是,通过源安装的用户即使配置好也无法在eclipse中启用tomcat,正如前面所说,源中安装的tomcat会被分别放置在两个文件夹中,因此无论是在eclipse中设置的哪个路径,都是错误的。因此,在配置前,我们还需要多做一个步骤,在终端中依次输入以下命令,将两个文件夹建立起联系:

sudo ln -s /var/lib/tomcat6/conf /usr/share/tomcat6/conf 

sudo ln -s /etc/tomcat6/policy.d/03catalina.policy /usr/share/tomcat6/conf/catalina.policy

sudo ln -s /var/log/tomcat6 /usr/share/tomcat6/log

sudo chmod -R 777 /usr/share/tomcat6/conf

这样就能解决问题了,此方案参考自http://wiki.ubuntu.org.cn/Tomcat。

之后就是eclipse里的配置了,window-preferences-server-runtime environment然后照图来就行了:

点击add开始添加服务器

至此,tomcat就算是全部设置完成了,现在就可以在eclipse里写代码然后在tomcat中运行调试了。

, , ,

简单的秒表应用

2011年05月24日 分类目录 :程序语言 0

这次写的是一个秒表应用,它实现的功能是在应用启动时记录一次当前时间,结束时记录一次当前时间,然后计算出所过时间并毫秒数。

StopWatch

private m_iMinute:int //记录分钟数
private m_iSecond:double //记录秒数

startCount():void //开始计时
stopCount():void //结束计时
reset():void //重置分数、秒数值为0
getMinute():int //获取当前分数
getSecond():double //获取当前秒数
toString():void //获取字符串类型的结果
getTotalTime():int //获取毫秒数

     import java.util.Date;
     import java.util.Scanner;

     public class StopWatch{
        private int m_iMinute;
        private double m_iSecond;
        private Date d1;
        private Date d2;

        public void startCount(){
                d1 = new Date();
                m_iMinute = d1.getMinutes();
                m_iSecond = d1.getSeconds();

        }

        public void stopCount(){
                d2 = new Date();
                m_iMinute = (d2.getMinutes() - m_iMinute) ;
                m_iSecond = (d2.getSeconds() - m_iSecond) ;
                getTotalTime();
        }

        public void reset(){
                m_iMinute = 0;
                m_iSecond = 0d;
                System.out.println("分数:"+m_iMinute+"秒数:"+m_iSecond);
        }

        public int getMinute(){

                return m_iMinute;
        }

        public double getSecond(){

                return m_iSecond;
        }

        public int getTotalTime(){
                return (int)(d2.getTime()-d1.getTime());
        }

        public String toString(){
                return "分数:"+m_iMinute+"秒数:"+m_iSecond+"毫秒数:"+getTotalTime();
        }
        public static void main(String[] args){
                StopWatch sw= new StopWatch();
                Scanner input=new Scanner(System.in);
                sw.startCount();
                System.out.print("输入stop结束计时,输入reset归零:");
                String s=input.next();
                if(s.equals("stop")){
                        sw.stopCount();
                        System.out.println(sw.toString());
                }else if(s.equals("reset")){
                        sw.reset();
                }else{
                        System.out.println("请输入正确的指令!");
                }
        }
}

 

效果图如下:

,

用JAVA实现简单的银行柜台机操作

2011年05月12日 分类目录 :程序语言 0

这次做的是一个可以实现显示帐号及余额,并允许进行存取款操作的小程序。这里作出说明,帐号和余额我使用了random类进行随机产生,由于随机产生的int类数据会有一定的概率是负数,因此又增加了个判断,当帐号为负时,重新产生。

import java.util.Scanner;
import java.util.Random;
public class BankService{

        public static void main(String[] args){

                Random rd=new Random();
                Scanner input = new Scanner(System.in);
                System.out.println("Welcome to our bank,here are four service which you can use!");
                System.out.println("1.存款");
                System.out.println("2.取款");
                System.out.println("3.查询余额");
                System.out.println("4.显示帐号");
                System.out.print("请输入数字以选择你要使用的服务:");
                int number = input.nextInt();
                int account=rd.nextInt()*10000000;
                double cobalance=rd.nextDouble()*100000;
                while(account<=0){
                         account=rd.nextInt()*10000000;
                }
                switch(number){
                        case 1:
                                System.out.println("你的当前余额为"+cobalance);
                                System.out.print("请输入你要存入的款额:");
                                Double money = input.nextDouble();
                                cobalance=saving(cobalance,money);
                                System.out.println("存款成功,你的当前余额为"+cobalance);
                                break;
                        case 2:
                                System.out.println("你的当前余额为"+cobalance);
                                System.out.print("请输入你要取出的款额:");
                                Double money1 = input.nextDouble();
                                cobalance=withdrawing(cobalance,money1);
                                System.out.println("取款成功,你的当前余额为"+cobalance);
                                break;
                        case 3:
                                System.out.println("你的当前余额为"+cobalance(cobalance));
                                break;
                        case 4:
                                System.out.println("你的帐号为"+account(account));
                                break;
                        default:
                                System.out.println("请输入正确的数字!");
                                break;
                }

        }
        public static double saving(double a,double b){
                return a+b;
        }
        public static double withdrawing(double a,double b){
                return a-b;
        }
        public static double cobalance(double a){
                return a;
        }
        public static int account(int a){
                return a;
        }

}

用JAVA绘制QQ表情呲牙式笑脸

2011年05月11日 分类目录 :程序语言 2

见作业中有要求用Graphics类在Applet中绘制一个笑脸的题,就忧郁的拿最喜欢使用的QQ表情呲牙来做模板了,经过上百次调试(主要是找出每个器官的位置),总算是有点成型了。这里贴出该图像的代码,欢迎互相学习。另注:本人艺术细胞气度缺乏,所以做出来的效果较差,甚至连脸部器官的位置都不正,望谅解!

import java.awt.*;
     import java.applet.*;
       public class SmileFace extends Applet{
              public static void main(String[] args){}
              public void paint(Graphics g)
                     {

                          //绘制脸部轮廓
                          g.setColor(Color.yellow);
                          g.fillOval(40,40,200,200);

                          //绘制眉毛
                          g.setColor(Color.black);
                          g.fillArc(85,90,40,10,0,180);          //左眉
                          g.fillArc(165,90,40,10,0,180);         //右眉

                          //绘制左眼
                          g.drawArc(80,100,40,20,0,180);

                          //绘制右眼
                          g.drawArc(160,100,40,20,0,180);

                          //绘制嘴巴
                          g.drawLine(110,174,180,174);
                          g.setColor(Color.white);
                          g.fillArc(110,160,70,30,180,180);     //牙齿
                          g.setColor(Color.black);              //上嘴唇
                          g.drawArc(110,160,70,30,180,180);     //下嘴唇
                          g.drawLine(120,174,120,184);          //牙缝
                          g.drawLine(130,174,130,190);          //牙缝
                          g.drawLine(140,174,140,192);          //牙缝
                          g.drawLine(150,174,150,190);          //牙缝
                          g.drawLine(160,174,160,187);          //牙缝
                          g.drawLine(170,174,170,184);          //牙缝
                   }
        }

效果图如下:

,

用JAVA实现打印斐波那契数列

2011年05月10日 分类目录 :程序语言 2

经过3个月的oracle数据库学习,总算于近日回到java上来了,虽然那天的课由于要参加大哥的婚礼没能去上,不过还好,这天的内容不多。不过看到回家作业就头疼了,竟然出现applet内容了,忧郁的,准备翻书、翻jdk文档了。

斐波那契数列(Fibonacci Sequence), 又称为黄金分割数列。具体介绍详见维基百科斐波那契数列词条

import java.util.Scanner;

public class Fibonacci {
  public static void main(String[] args) {  

        int num1 = 1;
        int num2 = 1;
        int num3; 

        Scanner input = new Scanner(System.in);
        System.out.print("请输入要打印的个数:");
        int number = input.nextInt();

        if(number==1){
                System.out.print("1");
        }else{
                System.out.print(num1 + " " +
                        num2 + " "); 

                for (int i = 0; i < number-2; i++) {
                  num3 = num1 + num2;
                  System.out.print(num3 + " ");
                  num1 = num2;
                  num2 = num3;
                }
                System.out.println();
        }
  }
}   

以上是我所写的一个简单的实现打印斐波那契数列的程序,由于增加了设置打印个数的选项,因此我们可以随意控制打印个数。不过由于定义的是int类型,现在只支持最多打印46个数,超过这个数则会出现均为负数的现象。之前也曾考虑过定义为long类型,不过也只增加了几个数而已,因此就罢了。

以下是前面的代码的变形式,其不同之处是构造了一个方法,通过调用这个方法来进行计算,然后在main中调用它并打印出来。

,

配置Java编译环境

2011年01月11日 分类目录 :程序语言 6

       java由于其代码在虚拟机中运行的特性,即使电脑上有了netbeans、eclipse、记事本等编程工具,也只能进行代码编写而无法进行编译、调试,因此,我们需要在系统上架设编译环境。 首先我们需要访问java官网下载JDK,jdk是整个java的核心,它是一个软件开发工具包,其中包含javac-编译器,jar-打包工具,javadoc-文档生成器以及jdb-调试工具,它是java环境开发人员必备工具之一,因此,在我们开始编写java代码前必须先在系统上安装好jdk。当然,仅仅有jdk还是不行的,因为这样我们仍然无法运行java程序,因为还缺少JRE(java运行环境)包括了用于产品环境的各种库类,以及给开发员使用的补充库。 备齐这2个程序之后,我们就可以开始进行java开发了。

       jdk可以从oracle公司的For Java Developers页面进行下载,在下载到的jdk中也包含了一个完整版的jre,我们无需额外进行下载。在下载时我们要注意选择符合自己需求的版本,尤其是要确定自己的电脑是32位还是64位!

(for windows)

       在安装过程中,建议修改下安装路径,莫要安装在默认的C:\Program Files文件夹下,由于Program Files中含有空格,编译出来的程序在linux系统中运行可能会出现问题,因此为了方便起见,建议直接安装在C:\java文件夹下。 安装完成后,并不代表已经完成了java编译环境的架设,接下来的操作才是最最重要的,由于windows和linux中的配置法不一样,因此接下来会分别给予介绍:

FOR WINDOWS (本文以win7为例)

1.右键桌面“计算机”-“属性”-“高级系统设置”,在弹出的“系统属性”对话框中切换到“高级”标签页,打开“环境变量”。

2.在“环境变量”对话框中的系统变量下新建变量:JAVA_HOME,变量值为jdk路径(在本例中为:C:\Java\jdk1.6.0_23)

3.在系统变量中找到Path变量,对其进行编辑,在首位添加“%JAVA_HOME%\bin;”,友情提示,不要很脑残的不小心把已有的path值删除,否则后果自负!

 

3.同样是在系统变量中新建变量:classpath,变量值为:“.;%JAVA_HOME%\lib”。友情提示:不要忘了那个“.”!

至此java编译环境的配置已经完成,接下来打开命令提示符(开始-运行-cmd),键入java -version查看java编译环境是否搭建成功。如出现下图就说明编译已经成功:

 

FOR LINUX(本文以ubuntu为例)

由于我们从网站上下载到的jdk并非deb格式而是bin格式,因此无法像windows里那样双击进行安装,稍微麻烦点:

 1.首先在终端中进入放有jdk-6u23-linux(-x64).bin(以下简写为jdk.bin,在实际操作中请正确输入文件名,区别大小写,你也可在进行操作前先重命名为一个输入方便的名字)的文件夹,架设该文件现放于“下载”文件夹中:在终端中键入“cd /home/your username/下载”

 2.在终端中键入“sudo chmod 755 jdk.bin“,获得足够的权限。

3.键入“sudo ./jdk.bin”,运行该文件

4.键入“sudo mkdir /usr/java”(假设安装在/usr/java文件夹下),在/usr/中创建一个名为java的文件夹

5.键入“sudo mv jdk.bin/ /usr/java”,把jdk.bin中的文件都移动到/usr/java文件夹中。 至此前期工作已经完成。

 6.键入”sudo gedit /etc/environment”(修改profile文件有风险,因此建议在environment中修改),开始环境变量配置,在此文件的末尾加上代码“ JAVA_HOME=/usr/java/jdk1.6.0_24 PATH=$JAVA_HOME/bin CLASSPATH=.:$JAVA_HOME/lib” ,全部输入后保存该文件,并在终端中执行 source /etc/profile,此时如果报错 ,则说明刚添加的代码中有错误,请注意查看。

7.在终端中键入java -version,检查环境变量更改是否已经生效。 至此,在ubuntu中的java编译环境配置也宣告完成,接下来就可以开始写代码了,激动一下吧,万里长征已经走出了第一步。

, , , ,