基本程序设计

概述和目标

  学习如何编程解决实际问题。通过这些问题,学到如何利用基本数据类型、变量、常量、操作符、表达式以及输入/输出来进行基本的程序设计。

一、创建、编译和执行java程序

  我们从一个简单的Java程序开始,该程序在控制台上显示“Welcome to Java!".

public class Welcome{
    public static void main(String[] args){
        //在控制台显示Welcome to Java!  
        System.out.println("Welcome to Java!");      
    }  
}

  第一行定义了一个类。每个java程序至少应该有一个类。每个类都有一个名字。按照惯例,类名都是以大写字母开头的。本例中,类名为Welcome。

  第二行定义主方法(main method)。程序是从main方法开始执行的。一个类可以包含多个方法。main方法是程序开始执行的入口。

  方法是包含语句的结构体。本程序中的main方法包括了System.out.println 语句。该语句在控制台显示Welcome to Java!。字符串是一个编程术语,表示一个字符序列。一个字符串必须放入双引号中。java中的每条语句都以分号(;)结束,也称为语句结束符。

  关键字(keyword)或保留字(reserved word)对编译器而言都是有特定含义的,所以不能在程序中用作标识符。

  第三行是注释(comment),它对程序进行解释说明。注释帮助程序员进行相互沟通以及理解程序。注释不是程序设计语句,所以编译器编译程序时是忽略注释的。在java中,在单行上用两个斜杠(//)引导注释,称为单行注释;在一行或者多行用/*和*/括住注释,称为多行注释;在一行或者多行用/**和*/括住注释,称为文档注释,文档注释允许你在程序(一般用于类,接口等类型上以及方法上)中嵌入关于程序的信息。你可以使用 javadoc 工具软件来生成信息,并输出到HTML文件中。

  程序中的一对花括号将程序的一些组成部分组合起来,形成一个块(block)。每个块以左花括号{开始以右花括号}结束。每个类都有一个将该类的数据和方法放在一起的类块。每个方法都有一个将该方法的语句放在一起的方法块。块是可以嵌套的。

   这个程序会显示一条信息,很容易将该程序扩展为显示更多的信息:

public class WelcomeWithThreeMessage{
    public static void main(String[] args){
        //在控制台显示Welcome to Java!  
        System.out.println("Welcome to Java!"); 
        System.out.println("哇哦,Java好有趣!");  
        System.out.println("我要学Java!");   
    }  
}

  更进一步,你可以进行数学计算,并将结果显示到控制台上。

public class ComputeExpression{
    public static void main(String[] args){
        System.out.println((10.5 + 2 * 3) / (45 - 3.5));   
    }  
}

  java中的乘法操作符是*,除法操作符是/,将一个数学表达式翻译成java表达式是一个非常直观的过程,在后面的章节进一步讨论java表达式。

  在程序执行之前,必须创建程序并进行编译。这个过程是反复执行的。如果程序有编译错误,必须修改程序来纠正错误,然后重新编译。如果程序有运行时错误或者不能产生正确的结果,必须修改这个程序,重新编译它,然后重新执行。

  注意:源文件的扩展名必须是.java,而且文件名必须与公共类名完全相同。例如我们的第一个程序源文件必须命名为Welcome.java,因为公共的类名就是Welcome。可以使用任何一个文本编辑器或者集成开发环境来创建和编译java源文件。

  java编译器将java源文件翻译成java字节码文件。下面的命令就是用来编译Welcome.java的:

javac Welcome.java

  如果没有出现语法错误,编译器(compiler)就会产生一个扩展名为.class的字节码文件。java语言是高级语言,而java字节码是低级语言。字节码类似于机器指令,但它是体系结构中立的,是可以在任何带Java虚拟机(JVM)的平台上运行的。虚拟机不是物理机器,而是一个解释java字节码的程序。这正是java的优点之一:java字节码可以在不同的硬件平台和操作系统上运行(一次编译,到处运行)。java源代码编译成java字节码,然后java字节码被JVM解释执行。你的java代码可能要用到java库中的代码。JVM将执行你的程序代码以及库中的代码:

  执行java程序就是运行程序的字节码,可以在任何一个装有JVM的平台上运行字节码(跨平台),解释java字节码。解释的过程就是一次将字节码中单独的一步翻译为目标机器语言代码,翻译完后就立即执行这一步。下面的命名用来运行第一个程序字节码

java Welcome

  注意:在执行Java程序时,JVM首先使用一个名为类加载器(class loader)的程序将类的字节码加载到内存中。如果您的程序使用其他类,类加载器会在需要它们之前动态加载它们。加载类之后,JVM使用一个名为字节码验证器(bytecode verifier)的程序来检查字节码的有效性,并确保字节码不违反Java的安全限制。Java强制执行严格的安全性,以确保来自网络的Java程序篡改和损害您的计算机。

二、程序设计风格和文档

  程序设计风格决定程序的外观,文档是关于程序的解释性评注和注释的一个结构体。良好的程序设计风格和适当的文档可以减少出错的机率,并且提高程序的可读性。

  1.正确的注释和注释风格

  2.正确的缩进和空白

  3.块的风格

三、编写简单的程序

  编写简单的程序涉及如何设计解决问题的策略,以及如何应用编程语言实现这个策略。

  首先,我们来看一个计算圆面积的简单问题。该如何编写程序解决这个问题呢?编写程序涉及如何设计算法以及如何将算法翻译成程序指令,即代码。算法描述的是:如果要解决问题,所需要执行的动作以及这些动作执行的顺序。算法可以帮助程序员在使用程序设计语言之前做一个规划。算法可以用自然语言或者伪代码(自然语言和程序设计语言混在一起使用)描述。这个程序的算法描述如下:

  1.读入半径

  2.利用公式计算面积:面积 = 半径 x 半径 x π

  3.显示面积

  编码将一个算法翻译称程序。我们已经知道每个java程序都是一个类的声明开始,在声明类名紧跟在class后面。假设选择ComputeArea作为这个类的类名。这个程序的框架就如下所示:

public class ComputeArea{

}

  每一个java应用程序都有一个main方法,程序从该方法开始执行:

public class ComputeArea{
    public static void main(Stirng[] args){
        //第一步:读入半径
        //第二步:计算面积
       //第三步:显示面积
    }
}   

  这个程序需要读取用户从键盘输入的半径。这就产生两个重要问题:

  • 读取半径
  • 将半径存储在程序中

  先来解决第二个问题。为了存储半径,在程序中需要声明一个称作变量的符号。变量代表了存储在计算机内存中的一个值。变量名应该尽量选择描述性的名字,在这个例子中用radius表示半径、用area表示面积而不是用x和y这样的名字。为了让编译器知道radius和area是什么,需要指明它们的数据类型。这称为声明变量。java提供简单数据类型来表示整数、实数、字符以及布尔类型。这些称为基本数据类型。

  实数(带小数点的数字)在计算机中使用一种浮点的方法来表示。因此我们把实数称为浮点数。java中,可以使用关键字double来声明一个双精度的浮点变量。将radius和area声明为double:

public class ComputeArea{
    public static void main(Stirng[] args){
     //每个变量都有名字,类型、大小和值
double radius; double area; //第一步:读入半径 //第二步:计算面积 //第三步:显示面积 } }

四、从控制台读取输入

  可以使用Scanner类从控制台输入:

Scanner input = new Scanner(System.in);
//调用nextDouble()方法来读取一个double值
double radius = input.nextDouble();

  重写上面程序,提示用户输入一个半径

import java.util.Scanner;//Scanner在java.util包中,使用需要将其导入进来

public class ComputeArea{
    public static void main(Stirng[] args){
        System.out.println("请输入圆的半径");
        Scanner input = new Scanner(System.in);
   //每个变量都有名字,类型、大小和值
        double radius = input.nextDouble();
   //计算面积 
        double area = radius * radius * 3.14;
       //显示面积
       System.out.println("半径为:" + radius + "的圆的面积为:" + area);

    }
}       
Scanner在java.util包中。在第一行被导入。import语句有两种类型:明确导入和通配符导入。
明确导入时在import语句中指定单个的类:import java.util.Scanner;
通配符导入指使用星号作为通配符,导入一个包中的所有类import java.util.*;
除非要在程序中使用某个类,否则关于被导入包中的这些类的信息在编译时或运行时是不被导入的。导入语句至少告诉编译器在什么地方能找到这些类。明确导入和通配符导入在性能上是没有什么差别的。‘
练习:从键盘读取三个数值,然后显示它们的平均值。

五、标识符

  Java中的包、类、方法、参数和变量的名字。所有的标识符必须遵循以下规则:

  • 可由任意顺序的大小写字母、数字、下划线(_)和美元符号($)组成
  • 不能以数字开头
  • 不能是关键字

  合法的标识符

    username
    user_name
    _userName
    $username

  不合法的标识符

    class

    3.14

六、变量

变量的概念:

  • 内存中的一个存储区域
  • 该区域有自己的名称(变量名)和类型(数据类型)
  • 该区域的数据可以在同一类型范围内不断变化

  变量用于表示特定类型的数据。为了使用变量,可以通过告诉编译器变量的名字极其可以存储的数据类型来声明该变量。变量声明告知编译器根据数据类型为变量分配合适的内存空间。声明变量的语法如下:

  datatype  variableName;

  示例:

  int count;

  double radius;

  double area;

  如果几个变量为同一类型,允许一起声明它们:

  datatype variable1,variable2,...,variablen;

  变量之间用,分开。例如:

  int i,jk;

  变量通常都有初始值。可以进一步完成变量的声明和初始化:

  int count = 1;

  它等同于下面两条语句:

  int count;

  count = 1;

  也可以使用简捷的方式来同时声明和初始化同一类型的变量:

  int i = 1, j = 2;

Tips:在赋值给变量之前,必须声明变量。方法中声明的变量在使用之前必须被赋值(初始化)。任何时候,都要尽可能一步完成变量的声明和初始化。这会使得程序易读同时避免程序设计错误。

  每个变量都有使用范围。变量的使用范围(作用域)是指变量可以被引用到的程序的部分。

七、赋值语句和赋值表达式

  赋值语句将一个值指定给一个变量。在java中赋值语句可以作为一个表达式。将等号(=)作为赋值操作符。语法如下所示:

  variable = expression;

  表达式(expression)表示涉及值、变量和操作符的一个运算,它们组合在一起计算出一个新值:

  int i = 1; 

  double radius = 1.0;

  int ret = 5 * (3 / 2);

  ret = i + 1;

  double area = radius * radius * 3.14;//变量可用在表达式中,也可用于=操作符的两边

八、命名常量

  一个变量的值在程序执行过程中可能会发生变化,但是常量则表示从不改变的永久数据。在前面的程序中,π是一个常量。如果频繁使用它但又不想重复地输入3.14,代替的方式就是声明一个常量π。语法如下:

  final datatype CONSTANTNAME = value;

  常量必须在同一条语句中声明和赋值。单词final是声明常量的java关键字。

package edu.cduestc.charpter1;

import java.util.Scanner;

public class ComputeAreaWithConstant {
    
    public static void main(String[] args) {
        final double PI = 3.14;
        System.out.println("请输入圆的半径:");
        Scanner input = new Scanner(System.in);
        //读取半径
        double radius = input.nextDouble();
        //计算圆的面积
        double area = PI * radius * radius;
        //显示面积
        System.out.println("半径为:" + radius + "的圆的面积为:" + area);
    }

}

使用常量的好处:

  1.不必重复输入同一个值

  2.如需修改常量值,只需要在源代码中的一个地方做修改

  3.给常量一个描述性名字会提高程序的易读性

九、命名习惯

  严格遵循java的命名习惯可以让你的程序易于理解,以及避免错误。应该确保程序中为标识符(变量、常量、类、方法和参数)所选择的描述性名字是直观易懂的。命名是区分大小写的。

  • 使用小写驼峰命名规则命名变量和方法及参数。例如,变量radius和area以及方法print
  • 类名中每个单词首字母大写,例如,类名ComputeArea和System。
  • 大写常量中的所有字母,多个单词用下划线连接,例如,常量PI和MAX_VALUE。

十、数值数据类型和操作

 

1、整型

 

为什么会有不同大小的类型,举个例子比如存 5 这个数据怎么存的?

  1. byte(8位,-2^7--2^7-1范围是-128到127) 
  2. short(16位,-32768—32767
  3. int(32位,-2147483648—2147483647
  4. long (64位,-92233720368547758089223372036854775807)

注意:给long赋值时,因为整数默认是int类型,要转换为long类型的值,后面加上l或L

上面的byte short int long 最大长度可以通过jdk文档去找到 具体的范围。

  • 同一个整数可以使用不同的进制表示:

  默认的进制10进制

  二进制: 是 0b 或者 0B开头

  八进制: 是0开头

  十六进制: 0X (0x) 开头

  上面输出的是 10进制

为了提高可读性,Java7 开始 支持数字之间用 _ 分割

2、浮点型(小数型)

 

A. float(单精度32位) 直接赋值时必须在数字后加上f 或F

B. double( 双精度64位)

区别:

       对于单精度浮点数,运行速度相比double更快,占内存更小,但是当数值非常大或者非常小的时候会变得不精确。双精度比单精度表示的位数大 精确的位数多,简单地说, float表示的小数点位数少。

默认浮点数的类型是 double

表现形式:

  1. 常规  3.14
  2. 科学计数法(例如  3.14e2  3.14e-2)

注意:

表示float 类型 必须加上f 或者F

float double  不能精确表示一个小数,例如 1.3*1.4

例如 double num= 1.0, 是一个无限接近1.0的一个值

              那怎么更精确的表示浮点数呢?BigDecimal

结论:浮点运算很少是精确的,只要是超过精度能表示的范围就会产生误差。往往产生误差不是 因为数的大小,而是因为数的精度。因此,产生的结果接近但不等于想要的结果。尤其在使用 float 和 double 作精确运 算的时候要特别小心。

3、从键盘读取值

4、数值操作符

  算术运算符注意问题:

  • “+”除字符串相加功能外,还能把非字符串转换成字符串 ,如: “x”+123;的结果是“x123” 。 
  • 如果对负数取模,可以把模数负号忽略不记,如:5%-2=1。但被模数是负数就另当别论。
  • 对于除号“/”,它的整数除和小数除是有区别的:整数之间做除法时,只保留整数部分而舍弃小数部分。 例如:

int x=3510;x=x/1000*1000;

实际运行结果是多少 ,想想为什么?

  操作符%通常用在正整数上,实际上它也可以用于负数和浮点值。只有当被除数是负数时余数才是负的。

示例:计算以秒为单位的时间量所包含的分钟数和余下的秒数。

package edu.cduestc.charpter1;

import java.util.Scanner;

public class DisplayTime {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("请输入一个整数来代表秒数:");
        int seconds = input.nextInt();
        int minutes = seconds / 60;
        int remainingSeconds = seconds % 60;
        System.out.println(seconds + "秒包含" + minutes + "分钟" + remainingSeconds + "秒");
    }
}

示例学习:显示当前时间数,可以通过System.currentTimeMills()返回当前时间的毫秒数。

package edu.cduestc.charpter1;

/**
 * 显示当前时间数
 * @author Adan
 *
 */
public class ShowCurrentTime {
    public static void main(String[] args) {
        //1.获取当前时间(总毫秒数)
        long totalMilliseconds = System.currentTimeMillis();//返回1970年1月1日午夜到现在流逝的毫秒数(1000毫秒 = 1秒)
        System.out.println(totalMilliseconds);
        //2.将总毫秒数换算成总秒数
        long totalSeconds = totalMilliseconds / 1000;
        //3.得到当前的秒数
        long seconds = totalSeconds % 60;
        //4.通过总秒数/60得到总分钟数
        long totalMinutes = totalSeconds / 60;
        //5.通过totalMinutes % 60得到当前分钟数
        long minutes = totalMinutes % 60;
        //6.通过totalMinutes / 60得到总小时数
        long totalHours = totalMinutes / 60 + 8;//位于东八区
        //用总的小时数 % 24 得到当前的小时
        long hours = totalHours % 24;
        
        System.out.println(hours + ":" + minutes + ":" + seconds);
    }
}

十一、增强赋值操作符

  经常会出现变量的当前值被使用、修改,然后再重新赋值给该变量的情况。例如,下面的语句将变量count加1.

  count = count + 1;

  可以使用增强赋值操作符来结合赋值和加法操作符的功能。例如,上面的语句可以写成:

  count += 1;

十二、自增和自减操作符

++让变量的值自增1

     1)前++++在变量的前面,先自增1,后运算

     2)后++++在变量的后面,先运算,再自增1

--让变量的值自减1

     1)前----在变量的前面,先自减1,再运算

     2)后----在变量的后面,先运算,再自减1

