这些编程语言中的小细节你get到了吗?(java二维数组与c二维数组的不同、动态数组、Scanner)
目录
一、关于Scanner
二、C++动态数组(new)
三、C动态数组(malloc)
四、对于二维数组,java和c的区别
c
java
🌻三种定义方式
🌻总结反思
关于Scanner
Scanner类的nextInt() nextLine() next()方法是以不同的标识作为结束符的
nextInt() 和 next()是以空格作为结束符
nextLine() 是以\n 换行符作为结束符
当我们在使用 nextInt() 或者 next()我们一般是输入内容后 回车 结束,,,这个时候我们接受到的内容是空格之前的;
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();// }// } }}
正确的位置
C++动态数组(new)
#include 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#include//要使用malloc是要包含此头文件#include //要使用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
C语言定义二维数组
C语言在定义二维数组的时候,可以省略行数,但不能省略列数。
下面看代码示例
#include 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/C++却不可以这样,除非加const)
二维数组的三种定义方式
方式一所对应的内存图
所对应的内存图:
方式三所对应内存图片与方式二相似:数组中不同行的数组大小可以是不同的
总结反思
在Java中,数组都是引用实体变量,呈树型结构,每一个叶子节点之间毫无关系,只有引用关系,每一个引用变量只引用一个实体。
java中二维数组表示
这就是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就是列数