这些编程语言中的小细节你get到了吗?(java二维数组与c二维数组的不同、动态数组、Scanner)

简介: 这些编程语言中的小细节你get到了吗?(java二维数组与c二维数组的不同、动态数组、Scanner)

关于Scanner

Scanner类的nextInt() nextLine() next()方法是以不同的标识作为结束符的

nextInt() 和 next()是以空格或回车作为结束符

c0dd3b638d8b47cd96dd3c81356b7673.png所以说当我们在使用 nextInt() 或者 next()我们每次接受到的内容是空格之前的;

 

nextLine() 是以\n 换行符作为结束符

03bd015aea724143921fbef335306c1d.png

解释一下


所有从键盘输入的数据,不管是字符还是数字,都是先存储在内存中的一个缓冲区里面,叫做键盘缓冲区,简称 输入缓冲区 或者 输入流 。Scanner是一个扫描器,它会去缓冲区中进行扫描并读入数据的。这个扫描器在扫描过程中判断停止的依据就是“空白符”(也称白字符,类似于空格,回车什么的都算做是空白符)。


nextInt()方法根据空白符(回车,空格等)只取出输入的流中分割的第一部分并解析成Int,然后把后面的字节传递下去(继续留在在缓冲区中)。

📝比如我们输入23\nHello world\n后,nextInt()只是把23从缓冲区取出来了,\nHello world仍然留在缓冲区里,那么我们在nextInt()后又用了一个nextline(),nextline()只会接收到\n,并不会接收到我们所期待的Hello world\n  

🤔怎么解决呢?

在每一个nextInt(),next(),nextDouble(),nextFloat()后都加一个nextLine()语句,将它们的结束换行符过滤。

Scanner的使用(反面案例)

import java.util.Scanner;
public class Main {
    public static boolean prime(int n) {
        if (n < 2) return false;
        for (int i = 2; i <= n / i; ++i) {
            if (n % i == 0) return false;
        }
        return true;
    }
    public static void print(int[][] ret) {
        for (int i = 0; i < ret.length; ++i) {
            for (int j = 0; j < ret[i].length; ++j) {
                if (prime(ret[i][j])) System.out.print(ret[i][j] + " ");
            }
            System.out.println();
        }
    }
    public static void main(String[] args) {
        int[][] a = new int[3][3];
        for (int i = 0; i < 3; ++i) {
            for (int j = 0; j < 3; ++j) {
                Scanner scanner = new Scanner(System.in); // 一定要注意scanner的位置,如果放在了for循环里面,你每次只能输入一个数
                // 因为你 的每次更新都把当前的输入流给更新了,即使你之前的输入流里还有数据
                // 比如你输入了 3 4 5 + 回车————那吗只会读取3,下次也不会接着读取4,(还要你接着输入)因为当前是输入流被重新定义更新了
//                while (scanner.hasNextInt()) {
                    a[i][j] = scanner.nextInt();
//                }
            }
        }
        print(a);
//        Scanner sc = new Scanner(System.in);
//        for (int i = 0; i < 3; ++i) {
//            for (int j = 0; j < 3; ++j) {
//                a[i][j] = sc.nextInt();
//            }
//        }
    }
}

正确的位置

image.png

C++动态数组(new)

#include<iostream> 
int main()
{
  int n;
  int *a;
  scanf("%d", &n);
  a= new int[n];                       //动态申请空间
  for(int i = 0; i < n; i++)           //使用
  {
    a[i] = i + 1;
  }
    delete[] a; // 释放空间
}

C动态数组(malloc)

一维数组

#include<stdio.h>
#include<stdlib.h>//要使用malloc是要包含此头文件
#include <memory.h>//要使用memset是要包含此头文件
int main()
{
    int m;
    scanf("%d", &m);//scanf只是遇到回车符的时候结束,并没有把回车符输入,因此输入流中还有一个回车符
    getchar();//把输入流中的回车符读走
    int *p;
    p = (int*)malloc(m*(sizeof(int)));//动态申请内存
    memset(p, 0, m);//初始化,每个元素都为零
    int i;
    for (i=0;i<m; i++)//数组赋值
    {
        p[i] = i;
    }
        for (i = 0; i <m; i++)//打印数组
        {
            printf("%d,", p[i]);
        }
    free(p);//释放内存
    getchar();//让程序停顿,好看到输出
    return 0;
}

二维数组

int **myMalloc(int r, int c, int* returnSize, int** returnColumnSizes) {
    int i;
    int **ret = (int **)malloc( sizeof(int *) * r );        // (1)
    *returnColumnSizes = (int *)malloc( sizeof(int) * r );  // (2)
    *returnSize = r;                                        // (3)
    for(i = 0; i < r; ++i) {
        ret[i] = (int *)malloc( sizeof(int) * c );          // (4)
        (*returnColumnSizes)[i] = c;                        // (5)
    }    
    return ret;
}

对于二维数组,java和c的区别

c

75d20b73a16f422188b2b798219a05d4.png

C语言定义二维数组

C语言在定义二维数组的时候,可以省略行数,但不能省略列数。

下面看代码示例

#include <stdio.h>
int main (void){
    int a[][3]={{1,2,3},{4,5,6},{7,8,9}};
    //int a[3][]={{1,2,3},{4,5,6},{7,8,9}};
}