十三、数值类型转换

发生的场景:不同类型的变量之间进行运算

数据类型的转换分为两种:

1)自动类型转换:byte short char ==>int==>long==>float==>double

       注意:a.当byte short char 之间进行运算时结果属于int型;

              b.boolean类型不可以转换为其它的数据类型。     

2)强制类型转换:将容量大的数据类型强制转换成容量小的数据类型,必须使用"(目标数据类型)"符号;

       格式是:小的数据类型 = (小的数据类型)大的数据类型。

       注意:强转后会造成精度的损失(丢失),丢的是高位。.

3)变量与字符串进行运算:

"+":表示的是连接符,即运算结果是字符串

 十四、软件开发过程

  软件开发生命周期是一个多阶段的过程,包括需求规范、分析、设计、实现、测试、部署和维护。

  开发一个软件产品是一个工程过程。软件产品无论多大或者多小,具有同样的生命周期:需求规范、分析、设计、实现、测试、部署和维护

   需求规范是一个规范化的过程,旨在理解软件要处理的问题,以及将软件系统需要做的详细记录到文档中。这个阶段涉及用户和开发者之间紧密的接触。

  系统分析旨在分析数据流,并且确定系统的输入输出。

  系统设计是一个从输入获得输出的过程。这个阶段涉及使用多层的抽象,将问题分解为可管理的组成部分,并且设计执行每个组成部分(子系统)的策略。

  实现是将系统设计翻译称程序。为每个组成部分编写独立的程序,然后集成再一起工作。

  测试确保代码符合需求规范,并且排除错误。

  部署是对软件产品进行更新和改进。

