C语言转Java语言,相同与相异之处

一些啰嗦的话:其实在学C语言之前,我最早接触的是Java语言,因为Java前期的一些知识比C语言简单,所以在Java学业考试的时候勉强达到理想分数。后面断断续续学了将近3个月的C语言,只停留在初识层面,知识对于我来说难,加上期末周没时间学习整理知识,让我感觉已经忘光了。这段时间的感悟除了"先学难的语言再入门比较简单的语言能学的更通透些"之外,还有就是"学计算机的人怎么那么NB,思路怎么那么灵活,不像我对一道编程题能解一整天"。不过我还是会继续加油,努力学好一门语言。希望屏幕前的你,共勉。

目录

一、主程序入口(主函数)的不同

二、注释

三、数据类型与变量

[3.1 数据类型](#3.1 数据类型)

[3.2 变量](#3.2 变量)

四、常量

五、类型转换

隐式/自动转换规则

强制类型转换

六、输入输出

C语言

Java


一、主程序入口(主函数)的不同

C语言

复制代码
int main(void) {        // 主函数返回类型为 int,参数可为 void(无参数)
    // 代码逻辑
    return 0;           // 必须返回整数值
}

Java

java 复制代码
public class Main {     // 主函数必须位于类内
    public static void main(String[] args) {  // 固定签名:public static void
        // 代码逻辑
    }
}

// public:修饰符,此外还有3种
// class:类
// Main:类名(不写死,与.java文件同名)
// static:静态
// String[] :字符串数组类型
// args:数组名
// String[] args字符串数组

刚接触Java的不需要深入理解每个单词代表什么,只要牢记:一个文件中只有一个程序主入口,即只能写一遍 public static void main(String[] args){}

这里我想多说一嘴:

class类,可以理解为类型、种类,比如这世界上有不同种类(class也有种类的意思)的人,黄人、黑人、白人,甚至还有沃尔玛购物袋(bushi);

String[] args 字符串数组,其实和C语言的类似。只不过C语言中没有 字符串 String 类型,且中括号 [ ] 是放在数组名后面的,如 int arr[]; 这么看来Java设计的数组形式似乎更合理些,因为数据类型后面直接跟着中括号就是数组类型了,但是C语言中间却夹着数组名。

二、注释

回忆C语言(包括C99之后)中的注释:

复制代码
// 两条斜杆后面就是注释,只在该行有效

/* 这是多行注释
   回车之后依旧有效
*/

Java注释方法和C语言一样,并且多行注释也是不能嵌套的。但Java比C语言多了一种 文档注释:

复制代码
/**
文档注释:比多行注释多了一颗*
  @version v1.0.0
  @author 409
  
  作用:可以声明一些信息,如上面的版本、作者,还可以写上编写时间、文件用途等信息
*/

而在集成开发环境(可以理解为软件)中,注释的快捷键是:

一般用IntelliJ IDEA编写Java文件,其注释的快捷键是 Ctrl + Shift + /,取消注释也是此法

一般用VS编写C语言脚本,其注释的快捷键是 Ctrl + K + C,取消则是Ctrl + K + U

三、数据类型与变量

3.1 数据类型

C语言

区分无符号和有符号类型,char 是 1个字节。

【Java也有字符型 char,但Java的字符占2个字节,可以写入中文,因为一个汉字占2个字节。】

Java

基本数据类型:四类八种(一定要记得是 8 种基本数据类型)

引用数据类型: 前期先将 String 是引用类型与基本数据类型区分开来就行

不注重区分有符号和无符号,可以存储负数、零、整数

基本数据类型的取值范围只要熟记字节型 byte 的取值范围是-128~127即可,与C语言的字符 char 取值范围一致。

3.2 变量

C语言有两种变量,一种是局部变量、一种是全局变量

cpp 复制代码
int global_var = 42;  // 定义全局变量

int main() {
    int i = 10; // 局部变量
    printf("%d %d", global_var, i);
    return 0;
}

Java中除了有全局变量、局部变量还有成员变量

全局变量通常是静态变量(即用 static 修饰),与成员变量(实例变量)一样都是定义在主函数外面的。前期还无法明确全局变量和成员变量的具体区别就先放一放。

但在定义变量时Java有几处注意事项:

  1. 如果一个变量没有 初始化 (即赋值),那么在使用的时候就会编译报错

  2. 如果进行变量赋值的时候,字面值超过了可存储数值类型的范围,那么编译也会报错

  3. 长整型long在初始化时在值的后面要加上大写的L,eg: long a = 10L;

  4. 浮点型会被默认为是double类型,因此在初始化float类型变量时,在其值后加上f/F

四、常量

C语言

1、#define 定义的标识符常量:无类型,纯文本替代,eg: #define PI 3.1415926

2、const 关键字修饰的常变量,定义只读变量(有类型,但本质仍是变量,注意的是const修饰的常变量不能直接被修改)eg: const float PI = 3.14159;

3、用 enum 关键字定义的枚举常量

Java

final 关键字定义的不可变变量(必须显式初始化)eg: final double PI = 3.14159;

五、类型转换

Java与C语言一样,都存在隐式/自动类型转换和强制类型转换,因为C语言的较麻烦,此处只想解释Java的类型转换。

隐式/自动转换规则

  • 遵循"小范围→大范围"的自动提升原则:byte→short→int→long→float→double
  • 编译器严格检查,不符合规则会直接报错‌

强制类型转换

就是将"大范围"放到"小范围"内,如将 长整型 long 赋值给 整型 int ,想要将 long 强制类型转换成 int ,再进行赋值。

强制类型转换得到的数值会损失精度,可以理解为想要将 4L 的水放进容量为 50ml 的水杯中,水会溢出,所以得到的水肯定没有4L那么多。

java 复制代码
public class Test{
    public static void main(String[] args){
        int a = 10;
        long b = 128L;
        b = a; // 正常通过编译
        a = b; // 报错,在赋值时会损失精度
        a = (int)b; // 强制类型转换
        System.out.println(a); // 输出-128(127-1得到的值,回顾C语言中的整数存储方式,一个循环)
    }
}

输出为-128的原因:

注意事项:

  1. 不同数字类型的变量之间赋值, 表示范围更小的类型能隐式转换成范围较大的类型

  2. 如果需要把范围大的类型赋值给范围小的, 需要强制类型转换, 但是可能精度丢失

  3. 将一个字面值常量进行赋值的时候, Java 会自动针对数字范围进行检查(如将128赋值给byte 类型的常量)

  4. 强制类型转换不一定能成功,不相干的类型不能互相转换(如 boolean 类型转换成 int 类型)

还有一项隐式类型转换在运算当中需要注意的:

  1. intlong之间运算,int会被提升为long

  2. bytebyte之间运算,最终转换成4个字节的int类型(整型提升)

整型提升:由于计算机的 CPU 通常是按照 4 个字节为单位从内存中读写数据。为了硬件上实现方便, 诸如 byte 和 short 这种低于 4 个字节的类型, 会先提升成 int,再参与计算。

java 复制代码
public class Test{
    public static void main(String[] args){
        byte a = 10;
        byte b = 20;
        byte c = a + b; // 错误
        int c = a + b; // 正确写法1
        byte c = (byte)(a + b); // 正确写法2,a+b需要加括号
    }
}

六、输入输出

C语言

输出:printf = print + format,格式化输出,需要使用占位符

cpp 复制代码
#include <stdio.h> // 需要包含头文件

int main(){
    printf("%5d\n", 123); // 输出为"  123",默认右对齐,123前面有2个空格
    
    printf("%-5d\n", 123);  // 输出"123  ",加一个"-"使其左对齐,后面2个空格

    printf("Number is %.2f\n", 0.5); // 输出"Number is 0.50",保留两个小数点

    printf("%6.2f\n", 0.5); // 输出为"  0.50"。 %6.2f 表示输出字符串最⼩宽度为6,小数位数为2。所以,输出字符串的头部有两个空格。
    
    printf("%*.*f\n", 6, 2, 0.5); // 等同于printf("%6.2f\n", 0.5);

    printf("%s\n", "Hello World"); // 输出字符串默认全部输出
    printf("%.8s\n", "Hello World"); // 限定输出8个字符,输出"Hello wo"
}

链式访问 --> printf() 输出的返回值:

猜一下以下代码输出什么

cpp 复制代码
#include <stdio.h>

int main()
{
	printf("%d", printf("%d", printf("%d", 43)));
	return 0;
}

输出结果 :4321

因为 printf() 返回的是 打印在屏幕上的字符的个数,43是两个字符,因此 printf("%d", printf("%d", 43)) 输出2,2又是一个字符,因此 printf("%d", printf("%d", printf("%d", 43))); 输出1;并且因为占位符后面没有空格,因此输出每个数字是黏在一起的。

cpp 复制代码
int main()
{
	printf("%d ", printf("%d ", printf("%d ", 43)));
	return 0;
}

注意看两个代码的区别,猜一下上面的代码将输出什么?

答案是:43 3 2

因为空格也是字符,也要算在里面。


输入:scanf,格式化输入,与取地址符号 & 搭配使用

cpp 复制代码
#include <stdio.h>

int main(){
    int x = 0;
    float y = 0.0;
    // 用户输⼊ " -13.45e12# 0"
    scanf("%d%f", &x, &y);
}

scanf 读取到的数据是:-13 和 449999994880.000000(即0.45*10^12 // 浮点数输出会有误差)原因是:

scanf() 处理用户输入的原理是,用户的输入先放入缓存,等到按下回车键后,按照占位符对缓存进行解读。 解读用户输入时,会从上一次解读遗留的第一个字符开始,直到读完缓存,或者遇到第一个不符合条件的字符为止。

对于字符串:

scanf 会忽略输入中的空白字符(空格、制表符、换行符等),解读时从当前第一个非空白字符开始读起,直到遇到空白字符为止。

scanf() 不适合读取可能包含空格的字符串,若要读取多个字符,则使用多个 %s。另外,scanf() 遇到 %s 占位符,会在字符串变量末尾存储一个空字符 \0。

用 %s 能够读到空格的写法:

cpp 复制代码
#include <stdio.h>

int main()
{
    char arr5[20];
    scanf("%[^\n]s", arr5);  // "%[^\n]s"的意思是读取一个字符串,直到遇到\n停止
    printf("%s\n", arr5);
    return 0;
}

指定读入字符串的最长度的写法:

cpp 复制代码
#include <stdio.h>

int main()
{
    char arr3[5];
    scanf("%4s", arr3);  // 4s表示最多读取4个字符,剩一个位置给\0
    printf("%s\n", arr3);
    return 0;
}

为避免 scanf() 解析带有格式的数据失败的情况,scanf() 提供了一个赋值忽略符 * 。只要把 * 加在任何占位符的百分号后面,该占位符就不会返回值,解析后将被丢弃

cpp 复制代码
#include <stdio.h>

int main()
{
	int year = 0;
	int month = 0;
	int day = 0;
	scanf("%d%*c%d%*c%d", &year, &month, &day); // %*c 能够读取字符串,但该占位符不会返回值,在解析的时候会将其抛弃
	printf("%d %d %d\n", year, month, day);

	return 0;
}

无论输入"2025-7-8",还是"2025/7/8",抑或是"2025*7/8"结果都能输出"2025 7 8"

scanf() 返回值是⼀个整数,表示成功读取的变量个数。如果没有读取任何项,或者匹配失败,则返回 0 。

如果在成功读取任何数据之前,发生了读取错误或者遇到读取到文件结尾,则返回常量EOF(-1)。EOF - end of file 文件结束标志,通常用于多组输入中。

cpp 复制代码
#include <stdio.h>

int main() {
    int a, b;
    while (scanf("%d %d", &a, &b) != EOF) { // 注意 while 处理多个 case
        printf("%d\n", a + b);
    }
    return 0;
}

Java

对于Java语言,并没有C语言中 "0为假,非0为真" 的概念,而是用布尔值表示真假,返回值为true 表示真,返回 false 则为假。

Java中的输入输出不需要包含头文件,Java中也没有 #include 的指令

输出

System.out.print(); 不会对数据进行换行处理;

System.out.println(); 自动换行,不需要占位符 \n ;

System.out.printf(); 与C语言格式化输出使用方法几乎一致,采用占位符

输入:使用 Scanner 类创建引用(如 Scanner scanner = new Scanner(System.in);),通过 scanner.nextXxx() 读取键盘上输入的数据,使用时需要导入相应的包java.util.Scanner。

读取整数是 nextInt(); 读取浮点数是 nextFloat(); ......

读取字符串有两种方式:next(); nextLine();

区别:
next()遇到空格停止输出;
nextline()遇到空格不会结束输出,推荐使用

同时读取整型、字符串和浮点数:

java 复制代码
import java.util.Scanner;

public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);

        System.out.println("输入一个整型:");
        int i = scan.nextInt();
        System.out.println(i); // 如果输入12,再按回车,输出整型时正常输出12,但输出字符串时显示空的,因为"回车"即使是空字符也被当成字符

        System.out.println("输入一串字符:");
        String str = scan.nextLine();
        System.out.println(str);

        System.out.println("输入一个浮点型:");
        float f = scan.nextFloat();
        System.out.println(f);
}
java 复制代码
输入一个整型:
12
12
输入一串字符:

输入一个浮点型:
4.5
4.5

输出结果显示 还没等我们输入字符串,就显示"输入一个浮点数"的提示,说明 Scanner 读取了"回车"作为我们输入的字符。

若要调整代码,只需要单独写一行来读取输入整数之后的"回车":

java 复制代码
public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);

        System.out.println("输入一个整型:");
        int i = scan.nextInt();
        System.out.println(i);
  
        scan.nextLine(); // 读取输入整型之后的"回车"

        System.out.println("输入一串字符:");
        String str = scan.nextLine();
        System.out.println(str);

        System.out.println("输入一个浮点型:");
        float f = scan.nextFloat();
        System.out.println(f);
    }
