数组_数组指针 - CSDN
数组 订阅
数组(Array)是有序的元素序列。 [1]  若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按有序的形式组织起来的一种形式。 [1]  这些有序排列的同类数据元素的集合称为数组。数组是用于储存多个相同类型数据的集合。 展开全文
数组(Array)是有序的元素序列。 [1]  若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按有序的形式组织起来的一种形式。 [1]  这些有序排列的同类数据元素的集合称为数组。数组是用于储存多个相同类型数据的集合。
信息
定    义
同类数据元素的集合
分    类
一维、二维(矩阵)、三维数组
中文名
数组
外文名
Array
数组产生来源
在C语言中, 数组 [2]  属于构造数据类型。一个数组可以分解为多个数组元素,这些数组元素可以是基本数据类型或是构造类型。因此按数组元素的类型不同,数组又可分为数值数组、字符数组、指针数组、结构数组等各种类别。关于可变长数组(VLA)的问题:原来的C89标准中是不允许可变长数组出现的,但是在C99标准中,加入了对VLA的支持 [3]  ,但是支持的编译器不多,而且由于栈溢出的安全问题,没有太多的人敢用这个可变长数组,所以在C11标准中又把它规定为可选实现的功能了 [4]  。如果有过用其它语言编程的经历,那么想必会熟悉数组的概念。由于有了数组,可以用相同名字引用一系列变量,并用数字(索引)来识别它们。在许多场合,使用数组可以缩短和简化程序,因为可以利用索引值设计一个循环,高效处理多种情况。数组有上界和下界,数组的元素在上下界内是连续的。因为 Visual Basic对每一个索引值都分配空间,所以不要不切实际声明一个太大的数组。此处数组是程序中声明的变量数组。它们不同于控件数组,控件数组是在设计时通过设置控件的 Index 属性规定的。变量数组总是连续的;与控件数组不同的是,不能从一个数组的中部加载或卸载数组元素。一个数组中的所有元素具有相同的数据类型(在C、C++、Java、pascal中都这样。但也并非所有涉及数组的地方都这样,比如在Visual Foxpro中的数组就并没这样的要求)。当然,当数据类型为 Variant 时,各个元素能够包含不同种类的数据(对象、字符串、数值等等)。可以声明任何基本数据类型的数组,包括用户自定义类型和对象变量。如果要用户输入的是一个数组,一般是用一个循环,但是在输入前也需要固定数组的大小。compact跟变长数组没有太大的关系,也应该用不到变长数组。因为一般的传数组到函数中就是传数组的地址和元素的个数的,那只是一个提示,不是要求。原型可以这样写(假设数组的元素是type):数组类型说明 在C语言中使用数组必须先进行类型说明。数组说明的一般形式为:类型说明符 数组名 [常量表达式],……; 其中,类型说明符是任一种基本数据类型或构造数据类型。数组名是用户定义的数组标识符。方括号中的常量表达式表示数据元素的个数,也称为数组的长度。数组就是一次性定义相同数据类型的一组变量数组定义。说明整型数组a,有10个元素。若要表示第10个元素,则使用a[9]。第一个则是a[0]。说明实型数组b,有10个元素,实型数组c,有20个元素。说明字符数组ch,有20个元素。1.数组是相同数据类型的元素的集合。2.数组中的各元素的存储是有先后顺序的,它们在内存中按照这个先后顺序连续存放在一起。3.数组元素用整个数组的名字和它自己在数组中的顺序位置来表示。例如,a[0]表示名字为a的数组中的第一个元素,a[1]代表数组a的第二个元素,以此类推。对于VB的数组,表示数组元素时应注意:1下标要紧跟在数组名后,而且用圆括号括起来(不能用其他括号)。2下标可以是常量,变量,或表达式,但其值必须是整数(如果是小数将四舍五入为整数)。3下标必须为一段连续的整数,其最小值成为下界,其最大值成为上界。不加说明时下界值默认为1。
收起全文
精华内容
参与话题
  • 数组

    千次阅读 多人点赞 2018-07-31 19:28:41
     数组也是一种引用类型, 2、名称:数组名称不是固定的,与存放的数据的类型有关。 数组中只能存一种类型的数据  如: 存放一组int类型的数据,  数组名称 int[]    存放一组字符串数据  数组名称 String[] ...

    1、概念:一组相同类型的数据的组合
             数组也是一种引用类型,
    2、名称:数组名称不是固定的,与存放的数据的类型有关。

    数组中只能存一种类型的数据
             如:  存放一组int类型的数据,
              数组名称   int[]
           
              存放一组字符串数据
              数组名称   String[]

              存放一组Scanner类型的数据
              数组名称   Scanner[]

              存放一组字符类型的数据
              数组名称   char[]
    3、元素的概念:
          数组中的每个数据,都是这个数值的元素。
    4、数组的声明与初始化
         声明:元素类型[]  变量名;
               元素类型   变量名[];--不建议此写法
         变量的初始化的时机:2种
           (1)声明时直接初始化
           (2)先声明,再初始化(使用前初始化)
         数组的变量初始化:3种情况
               (1)静态初始化
              String[] names = {"A","B"};
              int[] nums = {};

          
           (2)动态初始化
              --规定数组长度的写法
                int[] ages = new int[length];

            
            其实有默认元素:
            整数类型:默认是0
            浮点数类型:默认0.0
            字符类型:默认'\u0000'
            布尔类型:默认false
            引用数据类型:默认值null


              --不规定长度的写法
            int[] ages = new int[]{};
            double[] counts = new double[]{1.2,3.14};

          

    5、数组的长度:
         即数组元素的个数
         表示方式:变量名.length;
    6、数组的下标(index):
          下标从0开始,最后一个元素的下标为:length-1;
          下标范围:0~length-1
    7、数组元素的访问(查看):
          通过下标进行查看
          语法:变量名[index];

          
       元素的遍历(从头到尾依次查看)
       for(int i=0;i<变量名.length;i++){
        System.out.println(变量命[i]);
       }
    8、数组元素的覆盖(赋值,替换)
          
          语法:变量名[index] = value;

    9、数组间的赋值

    数组间的变量赋值:
                通过一个变量对数组的元素进行修改,
                那么与之相关的变量对应的数组的元素
                也会发生变化。
                如:
                   int[] a = {1,2,3};
                   int[] b = a;
                   通过b修改元素,a对应的数组也跟着改变

                   数组是引用数据类型,在变量中村的是地址。

                 
    10、数组下标越界异常:
        java.lang.ArrayIndexOutOfBoundsException

        出现的原因:
            访问数组元素时的下标超出了范围[0~length-1],属于运行时异常,

            数组下标越界异常,编译器检查不出来此异常
            运行时才会出现,出现的结果造成了程序的中断结束。
        正确范围:0~length-1
        错误下标:
               变量名[-1]
               变量名[length]
    11、引用类型之Arrays
        是数组的工具类。此类提供了很多对数组操作的功能方法
        如:

    在使用工具类时,一定要先到包。不然会出现错误
        String info = Arrays.toString(数组名);
        Arrays.toString():此方法是将数组的元素
        一一拼接成字符串.(一定要是数组)

       
        格式如下:
           "[元素1,元素2,.....元素length-1]"

    12、数组的复制
         数组的特点:一经创建,长度不可变。

         系统复制法:
           System.arraycopy(src,start1,des,start2,length);
           src:源数组,即被复制的数组名
           start1:源数组复制的开始下标
           des:目标数组,即复制到的数组名
           start2:目标数组复制的开始下标
           length:复制的长度

            int[] nums = {99,100,98,99,100};
            int[] num1 = new int[nums.length];//{0,0,0,0,0}
            System.arraycopy(nums,0,num1,0,nums.length);
            System.out.println("num1:"+Arrays.toString(num1));

         工具类提供的复制方法:
          元素类型[] 变量名=Arrays.copyOf(src,newLength);
          src:源数组
          newLength:新数组的长度

         功能解释:从src的下标为0的元素开始复制
                   复制到长度为newLength的新数组中
               新数组存放元素的开始位置为0

    (可以对复制的数组进行扩容何人缩容)

          数组的练习:  

            /* 定义一个字符串数组names,
               存储10个学生的姓名*/
            String[] names = new String[10];
            for(int i=0;i<names.length;i++){
                names[i] = "小"+(char)(i+65);
            }
            for(int i=0;i<names.length;i++){
                System.out.print(names[i]+" ");
            }
            /* 定义一个int数组scores,用于存储这10个学生的
               成绩,成绩使用随机数 [90,100]   
                计算成绩的平均值
                找到成绩的最大值,并输出其姓名
                找到成绩的最小值,并输出其姓名
               */
            System.out.println();
            int[] scores = new int[names.length];
            for(int i=0;i<scores.length;i++){
                scores[i] = (int)(Math.random()*11+90);
            }
            for(int i=0;i<scores.length;i++){
                System.out.print(scores[i]+" ");
            }
            /* 计算平均值:*/
            int sum = 0;
            for(int i=0;i<scores.length;i++){
                sum+=scores[i];
            }
            double avg_score = sum*1.0/scores.length;
            System.out.println("平均成绩为:"+avg_score);
            /* 找最大值 */
            int max = -1;//用于存入最大值
            int min = 101;//用于存储最小值
            for(int i=0;i<scores.length;i++){
                if(max<scores[i]){
                    max = scores[i];//将较大值的成绩存入max
                }
                if(min>scores[i]){
                    min = scores[i];//将较小值的成绩存入min
                }
            }
            System.out.println("最高成绩:"+max);
            System.out.println("最低成绩:"+min);

         /*
            需要知道最高成绩的下标,才能知道人名
            而最高成绩的下标可能有多个。需要保存
            到一个新数组里

            最低成绩同上。    
            */
            int h_count = 0;
            int l_count = 0;
            for(int i=0;i<scores.length;i++){
                if(max==scores[i]){
                    h_count++;//统计最高成绩的个数
                }
                if(min==scores[i]){
                    l_count++;//统计最低成绩的个数
                }
            }
            /*
               将最高/最低成绩的下标:
               存入新数组中
            */
            
            int[] max_indexs = new int[h_count];//用来存储最高成绩的多个下标
            int max_count=0;//用来下标的自增
            
            int[] min_indexs = new int[l_count];//用来存储最低成绩的多个下标
            int min_count=0;//用来下标的自增

            for(int i=0;i<scores.length;i++){
                if(scores[i]==max){
                    max_indexs[max_count] = i;//找到最大值的下标,并存入新数组
                    max_count++;//为下一次存储做准备
                }
                if(scores[i]==min){
                    min_indexs[min_count++] = i;
                }
            }
            /*输出 最高成绩的姓名和分数       
              从存储下标的数组中,取出值,此值是
              names数组的下标
            
            */
            for(int i=0;i<max_indexs.length;i++){
                int v = max_indexs[i];
                System.out.println(names[v]+":"+scores[v]);
            }

            /*输出 最低成绩的姓名和分数*/
            for(int i=0;i<min_indexs.length;i++){
                int v = min_indexs[i];//
                System.out.println(names[v]+":"+min);
            }

       }

    二维数组:

    概念:数组的元素依然是数组
          int[] a = {1,2,3,4}
           int[][] b={{1,2},{2,3,4,5,6},{1,2,3}}
    访问: b[0]-->{1,2}
               b[1]-->{2,3,4,5,6}
               b[2]-->{1,2,3}

           b[0][0] -->1
           b[0][1] -->2
           .....
           b[1][3] -->5
           b[1][4] -->6
           ...
           b[2][1] -->2
           x={
              {1,2,3},
              {1,2,3},
          {4,5,6}
             }

           x数组的元素:都是等长的数组,类似于矩阵。

           y ={
           {1,2},
           {1,2,3},
           {1}
              }
           y数组的元素:不是等长的数组。

    二维数组的初始化:
      静态初始化
          如:int[][] a = {{1},{1,2},{2,3,4}};

         
      动态初始化:
          (1)等长式初始化
              int[][] a = new int[3][2];

            
          表示a有三个元素,每个元素都是2个长度的数组。
          (2)只规定高维数组的长度
              int[][] a = new int[3][];
          表示a有三个元素,但是都是null.
          null在使用时,需要新建数组对象(长度任意)

            int[][] c = new int[3][];
            //输出c的第一个元素
            System.out.println(c[0]);//null  数组只有长度没有元素{}
            c[0] = new int[2];//将null替换成数组对象,如果是以上初始化方法,一定要有这一步
            System.out.println(Arrays.toString(c[0]));
            c[0][0] = 1;
            c[0][1] = 2;
            System.out.println(c[0]);
            System.out.println(Arrays.toString(c[0]));

    二维数组的练习

           /*录入5个学生的数学,语文,英语三科成绩
              计算每科的平均成绩与每人的平均成绩
              并找出每科成绩的最高分与最低分。
            */

            //以学生为主体,录入每个学生的3科,此处也可以以科目为主题,录入每个学生,

            //数组定义变为 int[3][5]
            int[][] scores = new int[5][3];
            Scanner sc = new Scanner(System.in);
            for(int i=0;i<scores.length;i++){

            //分别录入每个学生三科成绩
                System.out.println("录入第"+(i+1)+"个学生的成绩");
                for(int j=0;j<scores[i].length;j++){
                    scores[i][j]=sc.nextInt();    
                }
            }
            /*查看 每个学生的成绩*/
            for(int i=0;i<scores.length;i++){
                System.out.println("学生"+(i+1)+":"+Arrays.toString(scores[i]));
            }
            /*计算每个学生的总成绩和平均成绩
                int sum = 0;
                sum+=scores[0][0];
                sum+=scores[0][1];
                sum+=scores[0][2];
                sum/3.0;

                int sum = 0;
                sum+=scores[1][0];
                sum+=scores[1][1];
                sum+=scores[1][2];
                sum/3.0;

                .....
            */
            for(int i=0;i<scores.length;i++){
                int sum = 0;
                for(int j=0;j<scores[i].length;j++){
                    sum+=scores[i][j];
                }
                System.out.println("学生"+(i+1)+"的总成绩:"+sum+",平均成绩:"+(int)((sum/3.0)*100)/100.0);
            }
            /*
                计算每科的总成绩和平均成绩
                int total_sum = 0;
                total_sum+=scores[0][0];
                total_sum+=scores[1][0];
                total_sum+=scores[2][0];
                total_sum+=scores[3][0];
                total_sum+=scores[4][0];
                total_sum+=scores[5][0];
                .....
                total_sum/10.0

                int total_sum = 0;
                total_sum+=scores[0][1];
                total_sum+=scores[1][1];
                total_sum+=scores[2][1];
                total_sum+=scores[3][1];
                total_sum+=scores[4][1];
                total_sum+=scores[5][1];
                .....
                total_sum/10.0

                int total_sum = 0;
                total_sum+=scores[0][2];
                total_sum+=scores[1][2];
                total_sum+=scores[2][2];
                total_sum+=scores[3][2];
                total_sum+=scores[4][2];
                total_sum+=scores[5][2];
                .....
                total_sum/10.0
            
            */
            /*
              顺便统计每科的最高分与最低分
            */
            for(int i=0;i<scores[0].length;i++){
                int total_sum = 0;
                int max = -1;
                int min = 101;
                for(int j=0;j<scores.length;j++){
                    total_sum+=scores[j][i];

                    if(max<scores[j][i]){
                        max = scores[j][i];
                    }
                    if(min>scores[j][i]){
                        min = scores[j][i];
                    }
                }
                System.out.println("学科"+(i+1)+"的总成绩:"+total_sum+",平均成绩:"+total_sum/10.0+",最高分:"+max+",最低分:"+min);
            }
        }

    引用类型数组:
        基本数据类型数组,元素是基本类型的数据
        引用数据类型数组,元素是对象
        初始化的方式
            静态初始化:
                元素类型[] 变量名 = {}
            动态初始化
                规定长度
                    元素类型[] 变量名 = new 元素类型[]
                不规定长度:
                    元素类型[] 变量名 = new 元素类型[]{}
    引用数据类型的数组使用规定长度的方式进行初始化
    默认值是null;存入元素时,需要新建对象存入;
    如:
        Cell[] cs = new Cell[10];
        cs里有地址,数组对象的地址,此对象里有10个null
        第一个元素存储(0,3)的方格
        cs[0]= new Cell(0,3)
        第一个元素存储(0,4)的方格
        cs[1]= new Cell(0,4)
    引用类型的数组内,存储的是元素对象的地址信息

    展开全文
  • C语言中数组的总结

    万次阅读 多人点赞 2020-03-12 21:59:00
    目录 一维数组的创建和初始化 一维数组的使用 一维数组在内存中的存储 ...数组的创建:在创建数组时,我们必须定义数组的类型和大小,数组的大小不能为0,数组中的元素类型都是相同的。 eg: int arr

    #目录 #

    1. 一维数组的创建和初始化
    2. 一维数组的使用
    3. 一维数组在内存中的存储
    4. 指针的初步介绍
    5. 一维数组的指针访问
    6. 二维数组的创建和初始化
    7. 二维数组的使用
    8. 二维数组在内存中的存储
    9. 二维数组的指针访问
    10. 有关数组的运算
    11. 数组作为函数参数

    1.一维数组的创建和初始化

    数组的创建:在创建数组时,我们必须定义数组的类型和大小,数组的大小不能为0,数组中的元素类型都是相同的。
    eg:

    int arr[10];//[]内必须是常量/常量表达式(3+8),不能是一个变量(x...)
    

    数组的初始化:在数组创建时,我们也要必须为数组初始化。
    eg:

    int arr1[3] = {1, 2, 3};
    int arr2[] = {1, 2, 3};//在这里,我们arr[3]里边的数字可以不用写;
    int arr3[3] = {1, 2};//也是可以的,只是把最后一个数初始化为0了而已
    int arr4[3] = {1, 2, 3, 4};//是不可以的,不能超过数组长度  
    char arr5[3] = {'a', 98, 'c'};//因为是字符类型,所以98其实就是字符'b'
    char arr6[] = "abcdef";
    
    #include<stdio.h>
    
    int main()
    {
    	char arr1[] = { 'a', 'b', 'c' };
    	char arr2[4] = "abc";
    	char *p = "abc";//这里只是把a的地址放进了p里边
    
    	return 0; 
    }
    

    在内存中的存储:
    在这里插入图片描述

    2.一维数组的使用

    eg:

    #include<stdio.h>
    
    int main()
    {
    	int arr[10] = { 0 };
    	int i = 0;
    	for (i = 0; i < 10; i++)//i<11是不可以的,不可以越界访问
    	{
    		arr[i] = i;
    	}
    
    	return 0; 
    }
    

    数组是使用下标来访问的,下标是从0开始。
    数组的大小可以通过计算得到。(sz = sizeof(arr)/sizeof(arr[0]));

    3.一维数组在内存中的存储

    eg:

    #include<stdio.h>
    
    int main()
    {
    	int arr[10] = { 0 };
    	int i = 0;
    	for (i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
    	{
    		printf("&arr[%d] = %p\n", i, &arr[i]);
    	}
    
    	return 0; 
    }
    
    

    这里写图片描述
    从输出结果我们可以看出数组元素在内存中的存储是:地址是由低到高并且是连续存储的。

    4. 指针的初步介绍

    指针可以理解为一个变量,是一个专门用来存放地址的一个变量。
    eg:

    int *ptr = NULL;//定义一个整型的指针变量,初始化为NULL
    char *ptr = NULL;//定义一个字符的指针变量,初始化为NULL
    

    5. 一维数组的指针访问

    eg:

    #include<stdio.h>
    
    int main()
    {
    	int arr[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    	printf("%p\n", arr);
    	printf("%d\n", *arr);
    
    	return 0; 
    }
    

    这里写图片描述

    从输出结果我们可以看出数组名其实存放的就是首元素的地址

    eg:

    int main()
    {
    	int arr[10] = { 0 };
    	int i = 0;
    	int sz = sizeof(arr) / sizeof(arr[0]);
    	int *p = arr;
    	for (i = 0; i < sz; i++)
    	{
    	    //arr[i] = i; (1)
    		*(p + i) = i; (2)
    	}
    
    	for (i = 0; i < sz; i++)
    	{
    		printf("%d\n", arr[i]);//(1)和(2)的输出结果一样
    	}
    
    	return 0; 
    }
    
    

    这里写图片描述

    从输出结果我们可以看出,我们定义了一个指针p,指向arr,然后我们通过指针来访问数组。

    6. 二维数组的创建和初始化

    eg:

    #include<stdio.h>
    
    int main()
    {
    	int arr[3][4] = { 1, 2, 3, 4, 5, 6 };
    	//int arr[][4] = {{1, 2},{3, 4, 5},{6}};可以
    	//arr[3][] = {{1, 2},{3, 4, 5},{6}};是不可以的
    
    	return 0; 
    }
    

    这里写图片描述

    从监视窗口我们可以看到,一行有四个元素,总共有三行,当后边元素没有初始化的时候,全默认为0。

    7. 二维数组的使用

    二维数组的使用也是通过下标方式
    eg:

    #include<stdio.h>
    
    int main()
    {
    	int arr[3][5] = { 0 };
    	int i = 0;
    	int j = 0;
    	for (i = 0; i < 3; i++)
    	{
    		for (j = 0; j < 5; j++)
    		{
    			arr[i][j] = i * 5 + j + 1;
    		}
    	}
    
    	for (i = 0; i < 3; i++)
    	{
    		for (j = 0; j < 5; j++)
    		{
    			printf("%d ", arr[i][j]);
    		}
    		printf("\n");
    	}
    	
    
    	return 0; 
    }
    
    

    这里写图片描述

    8. 二维数组在内存中的存储

    我们可以通过打印它的地址来观察它是如何存储的。
    eg:

    #include<stdio.h>
    
    int main()
    {
    	int arr[3][5] = { 0 };
    	int i = 0;
    	int j = 0;
    	for (i = 0; i < 3; i++)
    	{
    		for (j = 0; j < 5; j++)
    		{
    			printf("&arr[%d][%d] = %p\n", i, j, &arr[i]);
    		}
    	}
    
    	
    	return 0; 
    }
    

    这里写图片描述

    我们可以看出数组元素的地址是连续的,并没有进行换行,我们只是把它假想成了三行。

    9. 二维数组的指针访问

    我们知道了一维数组的内存存储模式之后,我们尝试使用指针对一维数组进行访问,那在这里,我们尝试使用指针来访问我们的二维数组。
    eg:

    
    #include<stdio.h>
    
    int main()
    {
    	int arr[3][5] = { 0 };
    	int *p = &arr[0][0];
    	int i = 0;
    	int j = 0;
    	for (i = 0; i < 15; i++)
    	{
    		*(p + i) = i + 1;
    	}
    	for (i = 0; i < 3; i++)
    	{
    		for (j = 0; j < 5; j++)
    		{
    			printf("%d ", arr[i][j]);
    		}
    	}
    
    	return 0;
    }
    
    

    指针也存在类型:
    eg:

    #include<stdio.h>
    
    int main()
    {
    	int num = 0x11223344;
    	int *p = &num;
    	*p = 0;
    
    	return 0;
    }
    

    这里写图片描述
    这里的指针p是int型,所以我们对它的改变,是改变4个字节的大小,同样的,如果我们对p进行加1操作,指针向后跳4个字节。
    eg:

    #include<stdio.h>
    
    int main()
    {
    	int num = 0x11223344;
    	//int *p = &num;
    	//*p = 0;
    	char *pc = &num;
    	*pc = 0;
    
    	return 0;
    }
    

    这里写图片描述
    我们可以从内存中观察到,只改变了1个字节的大小,因为pc指针的类型是char。如果我们对pc进行加1操作,指针向后跳1个字节。
    eg:

    #include<stdio.h>
    
    int main()
    {
    	int arr[10] = { 0 };
    	printf("%p\n", &arr[0]);
    	printf("%p\n", &arr[0] + 1);
    	printf("---------------\n");
    	printf("%p\n", arr);
    	printf("%p\n", arr + 1);
    	printf("---------------\n");
    	printf("%p\n", &arr);
    	printf("%p\n", &arr + 1);
    
    	return 0;
    }
    

    这里写图片描述
    我们可以从输出结果看出&arr[0],arr,&arr它们的地址虽然相同,但它们的意义是不同的,&arr,取的是数组的地址,对它进行加1,就相当于跳过整个数组,又因为数组是int型,总共有10个元素,所以跳过的字节大小是40。

    10. 有关数组的运算##

    关于数组我们必须要学会有关数组的一些运算。
    eg:

    #include<stdio.h>
    
    int main()
    {
    	//一维数组
    	int a[] = { 1, 2, 3, 4 };
    	printf("%d\n", sizeof(a));//16  
    	//1.数组名单独放在sizeof内部,数组名表示整个数组,所以sizeof(数组名)计算的是是数组总大小,单位是字节
    	//2.&数组名,数组名表示整个数组,所以&数组名取出的是整个数组的地址
    	//3.除此之外,所有的数组名都表示首元素的地址
    	printf("%d\n", sizeof(a + 0));//4    a代表首元素地址,a+i代表第i个元素的地址,在32位平台下所有的地址的大小都是4个字节
    	printf("%d\n", sizeof(*a));//4       a是首元素地址,*a是首元素--1,int型占4个字节大小
    	printf("%d\n", sizeof(a + 1));//4    a是首元素地址,a+1是第二个元素的地址,它还是一个地址
    	printf("%d\n", sizeof(a[1]));//4     a[1]--第二个元素
    	printf("%d\n", sizeof(&a));//4       &a虽然取出的是整个数组的地址,但它还是一个地址
    	printf("%d\n", sizeof(*&a));//16     &a取出的是整个数组的地址,对它进行解引用,就是这个数组,这个数字的大小就是16
    	printf("%d\n", sizeof(&a + 1));//4   &a取出的是整个数组的地址,加1跳过了整个数组(16个字节),但它还是一个地址
    	printf("%d\n", sizeof(&a[0]));//4    &a[0]取的是第一个元素的地址
    	printf("%d\n", sizeof(&a[0] + 1));//4   &a[0] + 1取的是第二个元素的地址
    
    	return 0;
    }
    

    这里写图片描述

    #include<stdio.h>
    
    int main()
    {
    	//字符数组
    	char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
    	printf("%d\n", sizeof(arr));//6
    	printf("%d\n", sizeof(arr + 0));//4        首元素地址
    	printf("%d\n", sizeof(*arr));//1           首元素地址解引用是首元素(a),char类型占1个字节
    	printf("%d\n", sizeof(arr[1]));//1         首元素
    	printf("%d\n", sizeof(&arr));//4           数组的地址
    	printf("%d\n", sizeof(&arr + 1));//4       下一个数组的地址,跳过了f
    	printf("%d\n", sizeof(&arr[0] + 1));//4    第二个元素的地址
    
        printf("%d\n", strlen(arr));//随机值       strlen()求的是字符串长度,以'\0'为结束标志,这里并没有'\0',所以会一直往后数
    	printf("%d\n", strlen(arr + 0));//随机值   还是从'a'开始数,但没有'\0',所以停不下来
    	printf("%d\n", strlen(*arr));//程序会崩掉  strlen()接收的是一个地址,*arr是字符'a',这里把'a'的ASCII码值(97)作为一个地址访问,这一块的地址是不能被访问的
    	printf("%d\n", strlen(arr[1]));//错误      传的是'b',和传的是'a'效果一样
    	printf("%d\n", strlen(&arr));//随机值      &arr虽然取的是数组的地址,但数组的地址和数组首元素的地址是一样的,也是从‘a'开始数,但并没有'\0'
    	printf("%d\n", strlen(&arr + 1));//随机值  但这个随机值和前边的随机值意义不同,它是把'a','b','c','d','e','f'跳过去了,从f后边开始数
    	printf("%d\n", strlen(&arr[0] +1));//随机值   这个是从'b'开始往后数的
    
    
    	return 0;
    }
    
    

    这里写图片描述

    #include<stdio.h>
    
    int main()
    {
        char arr[] = "abcdef";
    	printf("%d\n", sizeof(arr));//7   里边还有'\0',只不过我们看不到而已
    	printf("%d\n", sizeof(arr + 0));//4     arr+0---首元素地址
    	printf("%d\n", sizeof(*arr));//1   对首元素地址解引用是首元素
    	printf("%d\n", sizeof(arr[1]));//1 第二个元素
    	printf("%d\n", sizeof(&arr));//4    数组的地址也是地址
    	printf("%d\n", sizeof(&arr + 1));//4  也是一个地址,不过这个地址在'\0'后边,跳过了整个数组
    	printf("%d\n", sizeof(&arr[0] + 1));//4   从b开始的一个地址
    
    
    
    	printf("%d\n", strlen(arr));//6   strlen()以'\0'为结束标志,但不算'\0'
    	printf("%d\n", strlen(arr + 0));//6  arr+0与arr都代表首元素地址
    	printf("%d\n", strlen(*arr));//错误   这传进来的不是一个地址,而是一个字符
    	printf("%d\n", strlen(arr[1]));//错误
    	printf("%d\n", strlen(&arr));//6    数组的地址也是首元素地址,地址的位置是一样的
    	printf("%d\n", strlen(&arr + 1));//随机值   跳过了'\0',从'\0'往后数,不知道会数到哪里去
    	printf("%d\n", strlen(&arr[0] + 1));//5    从第二个元素(b)开始往后数,遇到'\0'结束
    
    
    	return 0;
    }
    
    

    这里写图片描述

    #include<stdio.h>
    
    int main()
    {
        char *p = "abcdef";
    	printf("%d\n", sizeof(p));//4   p是指针变量,里边存的是a的地址
    	printf("%d\n", sizeof(p + 1));//4   还是一个地址,不过是指向了b的地址
    	printf("%d\n", sizeof(*p));//1      对a的地址解引用就是a
    	printf("%d\n", sizeof(p[0]));//1    第一个元素(a)
    	printf("%d\n", sizeof(&p));//4      &p取的是p的地址,p是一个指针,指向a的地址,但p的地址是什么并不知道
    	printf("%d\n", sizeof(&p + 1));//4  &p+1--跳过了p的一个地址
    	printf("%d\n", sizeof(&p[0] + 1));//4   还是一个地址,这个地址指向了b的地址
    
    
        printf("%d\n", strlen(p));//6        从a开始向后数
    	printf("%d\n", strlen(p + 1));//5    从b开始向后数
    	printf("%d\n", strlen(*p));//错误    *p就是a,strlen()要的是一个地址,而不是a的ASCII码值(97)
    	printf("%d\n", strlen(p[0]));//错误
    	printf("%d\n", strlen(&p));//随机值
    	printf("%d\n", strlen(&p + 1));//随机值
    	printf("%d\n", strlen(&p[0] + 1));//5    从b开始往后数
    
    	return 0;
    }
    
    

    这里写图片描述

    #include<stdio.h>
    
    //二维数组
    int main()
    {    
    	int a[3][4] = { 0 };
    	printf("%d\n", sizeof(a));//48    整个数组有12个元素,每个元素都是int型
    	printf("%d\n", sizeof(a[0][0]));//4   代表的是第一行第一列那个元素
    	printf("%d\n", sizeof(a[0]));//16   a[0]--第一行数组名,第一行总共有4个元素
    	printf("%d\n", sizeof(a[0] + 1));//4   a[0]降级变为a[0][0]的地址,a[0]+1是a[0][1]的地址
    	printf("%d\n", sizeof(a + 1));//4    a--首元素(第一行)地址,a+1--第二行地址
    	printf("%d\n", sizeof(&a[0] + 1));//4    第二行地址
    	printf("%d\n", sizeof(*a));//16   对第一行地址解引用就是第一行元素
    	printf("%d\n", sizeof(a[3]));//16    这里有好多人会出错,认为这个数组并没有这么大,只有3行,不能访问第4行,其实这里并没有访问第4行,它只是一个类型(1行的大小)
    	return 0;
    }
    

    这里写图片描述
    11.数组作为函数参数

    我们在写代码的时候,会将数组作为参数传给函数。
    eg:

    void bubble(int arr[])
    {
        int sz = sizeof(arr)/sizeof(arr[0]);//这是错误的
        ...
    }
    

    数组作为函数参数时,不会把整个数组传递过去,实际上只是把数组的首元素地址传递过去了。

    展开全文
  • Java中数组的定义与使用(一)

    万次阅读 多人点赞 2018-12-04 21:41:35
    如果说现在要求你定义100个整型变量,那么如果按照之前的做法,可能现在定义的的结构如下: int i1, i2, i3, ... i100; 但是这儿时候如果按照此类方式定义就会非常麻烦,...

    数组的基本概念

    如果说现在要求你定义100个整型变量,那么如果按照之前的做法,可能现在定义的的结构如下:

    int i1, i2, i3, ... i100;
    

    但是这个时候如果按照此类方式定义就会非常麻烦,因为这些变量彼此之间没有任何的关联,也就是说如果现在突然再有一个要求,要求你输出这100个变量的内容,意味着你要编写System.out.println()语句100次。

    其实所谓的数组指的就是一组相关类型的变量集合,并且这些变量可以按照统一的方式进行操作。数组本身属于引用数据类型,那么既然是引用数据类型,这里面实际又会牵扯到内存分配,而数组的定义语法有如下两类。

    • 数组动态初始化:
      • 声明并开辟数组:
        • 数据类型 [] 数组名称 = new 数据类型[长度];
        • 数据类型 [] 数组名称 = new 数据类型[长度];
      • 分布进行数组空间开辟(实例化)
        | Tables | Are |
        | ------------- |:-------------?
        | 声明数组: | 数组类型 数组名称[] = null; | | | 数组类型 [] 数组名称 =null; | | 开辟数组空间: | 数组名称 =new` 数组类型[长度]; |

    那么当数组开辟空间之后,就可以采用如下的方式的操作:

    • 数组的访问通过索引完成,即:“数组名称[索引]”,但是需要注意的是,数组的索引从0开始,所以索引的范围就是0 ~ 数组长度-1,例如开辟了3个空间的数组,所以可以使用的索引是:0,1,2,如果此时访问的时候超过了数组的索引范围,会产生java.lang.ArrayIndexOutOfBoundsException 异常信息;
    • 当我们数组采用动态初始化开辟空间后,数组里面的每一个元素都是该数组对应数据类型的默认值;
    • 数组本身是一个有序的集合操作,所以对于数组的内容操作往往会采用循环的模式完成,数组是一个有限的数据集合,所以应该使用 for 循环。
    • Java 中提供有一种动态取得数组长度的方式:数组名称.length;

    范例: 定义一个int型数组

    public class ArrayDemo {
    	public static void main(String args[]) {
    		int data[] = new int[3]; /*开辟了一个长度为3的数组*/
    		data[0] = 10; // 第一个元素
    		data[1] = 20; // 第二个元素
    		data[2] = 30; // 第三个元素
    		for(int x = 0; x < data.length; x++) {
    			System.out.println(data[x]); //通过循环控制索引
    		}
    	}
    }
    

    数组本身除了声明并开辟空间之外还有另外一种开辟模式。

    范例: 采用分步的模式开辟数组空间

    public class ArrayDemo {
    	public static void main(String args[]) {
    		int data[] = null; 
    		data = new int[3]; /*开辟了一个长度为3的数组*/
    		data[0] = 10; // 第一个元素
    		data[1] = 20; // 第二个元素
    		data[2] = 30; // 第三个元素
    		for(int x = 0; x < data.length; x++) {
    			System.out.println(data[x]); //通过循环控制索引
    		}
    	}
    }
    

    但是千万要记住,数组属于引用数据类型,所以在数组使用之前一定要开辟控件(实例化),如果使用了没有开辟空间的数组,则一定会出现 NullPointerException 异常信息:

    public class ArrayDemo {
    	public static void main(String args[]) {
    		int data[] = null; 
    		System.out.println(data[x]);
    	}
    }
    

    这一原则和之前讲解的对象是完全相同的。

    数组在开发之中一定会使用,但是像上面的操作很少。在以后的实际开发之中,会更多的使用数组概念,而直接使用,99%情况下都只是做一个 for 循环输出。

    数组引用传递

    既然数组属于引用数据类型,那么也一定可以发生引用传递。在这之前首先来研究一下数组的空间开辟。

    范例: 观察一道程序

    public class ArrayDemo {
    	public static void main(String args[]) {
    		int data[] = null;
    		data = new int[3]; //开辟一个长度为3的数组
    		data[0] = 10;
    		data[1] = 20;
    		data[2] = 30;
    	}
    }
    

    新建数组变量

    那么既然说到了引用数据类型了,就一定可以发生引用传递,而现在的引用传递的本质也一定是:同一块堆内存空间可以被不同的栈内存所指向。

    范例: 定义一个程序

    public class ArrayDemo {
    	public static void main(String args[]) {
    		int data[] = null;
    		data = new int[3]; //开辟一个长度为3的数组
    		int temp[] = null; //声明对象
    		data[0] = 10;
    		data[1] = 20;
    		data[2] = 30;
    		temp = data;  //int temp[] = data;
    		temp[0] = 99;
    		for(int i = 0; i < temp.length; i++) {
    			System.out.println(data[i]);
    		}
    	}
    }
    

    这里写图片描述

    引用传递分析都是一个套路。同一块堆内存被不同的栈内存所指向。

    数组静态初始化

    在之前所进行的数组定义都有一个明显特点:数组先开辟内存空间,而后再使用索引进行内容的设置,实际上这种做法都叫做动态初始化,而如果希望数组在定义的时候可以同时出现设置内容,那么就可以采用静态初始化完成。

    数组的静态初始化一共分为以下两种类型:

    Tables Are
    简化格式: 数据类型 数组名称 = {值, 值,…}
    完整格式: 数据类型 数组名称 = new 数据类型[] {值, 值,…}

    范例: 采用静态初始化定义数组

    public class ArrayDemo {
    	public static void main(String args[]) {
    		int data[] = {1, 2, 4, 545, 11, 32, 13131, 4444};
    		for(int i = 0; i < data.length; i++) {
    			System.out.println(data[i]);
    		}
    	}
    }
    

    在开发之中,对于静态数组的初始化强烈建议使用完整语法模式,这样可以轻松地使用匿名数组这一概念。

    public class ArrayDemo {
    	public static void main(String args[]) {
    		System.out.println(new int[] {1, 2, 4, 545, 11, 32, 13131, 4444}.length);
    	}
    }
    

    以后使用静态方式定义数组的时候一定要写上完整格式。

    数组最大的缺陷:长度固定。

    二维数组

    在之前所使用的数组发现只需要一个索引就可以进行访问,那么这样的数组实际上非常像一个数据行的概念。

    索引 0 1 2 3 4 5 6 7 8
    内容 12 23 44 56 90 445 49 99 1010

    现在痛过一个索引就可以取得唯一的一个记录。所以这样的数组可以简单理解为一维数组,而二维数组本质上指的是行列集合,也如果要确定某一个数据需要行索引和列索引来进行定位。

    索引 0 1 2 3 4 5 6 7 8
    0 12 23 44 56 90 445 49 99 1010
    1 2 3 41 56 9 45 49 99 10

    如果要想确定一个数据则数据使用的结构是“数组名称[行索引][列索引]”,所以这样的结构就是一个表的结构。

    那么对二维数组的定义有两种声明形式:

    • 数组的动态初始化:数据类型 对象数组[][] = new 数据类型[行个数][列个数];
    • 数组的静态初始化:数据类型 对象数组[][] = new 数据类型[行个数][列个数]{{值, 值,…}, {值, 值,…},…};

    数组的数组就是二维数组。

    范例: 定义一个二维数组

    public class ArrayDemo {
    	public static void main(String args[]) {
    		//此时的数组并不是一个等列数组
    		int data[][] = new int[][] {
    			{1, 2, 3}, {4, 5}, {6, 7, 8, 9}};
    		//如果在进行输出的时候一定要使用双重循环,
    		//外部的循环控制输出的行数,而内部的循环控制输出列数
    		for(int i = 0; i < data.length; i++) {
    			for(int j = 0; j < data[i].length; j++) {
    				System.out.print("data[" + i + "][" + j + "]=" + data[i][j] + "、");
    			}
    			System.out.println();
    		}
    	}
    }
    

    由于输出麻烦,所以可以忽略了,在进行开发之中,出现二位数组的几率并不高。

    展开全文
  • Java数组的三种打印方式

    万次阅读 多人点赞 2019-11-27 09:50:32
    1.数组的输出的三种方式 一维数组: 定义一个数组 int[] array = {1,2,3,4,5}; (1)传统的for循环方式 for(int i=0;i<array.length;i++) { System.out.println(array[i]); } (2)for each循环 for...

    1.数组的输出的三种方式

    一维数组:

    定义一个数组   int[] array = {1,2,3,4,5};

    (1)传统的for循环方式

    for(int i=0;i<array.length;i++)
    {
          System.out.println(array[i]);
    }

     

    (2)for each循环

    for(int a:array)
        System.out.println(a);


    (3)利用Array类中的toString方法

     

    调用Array.toString(a),返回一个包含数组元素的字符串,这些元素被放置在括号内,并用逗号分开

    int[] array = {1,2,3,4,5};
    System.out.println(Arrays.toString(array));

    输出:[1, 2, 3, 4, 5]

     

    说明:System.out.println(array);这样是不行的,这样打印是的是数组的首地址。

     

    二维数组:

    对于二维数组也对应这三种方法,定义一个二维数组:

     int[][]magicSquare =
        	 {
        		 {16,3,2,13},
        		 {5,10,11,8},
        		 {9,6,7,3}
        	 };

    Java实际没有多维数组,只有一维数组,多维数组被解读为"数组的数组",例如二维数组magicSquare是包含{magicSquare[0],magicSquare[1],magicSquare[2]}三个元素的一维数组,magicSqure[0]是包含{16,3,2,13}四个元素的一维数组,同理magicSquare[1],magicSquare[2]也一样

    (1)传统的for循环方式

    for(int i=0;i<magicSquare.length;i++)
         {
        	 for(int j=0;j<magicSquare[i].length;j++)
        	 {
        		 System.out.print(magicSquare[i][j]+" ");
        	 }
        	 System.out.println();	//换行
         }

     


    (2)for each循环

     

    for(int[] a:magicSquare)
         {
        	 for(int b:a)
        	 {
        		 System.out.print(b+" ");
        	 }
        	 System.out.println();//换行
         }


    (3)利用Array类中的toString方法

    for(int i=0;i<magicSquare.length;i++)
        System.out.println(Arrays.toString(magicSquare[i]));

     

     

     

     

     

     

     

     

    展开全文
  • 数组的所有方法

    千次阅读 2019-03-04 09:20:39
    JavaScript中创建数组有两种方式 (一)使用 Array 构造函数: var arr1 = new Array(); //创建一个空数组 var arr2 = new Array(20); // 创建一个包含20项的数组 var arr3 = new Array(“lily”,“lucy”,“Tom”);...
  • 数组a[i++]是等于a[i]还是a[i+1]?

    千次阅读 2017-12-18 00:49:56
    a[i++]等于a[i]例如:a[i]=10;i=1;则:int y = a[i];int x = a[i++]; // x=10;// 此时i=2当然n=0 a[n++]=c-'0' 意思是a[0]=‘c’此时n=1n可以表示当前数组里面个数
  • C / C ++中的数组讲解

    千次阅读 2017-06-05 09:58:52
    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》...效果如下所示: 数组声明: 在C中,
  • c+合并两个数组Here you will get C/C++ program to find union of two arrays. 在这里,您将获得C / C ++程序来查找两个数组的并集。 For example: 例如: First array: {1, 3, 7, 9} 第一个数组:{1、3、7、9...
  • c语言++数组名【数字】A unique number is a number in which no digit is repeated. For example: 102452 is not a unique number as 2 is repeated twice while 2374 is a unique number. So in this article I am...
  • 数组a[i++]等于a[i]

    2020-03-31 15:30:44
    数组a[i++]等于a[i] a[i++]等于a[i] 例如: a[i]=10;i=1;则: int y = a[i];//y=10; int x = a[i++]; // x=10; // 此时i=2 当然n=0 a[n++]=c-‘0’ 意思是a[0]=‘c’此时n=1 n可以表示当前数组里面个数 ...
  • Array [] 数组

    千次阅读 2018-08-13 15:46:44
    ※ Array 数组 数组是指一组数据的集合,(容器)数组中的每个数据称为元素。在Java中,数组也是Java对象。数组中的元素可以是任意类型(包括基本类型和引 用类),但同一个数组里只能存放类型相同的元素。长度不可变...
  • 数组的三种定义方式

    万次阅读 多人点赞 2018-11-14 11:03:17
    1.数组的定义 用于存储同一类型数据的集合,其实数组就是一个容器。 连续的存储单元 2.数组的好处 自动给数组中的元素从零开始编号。自动给下标,从零开始0-1-2-3-…… 3.书写格式    元素类型[] 数组名 =...
  • 【Java】04 数组

    千次阅读 2020-04-09 22:58:09
    数组是编程语言中最常见的一种数据结构,可用于存储多个数据,每个数组元素存放一个数据,通常可通过数组元素的索引来访问数组元素,包括为数组元素赋值和取出数组元素的值。
  • javascript 数组以及对象的深拷贝(复制数组或复制对象)的方法前言在js中,数组和对象的复制如果使用=号来进行复制,那只是浅拷贝。如下图演示: 如上,arr的修改,会影响arr2的值,这显然在绝大多数情况下,并...
  • java如何向数组里添加元素

    万次阅读 多人点赞 2019-08-08 19:46:44
    java篇 哇,菜鸟第一次写这个东西,当加深印象,大佬们请略过,欢迎...但有个可以改变大小的数组为ArrayList,即可以定义一个ArrayList数组,然后用add(element)方法往里添加元素即可,还可add(index,element)往指...
  • 指针数组数组指针详解

    万次阅读 多人点赞 2016-09-28 21:21:20
    指针数组:指针数组可以说成是”指针的数组”,首先这个变量是一个数组,其次,”指针”修饰这个数组,意思是说这个数组的所有元素都是指针类型,在32位系统中,指针占四个字节。 数组指针:数组指针可以说成是”...
  • js数组删除(splice和delete)

    万次阅读 多人点赞 2018-01-17 22:37:22
    今天用到了数组的删除,分别使用了splice和delete方法,记录一下,方便下次查找。原数组是一个关联数组,如var test=[];test[1]={name:'1',age:1};test[2]={name:'2',age:2};test[4]={name:'3',age:3};console.log...
  • 在JS数组指定位置插入元素

    万次阅读 多人点赞 2014-07-26 14:37:30
    原文链接: Array: Insert an Item at a Specific Index with JavaScript原文日期: 2014年07月24日翻译日期: 2014年07月26日翻译人员: 铁锚很多与数组有关的任务听起来很简单,但实际情况并不总是如此,而开发人员在很...
  • C语言如何计算数组的长度

    万次阅读 多人点赞 2018-05-04 19:14:07
    (1)借助sizeof()函数 :#include&lt;stdio.h&gt;int main(){ // 定义一个整型数组, 并进行... // 计算数组中数据长度 : // 所有数据的字节数除以一个数据的字节数即为数据的个数 :  length = sizeof(arr) / ...
  • js如何往数组Array中添加元素

    万次阅读 2015-12-08 11:55:30
    unshift:将参数添加到原数组开头,并返回数组的长度  pop:删除原数组最后一项,并返回删除元素的值;如果数组为空则返回undefined  push:将参数添加到原数组末尾,并返回数组的长度  concat:返回一个新数组,...
1 2 3 4 5 ... 20
收藏数 3,656,681
精华内容 1,462,672
关键字:

数组