示例:设计一个计算贷款支付程序。我们重点关注需求规范,分析,设计,实现和测试。

需求规范
  程序满足以下要求:
    必须让用户输入贷款利率、贷款额度、贷款年限
    必须计算和显示月支付额度和总支付额度
系统分析
  输出是月支付额和总支付额,可以通过贷款公式进行计算
   

  总支付额 = 月支付额度 * 年限 * 12;
系统设计
  分解出下面这些步骤:
    step1:提示用户输入贷款利率、贷款额度、贷款年限
    step2:对于年利率的输入是一个百分比格式的数字,需要转换为十进制数,输入的利率是年利率,可以计算出月利率
    step3:使用公式计算月支付额
    step4:计算总支付额
编码实现

package edu.cduestc.charpter1;

import java.util.Scanner;

public class ComputeLoan {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("请输入贷款额度:");
        double loanAmount = input.nextDouble();
        System.out.println("请输入贷款年限:");
        int years = input.nextInt();
        System.out.println("请输入贷款利率,格式为:4.5,代表年利率为4.5%");
        double interestRate = input.nextDouble();
        double monthlyInterestRate = interestRate / 1200;
        
        double monthlyPayment = loanAmount * monthlyInterestRate / (1 - 
                1 / Math.pow(1 + monthlyInterestRate, years * 12));
        double totalPayment = monthlyPayment * years * 12;
        
