从本科到研究生毕业,从windos下C编程,到单片机汇编和C编程,到Linux操作系统下C开发,再到光通信算法研究,再到硬件开发,做过的东西很多很杂,有一个特点就是做后一个项目,前一个项目的内容瞬间就会不知道被扔到脑海的那个小角落里,要捡起的时候还要寻摸很久,因此就有了写技术贴的想法,把那些可能遗失在角落的知识整理到网上来,好让自己可以随时观玩,也可以分享给那些同样正在摸索这些知识的小伙伴们,希望大家共同成长。
这篇帖子是我回顾C语言和JAVA学习的一篇技术贴,在C与JAVA的对比中捡起那些基础点滴。
Java和C以及C++的都是高级语言,相比于汇编,或者机器语言的01代码,无疑大大简化了程序员的编程工作,三者很多基础语法结构类似,尤其是JAVA与C++,有一门的基础往往其他几种语言掌握起来会非常容易,抛去与计算机有关的东西,编程语言最后都会归结到算法上来,这是一个基础,同一个功能,三种语言一般都可以实现,只不过难易不同,因此一些招聘要求低的公司,往往会说掌握其中一门编程语言即可。
相比于共同点,掌握JAVA与C的区别才是一个工程师从C转向JAVA或者从JAVA转向C的必修课程。JAVA可以用十一个词来说明它的特点:简单性,面向对象性,分布式,健壮性,安全性,体系结构中立性,可移植性,解释型,高性能,多线程,动态性(具体解释可以参考JAVA白皮书)。从其特点可以看出,实际上JAVA与C最大的区别是C是面向过程的,过程可控;JAVA是面向对象的,忽略过程编写简单功能强大效率较低,这是一个信息量很大的解释,具体可以查找面向对象和面向过程的对比。
JAVA具有更好的可移植性,可以做到跨平台,因为Java是解释型语言,所有代码都会翻译成统一的、与系统无关的bytecode,然后放到JVM上运行;而C是编译式语言,代码要先通过编译器转换成与系统相关的中间代码,然后才能运行。
再一个不同是,Java不支持系统调用,既无法与操作系统进行交互,这是由它跨平台的特点决定的,而C则可以调用系统中的指令,如fork()。这也就是为什么Java中只有线程(Thread)概念而没有进程(Process)概念,而C两者均有。
再者,Java无法对内存进行控制,而C则可以通过指针对内存进行人为分配。还有一点,Java有Gabbage Collection机制,可以自动回收不再使用的空间,而C则要用free()函数释放空间【http://zhidao.baidu.com/link?url=GHSCSIrf21G9rv4Wq8aBvj6TFxhfl3OqAgtg35_yeldSfXFuUVKv2QsoTuEz3-zul02TiMfwa6UwAeKlR3Crba】。
再具体的从语法上来说,JAVA和C还有很大的不同,下面应用网上总结罗列几个【http://blog.csdn.net/easy_gemini/article/details/8226402】:
1、标识符:
C可用的标识符为数字、大小写字母、下划线,不能以数字开头;
Java可用的标识符除了C的三种以外,多一种美元符号($),同样不能以数字开头。
2、关键字:
C中的关键字有:
auto break case char const
continue default do double else
enum extern float for goto
if int long register return
short signed sizeof static struct
switch typedef union unsigned void
volatile while
Java中的关键字有:
abstract boolean break byte case
catch char class continue default
do double else extends false
final finally float for if
implements import instanceof int interface
long native new null package
private protected public return short
this throw throws transient true
try static super switch synchronized
void volatile while
3、数据类型:
C中的数据类型有:
1)基本类型:整型(基本整型int、短整型short[int]和长整型long [int]以及有符号型[signed]、无符号型unsigned)、字符型[signed/unsigned ]char、浮点型(单精度型float、双精度型double和长双精度long double)、枚举类型
2)构造类型:数组类型、结构体类型、共用体类型
3)指针类型
4)空类型
注意下各类型一般所占字节数:
int:2字节
short:2字节
long:4字节
char:1字节
float:4字节
double:8字节
long double:16字节
以上存储除char类型外,其他视系统不同略有不同,但低精度的位数不可以超过高精度的。
Java中的数据类型:
1)基本类型:字符型(char)、数值型(整型(字节型byte、短整型short、整型int、长整型long)、浮点型(单精度型float、双精度型double))、布尔型(boolean(true或false))
2)复合类型:类、接口、数组
注意下各类型存储所占字节数:
byte:1字节
short:2字节
int:4字节
long:8字节
char:2字节(Unicode编码)
float:4字节
double:8字节
以上数据类型对应的存储空间与平台无关,固定为该值。
4、常量和变量
1)常量
Java和C中整型常量定义相同,除长整型数据在其末尾加l或L外,其他类型均直接显示数值。C中无符号常量在其后加u或U。对于不同进制,十进制直接显示最高位不能有0,八进制以0开头,十六进制以0x或0X开头。
对于浮点类型,C和Java均只能采用十进制表示。可使用小数形式和指数形式,指数形式表示时小数与指数之间用e或E分隔。注意Java中要求单精度后要加f或F,双精度后要加d或D以示区分。
字符型常量都是以单引号引起来的单个字符或转义字串表示。特别注意,C中字符型只能表示ASCII码从0~255的字符,Java中使用Unicode编码2字节存储单元可以表示特殊字符,表示unicode编码时使用\u加4位16进制字串。
布尔类型只有Java中才有,需特别注意。
Java中常量用关键字final修饰,一经赋值不可更改,习惯上常量明用大写,如果要定义一个类中可以被多个方法使用的常量即“类常量”,一般用static final定义在方法外定义,如果一个常量被public声明,那么其他类的方法也可使用这一常量;C中表示不可更改的关键字是const,其修饰的变量(注意是变量,不是常量)必须在定义时赋初值,另外用#define定义的宏常量没有类型。
2)变量
Java和C中变量的定义基本相同,即:
数据类型变量名[ = 变量初值];
变量可赋初值也可不赋,但Java中长整型和浮点型数后要加相应识别标志(如l、f)。
特别注意:由于编译器的不同,C申明变量要放在可执行语句之前,否则可能发生编译错误;而在JAVA中,变量声明可以放在代码的任何地方,但是好的代码规范是尽可能将变量声明放在第一次使用变量的前面。C中变量的声明和定义是区别的,在Java中不加以区分。
5、逻辑运算符和位运算符
C和Java中都有的逻辑运算符&&、||、!三种,且意义相同,区别在于C中运算结果为0和非0,Java中只能是ture或false。Java中还存在&、|、^(异或),&和&&、|和||的区别在于前者是非捷径运算符而后者是捷径运算符,即&前后都做判断,&&前为假不做后面的判断,|前后都做判断,||前为真不做后面的判断。^表示两者相同为假。
C和Java中都有的位运算符是:&、|、^、~(取反)、<<(左移)、>>(右移),意义基本相同。负数的右移运算在C中视不同系统有所不同(可能是算术右移也可能是逻辑右移),而Java中>>表示的是算术右移,即最高位填充符号位。Java中逻辑右移(无符号右移)运算符是>>>,采用补码右移,高位添0。
PS:有心的读者可能会发现,如果你定义了一个byte或者short类型的负数,如-10,采用>>>方法进行无符号右移后输出的结果是-5,按照上面说的高位添0应该是正数。而int或long类型的就不会是负数,这是为什么呢?我认为这是因为Java在进行>>>运算时采用的最低数据类型是int类型,导致高位数据全为1(计算机内存储的数据是以补码存储的,所以负数的byte或short类型转成int类型高位全填充1),移位时高位的最后一个1移到低位的第一位,然后截取成我们定义的数据类型(byte或short),所以我们看到的数还是负数。从这里我们可以看出,在byte和short类型的数据做>>>运算的时候可能得不到我们想要的值,千万注意。
6、数组
C中数组的定义如下:
类型说明符数组名[常量表达式];
定义可与初始化同时进行,如:int a[10] = {0,1,2,3,4,5,6,7,8,9};中括号内的常量可以省略。
Java中数组定义有两种方式:
数据类型数组名[];或
数据类型 []数组名;
定义和初始化可同时进行,如:int []a = {0,1,2,3,4,5,6,7,8,9};
注意Java中数组如果在定义时没有进行初始化,在进行初始化的时候需要先分配内存,即:
数组名 = new 数据类型[常量表达式];
也可在定义同时进行内存分配:
数据类型数组名[] = new 数据类型[常量表达式];
C和Java都不支持变长数组,引用的时候都是 数组名[下标]。区别是:Java的下标范围为0~数组长度-1,不在该范围会抛出数组下标越界异常,而C有效范围也是0~数组长度-1,但下标超出此界不会报错。
多维数组中,数组元素都是按行排列的。
还有一点要注意:C中定义数组不进行初始化则数组元素值是不可预知的,而Java中分配内存而不进行初始化数组中是有默认值的。
7、语句
C和Java语句区别不大,主要是:
1)方法/函数调用时C直接调用函数,Java调用方法时方法名前面要加对象名。
2)C中两个嵌套的复合语句同时定义同名变量是可以的,而Java不可以。
8、类、域、方法和全局变量、函数
1)类是C中没有的,Java中类定义如下:
[修饰符] class 类名[extends 父类名][implements 接口名]
{
//类体
}
其中修饰符可以为以下一个或多个访问修饰符:
abstract:抽象类。
final:最终类。
public:公共类。
2)域(成员变量)和全局变量类比:
Java中域的定义如下:
[修饰符] 类型 成员变量名;
修饰符可选以下一个或多个关键字:
public:公共成员。
protected:本类或同一个包的其他类以及其它包该类的子类可访问。
private:私有成员。
final:常量,确定后不能改变。
static:静态变量。
transient:临时变量。
volatile:备份变量。
各类型成员变量默认初始化为:
整型变量:0
浮点型变量:0.0
布尔型变量:false
字符型变量:空格
类变量:null
C中全局变量定义同一般变量:
[存储类别] 数据类型 变量表列;
其中存储类别可选:
auto:自动变量,当不申明存储类别时隐式默认该值。
static:静态变量。
register:寄存器变量。
extern:外部变量。
3)方法和函数类比:
Java中方法的定义如下:
[修饰符] 返回类型 方法名([参数表列])
{
//方法体
}
修饰符可选以下一个或多个:
public:公共方法。
protected:本类或同一个包的其他类以及其它包该类的子类可访问。
private:私有方法。
abstract:抽象方法,只有方法头没有方法体。
static:静态方法。
C中函数的定义如下:
[存储类别] [数据类型] 函数名([形参表列])
{
//函数体
}
存储类别可选:
extern:外部函数。
static:静态函数。
注意一下:Java中返回类型是不可省略的,没有返回值的时候必须为void(构造方法不用加void),而参数表列为空的时候不能加void。C中函数可以没有返回类型,默认为int类型(注意不是void!),形参表列也可以没有也可以为void。Java中一个类、域或方法没有定义访问控制符,则它的类型为默认修饰符(package),只能被本程序或同一个包的其他类访问和引用。C中变量和函数一定要先定义或申明才能使用,而Java中域(注意是域,不能是局部变量)和方法可以在同一个类中任意排列。与C不同,Java中局部变量必须先初始化才能使用,而域可以不进行初始化。C中函数结束可以没有return或retrun类型可以不匹配,return后也可以有执行不到的语句,但Java中return语句必须和类型匹配(除返回类型为void的可以省略return语句),且是最后一条可执行语句,否则会出现编译错误。同样Java方法的参数表列与传参类型必须一致。Java中局部变量可以和成员变量名相同,使用时用this关键字区分,但同一个方法中两个同级或嵌套的复合语句同时定义同名变量是不可以的。
9 二者字符串表示对比【http://blog.csdn.net/easy_gemini/article/details/8226123】
(1). C 语言
在C语言中字符串和字符数组基本上没有区别,都需要结束符;如:char s[4]={'a','b','c','d'};此字符数组的定义编译可以通过,但却没有关闭数组,若其后需要申请内存,那么以后的数据均会放入其中,尽管它的长度不够,但若为 char s[5]={'a','b','c','d'};则系统会自动在字符串的最后存放一个结束符,并关闭数组,说明字符数组是有结束符的;
而字符串定义的长度必须大于字符序列的长度,如:char s1[4]={"abcd"};编译不能通过,而应写成char s1[5]={"abcd"};并且系统会自动在字符串的最后存放一个结束符,说明字符串有结束符;
在C语言中使用strlen()函数可以测数组的长度,strlen()函数计算的时候不包含结束符'/0'。
char s[5]={'a','b','c','d'};
char s1[5]={"abcd"};
int a=strlen(s);
int b=strlen(s1);
结果是a,b均为4;
(2).Java语言
字符串和字符串数组都是不需要结束符的;
如:char[] value={'j','a','v','a','语','言'};
String s1=new String(value);
String s2="java语言";
int a=value.length;
int b=s1.length();
int c=s2.length();
运行得到的结果a,b,c都是6,说明字符串和字符串数组都不需要结束符。但注意此处value.length和s1.length(),在数组中有名常量length可以记录数组对象的长度,而length()是File类中的一个实例方法,用于返回文件的大小,当然也可以返回字符串的大小。String 类对象称为不可变字符串,不能直接修改字符串内容,一般是通过拼接等方法。