java 复制代码
输入一个整型:
66
66
输入一串字符:
oha na
oha na
输入一个浮点型:
6.6
6.6
相关推荐
能工智人小辰1 分钟前
二刷 黑马点评 秒杀优化
java·开发语言
杨小扩2 分钟前
夯实基础:配置Java开发环境JDK与构建工具Maven
java·开发语言·maven
大飞pkz3 分钟前
【Lua】闭包可能会导致的变量问题
开发语言·lua
大飞pkz6 分钟前
【Lua】题目小练2
开发语言·lua·游戏开发·lua题目
智者知已应修善业18 分钟前
2021-07-21 VB窗体求范围质数(Excel复制工作簿)
经验分享·笔记·算法
云和数据.ChenGuang24 分钟前
bash-completion未安装或未启用
开发语言·bash
开开心心_Every30 分钟前
免费PDF文件格式转换工具
java·智能手机·pdf·word·batch·java-zookeeper
Kiri霧38 分钟前
Kotlin集合分组
android·java·前端·kotlin
C++chaofan1 小时前
45. 跳跃游戏 II
java·开发语言·数据结构·算法·leetcode·游戏·职场和发展
Ciderw1 小时前
leetcode15.三数之和题解:逻辑清晰带你分析
开发语言·c++·笔记·学习·leetcode