在编译器中运行,前者可以通过,后者报错。


这主要是因为C语言关于二维数组的定义。C语言中二维数组的每个元素都是相同大小的一维数组。所以只要确定了列数,再根据定义的时候用到的行数,就可以给数组元素所在的内存。但如果在定义的时候没有说明列数,就会导致内存出错。因为在内存访问时候要用到列数

java

在 Java 中二维数组被看作数组的数组,即二维数组为一个特殊的一维数组,其每个元素又是一个一维数组。Java 并不直接支持二维数组,但是允许定义数组元素是一维数组的一维数组,以达到同样的效果。声明二维数组的语法如下:

type[][] arrayName;    // 数据类型[][] 数组名;

其中,type 表示二维数组的类型,arrayName 表示数组名称,第一个中括号表示行,第二个中括号表示列。

java其下每个数组是独立的,可以独立分配内存大小,C语言的数组每一维的内存大小都一样,但java允许每一维的大小不同。


(顺便提一下,Java中数组长度可以是变量,而C却不可以这样,除非加const或者用malloc动态分配内存)

补充一点,上面说的情况是c90的标准下。在c99的标准下c定义的数组长度可以是变量


c3ad3e98d7bd44daacd5336c91536622.png

二维数组的三种定义方式

20151024215550639.png

方式一所对应的内存图

dabbaa35436f4a5c8ee1179114faea35.png

20151024215739194.png

所对应的内存图:

20151024215802615.png

20151024215839121.png

方式三所对应内存图片与方式二相似:数组中不同行的数组大小可以是不同的

总结反思

在Java中,数组都是引用实体变量,呈树型结构,每一个叶子节点之间毫无关系,只有引用关系,每一个引用变量只引用一个实体。

20190407233823656.png


java中二维数组表示

654f9c3167264ee0ad2eabe3eb67742c.png

这就是Java中的二维数组在内存中的状态,这里用到了降维的思想,将二维数组降到了一维的状态下去处理,在定义二维数组时用到了两块内存栈和堆,栈里主要是放数组名,而堆里就是用来存放具体的数据,从图里我们可以看出,数组名指向堆内存里的元素,而里面的元素被分成了一维数组拼起来的状态,实际上就是二维数组


Java中如果要想查第i行的元素个数就直接访问数组的第i个数据如:b[i].length。如果想要查行数就直接访问数组名如:b.length。


现在再来看看Java中的二维数组定义的代码:

int[][] arr=new int[5][];


这里要说的是那个中括号里的“5”字不能省略,也不是说必须填“5”,而是那个中括号不能空,必须要填一个数字。因为从图上可以看出如果那个中括号为空的话,数组名所指的 内存就找不到了,所以就不能给数组分配空间了,当然还有一个方法就是定义时直接赋初值那个“5”就可以不要了。                                                                        

         

要注意一点:java中的数组自带length属性,例如:假设有个二维数组a[][]

a.length就是行数,a[0].length就是列数

相关文章
|
1月前
|
分布式计算 安全 Java
Java帝国的无限魅力:揭秘这门万能编程语言如何征服科技世界,从Web到太空探索,Java的触角无处不在!
【8月更文挑战第12天】随着信息技术的发展,编程语言成为科技核心。Java以其成熟与广泛应用,在众多语言中脱颖而出。它支持跨平台运行,实现“一次编写,处处运行”。Java的面向对象特性促进代码复用与维护,内置的安全机制保障系统安全。Java应用于Web开发、大数据处理、移动应用等多个领域,展现了其不可替代的价值。
29 1
|
30天前
|
安全 Java 数据库连接
|
2月前
|
Java 编译器 开发者
Java演进问题之Truffle处理不同编程语言的源代码或中间格式如何解决
Java演进问题之Truffle处理不同编程语言的源代码或中间格式如何解决
|
2月前
|
Java 数据库连接 Apache
java编程语言常用框架有哪些?
Java作为一种广泛使用的编程语言,拥有众多常用框架,这些框架帮助开发者提高开发效率和代码质量。
44 3
|
3月前
|
存储 安全 Java
Java集合类是Java编程语言中用于存储和操作一组对象的工具
【6月更文挑战第19天】Java集合类,如`List`、`Set`、`Map`在`java.util`包中,提供高级数据结构。常用实现包括`ArrayList`(快速随机访问)、`LinkedList`(高效插入删除)、`HashSet`(无序不重复)、`TreeSet`(排序)、`HashMap`(键值对)和`TreeMap`(排序映射)。集合动态调整大小,支持对象引用,部分保证顺序。选择合适集合优化性能和数据组织。
23 1
|
3月前
|
IDE Oracle Java
Java 是一种跨平台的编程语言,可以在各种操作系统上运行。
Java 是一种跨平台的编程语言,可以在各种操作系统上运行。
|
3月前
|
Java 开发工具 开发者
【编程语言】Python平台化为何比Java差?
【编程语言】Python平台化为何比Java差?
35 1
|
2月前
|
Java 数据库连接 开发者
Java作为一门广泛应用的编程语言
【7月更文挑战第2天】Java作为一门广泛应用的编程语言
19 0
|
3月前
|
Java
Java编程语言的基本语法
Java编程语言的基本语法
37 0
|
3月前
|
Java
二维数组与稀疏数组转换(java)
二维数组与稀疏数组转换(java)