下学期的教课需要从Java改用C++,快10年没碰过的语言了,需要从头复习一下,把总结记录下来方便提醒自己。此文以当前最新的C++ 17 和 Java 12 标准为准。此文假设读者熟悉Java。
大体上来说二者都是编译型语言,且都有很多编译器可供使用。Java先把Source Code编译为bytecode, 在执行时由JVM动态地读取bytecode并interpret成machine code然后执行,严格意义上来说属于半编译半解释型语言。C++总体上是纯编译型语言,由source code编译为assembly code,再到machine code, 最后link为可执行文件运行。
Java的标准JVM是Hotspot JVM,C++的标准编译器是GCC(g++)。这两个产品都是主流的,经过多年润饰的稳定型产品。如果追求极致性能则应该考虑其他替代产品。
从执行环境来看,Java进程是在JVM里面执行,内存的堆栈, metaspace, 方法区,垃圾回收等全部由JVM搞定,不直接面对操作系统,优点是性能不受平台影响,缺点是速度相对慢,需要针对不同平台的环境分别配置JVM,此外仍需配置OS, 运维管理比较复杂。C++进程则是直接由操作系统管理的,缺点是性能受平台影响,优点则是配置简单,只需要配置好OS即可,此外省去了解释的步骤所以速度相对快。
Java的库比较简单,由于bytecode都是在运行时动态导入的,所以不存在“动态库”(dynamic linked library)的说法。静态库(static library)则只有一种,即包含bytecode的jar文件。
C++的库相对复杂些。存在动态链接库的概念,而且在不同的操作系统上的格式不同
动态库:
静态库:
Java除了标准库,主要还有Apache库。C++除了标准库,主要还有Boost库。
Java主流的依赖关系系统有Maven和Gradle, C++有Conan, Buckaroo, Cmake等。
Java的source code文件格式以.java为后缀名,bytecode文件后缀则是.class。
C++的source code文件有两种,.cpp和.h,汇编文件为.s, 编译后文件为.a, 连接后文件后缀名与OS有关。Windows上为.exe, Linux和Mac OS上无后缀名限制。
Java使用package作为命名空间,与文件系统的路径相对应,.java文件的名字必须与其中的类同名,且一个.java文件只能定义一个类。使用URL的倒序作为package名字来唯一地识别命名空间。不允许在一个.java文件里定义多个命名空间,使用起来相对简单。
导入命名空间(包):
import java.util.*;
使用命名空间全名引用:
java.util.Scanner scanner = new java.util.Scanner(System.in);
C++的情况更复杂,允许在一个.cpp文件中定义多个命名空间:
namespace a {
int dog = 1;
}
namespace b {
int dog = 2;
}
还可以嵌套定义:
namespace c{
int dog = 2;
namespace d{
int dog = 2;
}
}
还可以在多个文件中定义一个命名空间。由于这种复杂性,C++里导入库和引用命名空间是分开的:
导入库:
C++: #include \<iostream\>
引用命名空间;
std::cout >> "Hello World";
这是因为一个库中可能定义了好几个命名空间。
二者一样,都支持line comment 和 block comment:
// line comment.
/* block comment
1
2
/*
基本数据类型基本相同,都包括:
此外, C++特有一个宽字符型 wchar_t, 就是short int的别名:
typedef short int wchar_t
C++还独有一些类型修饰符,可以修饰char, int 或者double, 包括:
而Java没有类型修饰符的概念,默认都为有符号类型。多了一个byte类型。把short int, long int直接作为基本数据类型(short, long)。要在Java里模拟无符号数则需要用到>>>这个无符号右移操作符。
这是C++从C里面继承来的关键字,可以给已有的数据类型定义别名(alias):
typedef int feet;
feet a; // same as 'int a;'
Java里面没有类似的关键字,如果想实现类似的功能,可以用类的继承来实现类似的效果,不过此法对基本数据类型无效。
C++里的enum比java简单得多,只能包括data member, 不能包含member function。
enum color{
red=0,
blue=1,
yellow=2
}
color c=red;
Java里的enum除了可以定义常量外,还可以像一个普通类一样定义data member和member function.
public enum Color {
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index;
// 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
// 普通方法
public static String getName(int index) {
for (Color c : Color.values()) {
if (c.getIndex() == index) {
return c.name;
}
}
return null;
}
// get set 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}
---------------------
版权声明:本文为CSDN博主「李学凯」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_27093465/article/details/52180865
C++和Java都要求变量名只能包括字母,数字和下划线,且不能以数字开头,都对大小写敏感。
Java中的变量声明和定义是一起完成的, 而且声明的同时就会被初始化,比如:
int a;
完成了声明,定义和初始化的全部三个步骤(初始化为0)。
C++中,变量的声明和定义是分开的,因为C++允许在别的文件中定义变量,如下:
extern int a;
而变量的定义则必须在函数内完成。
C++和Java的局部变量都是指在函数内部定义的变量,其作用域同为定义发生的函数。
C++的全局变量是独立于类的,任何类和函数都可以使用。Java中的全局变量必须隶属于一个类,是这个类的public static 成员,而且引用时需要用类名.变量名或者通过一个static getter 函数。
由于运行效率的原因,C++和Java都会默认给全局变量初始化(0, null 或者false),都不会初始化局部变量(可能为任何值)。
文件1
#include
int count ;
extern void write_extern();
int main()
{
count = 5;
write_extern();
}
=============================================
文件2
#include
extern int count;
void write_extern(void)
{
std::cout << "Count is " << count << std::endl;
}
Java使用final关键字来定义常量。
C++有两种方式,可以用const关键字定义,也可以用#define 预处理器定义
const int A = 0;
#define A 0
二者等价
C++与Java的各类运算符基本完全相同。
C++和Java中的大部分循环语法相同,包括while, for, do…while, break, continue。
C++中多了一个goto语句,可以强制将控制转移到指定的语句。不建议使用。
C++和Java中的大部分判断语法相同,包括if, if…else, switch, …?..:…。
Java允许用String做Switch的条件,C++不允许必须用strcmp()函数解决。
C++中的函数可以在别的文件中声明,声明与定义分开。函数可以属于类也可以像C那样单独存在。
Java中的函数声明和定义都在一起,而且Java里任何东西都是类,所以函数只能属于类而不能单独存在。
具体函数声明/定义的语法二者相同,返回值类型+函数名+参数定义。
C++中的一个文件调用定义在另一个文件中