        System.out.println("月支付额:" + monthlyPayment);
        System.out.println("总支付额:" + totalPayment);
    }

}

作业:

1.初始化a=3b=4;请计算:

1) (a++)/3+(--b)*2-(a--)%6+(b++)*3-(b--) 

2) (++b)*2-(a--)%4+(a++)*5-(--b)/2+(--a)

3) (a--)*6+(b++)/3-(--a)*2-(--b)*2+(++a)

2.初始化a=3,b=4;请计算:

1)  a>b&(a++)>b&(--b)<a&(b++)>(a--);   

2)  b<=a|(b--)>(--a)|(++b)!=(a++)|(b--)==(a--)

3.成绩score=80,如果成绩大于等于60,输出及格,如果成绩大于等于70,输出中,如果成绩大于等于80,输出良,如果成绩大于等于90,输出优秀,如果成绩小于60,输出不及格。

4.完成如下图的功能

 

5.用户输入四位会员号:计算四位会员号的之和。提示:用/%得到个位,十位,百位,千位

   6.整钱兑零:将一个大额的钱分成较小的货币单位
该程序要求用户输入一个double类型的数值,该值是用美元和美分表示的总钱数,列出和总钱数等价的最大数量的dollar(美元)、quarter(2角5分)、dime(1角)、nickel(5分)和penny(1分)的数目,按照这个顺序,从而使得硬币最少。

     7.将摄氏温度转为华氏温度
    华氏温度=(9/5)* 摄氏温度 + 32

     8.计算飞机起飞所需的最短跑道长度
    跑道长度 = v平方/2a;其中v为起飞速度,a为加速度

     9.假设你每月向银行存1000元乖乖,年利率为2%,那么月利率为 0.02 / 12,第一个月后,账户上的值就变为:
1000 * (1 + 0.02 / 12) = 1,001.67
第二个月就变为:
(1000 + 1,001.67) * (1 + 0.02 / 12) = ?
依次类推,编写程序显示6个月的账户总数(每个月显示一行) 

      10.计算两点(x1,y1) 和(x2,y2)之间的距离

 

面试常见问题

1.在底层,正数是以哪个码存的?负数是以哪个码存的?

2.Java有没有goto

3.用最有效率的方法算出2乘以8等于几?

4.char型变量中能不能存贮一个中文汉字?为什么?

5.String是最基本的数据类型吗?

posted @ 2020-07-03 11:12  Tiger-Adan  阅读(2228)  评论(0编辑  收藏  举报