C语言一维,二维数组

目录

一,一维数组

      1,数组的创建

      2,数组的初始化

           1,完全初始化

           2, 不完全初始化 

           3,指定初始化器初始化(新特性)

            3.1 特性

二,一维数组的使用 

  1,指定数组的大小

  2,数组的边界

  3,给数组元素赋值

二,二维数组

 1,二维数组的创建  

2,二维数组的初始化

3,二维数组的使用

三,变长数组

四,复合字面量

总结与补充


一,一维数组

        数组是一组相同元素的集合

      1,数组的创建

typedef   arr_name[const_n] ;

           typedef : 表示数组元素的类型 ,普通变量可以使用的类型,数组都可以使用     

           arr_name : 表示数组名(自定义)

           const_n : 是一个常量表达式,用来指定数组的大小

如: int arr[10]

        数组元素的类型是int ,数组名是 arr ,数组大小是10,可以存放十个元素

      注:创建数组时 [ ] 里要给一个常量表达式才可以,虽然有的标准中可以使用变长数组(VLA),有的编译器还是会报错误的。

     

      2,数组的初始化

           1,完全初始化

                      初始化时,每个元素都赋上值,如:

  int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 } ;               

           2, 不完全初始化 

                      初始化时,只对个别元素,或者前面几个元素初始化

int arr2[10] = { 1,2,3,4,5 } ;

           3,指定初始化器初始化(新特性)

提示:数组下标从0开始,下标引用时[4]表示数组第五个元素,[1]表示数组第二个元素 。 

//指定初始化数组的某一个元素
  int a[10] = { [5] = 6} ;
             //把 arr[5] 初始话为 6 
//对days数组使用初始化器初始化
int days[12] = { 31 , 28 ,[4] = 31 ,30,31,[1]=29} ;

//输出结果 31,29,0,0,31,30,31,0,0,0,0,0

         由此可以看到,前面已经被初始化的元素可以被后面使用初始化器修改,[4] 被初始化后直接从继续开始输出话,这就说明了指定初始化器的两个重要特性。

            3.1 特性

                  1 ,如果指定初始化器后面有更多的值,如该代码片段中[4] =31,30 ,31 。那么后面                           的值将会初始化指定元素后面的值。也就是说 days[5]被初始化为30,days[6]被初                             始化为31。

                  2,如果再次初始化指定的元素,那么最后初始化的值将会取代之前的初始化,如:

                        [1]在前面被初始化为28,但是后面使用初始化器初始化为29,那么days[1]的值就                            改取代成 29。

注: 1. 使用不完全初始化,没有被初始化的元素会被初始化为0。

        2.初始化时,初始化列表里面的项数多余数组可存放元素个数,编译器会直接报错。

        3.初始化时,数组的大小没有给定,那么后面初始化的元素个数就是该数组的大小

           如:   int a[] = { 1,2,3,4,5,6,7 };    这个数组大小是 7

        4.使用指定初始化器初始化时,数组的大小没有指定,编译器会把数组的大小设置为足够装               得下初始化的值。

二,一维数组的使用 

         通过下标引用操作符( []) ,访问数组的每个元素;应注意数组的下标是从0开始的到n-1

         也可以通过引用下标对选中元素进行赋值。

  1,指定数组的大小

               前面说了数组的大小都是由常量表达式来声明的,接下来介绍一下给定大小。

          []里的值必须大于0,且为整数。

    int n = 5;
	float a1[5];             //可以
	float a2[5*2+1];         //可以
	 //sizeof()表达式被视为整型常量
	float a3[sizeof(int)+1]; //可以
	float a4[(int)2.5];      //可以,2.5被强制类型转换为整型2
	float a5[-4];            //不可以 数组大小必须大于0
	float a6[0];	         //不可以 数组大小必须大于0
	float a7[2.5];           //不可以 数组大小必须为整数
	float a8[m];             //VLA c99之前不允许

  2,数组的边界

      在使用数组时,要防止数组的下标超出边界,必须要保证下标是有效的值,如:

         int arr[20] ;

      定义一个可以存放20个整型元素的数组,那么它的下标就是 0-19的范围。超出这个范围比如说是使用 -1,或者20 当做下标,就会造成越界访问,使程序异常终止。

  3,给数组元素赋值

    声明数组后,可以借助数组下标给数组元素赋值,如:

int arr[10];//定义一个十个元素的数组
int  i =0 ;
//利用循环给数组赋值
for(i=0 ;i<10 ;i++)
{
   arr[i] = i ;  
}

   这种赋值方式是依次进行的,也可以单独赋值:

arr[5] = 6 ; 

  赋值和使用时都要注意的一点就是,下标从0 开始,最大不要超过n-1。

二,二维数组

        用图来简单描述一维数组和二维数组的区别。

       所以二维数组是建立在一维数组的基础上的。 

 1,二维数组的创建  

int arr[行][列] ;
int arr[3][4] ;//一个三行四列的二维数组

2,二维数组的初始化

      

//创建一个3行4列的二维数组
int arr[3][4] = {1,2,3,4} ;

int arr1[3][4] = {
                  {1,2},
                  {4,5}
                 } ;
//这样也是一种方式 ,没初始化的部分被初始化为0

int arr2[][4]  = {1,2,3,4,5,6,7,8,9,10,11,12};
//二维数组中的行是可以省略的,列不可以

初始化时时一行一行开始的,第一行的值被初始化为1,2,3,4 ; 没有初始化的部分,与一维数组一样会被初始维0。

当二维数组中的行省略时,会根据一列有多少来判断有多少行。

如上述代码断 arr2[][4] ,会根据一行四个来初始化,也就是会初始化三行。

3,二维数组的使用

   我们知道一维数组的使用可以引用下标操作,下标是从0开始的,那同样在使用二维数组时,我们也可以使用下标,注意 行和列的下标都是从0开始的

我们可以通过下标引用来初始化二维数组:

int i =0 ,j =0 ;
int arr[3][4]  ;
for(i =0 ; i <3 ;i++)
{
  for(j=0 ; j<4 ;j++)
   {
      arr[i][j] = i ;  
   }

}

三,变长数组

       前面说过,不管是一位数组还是二维数组,数组的大小都需要是一个确定的大于0的整数值,即便是已经被赋值的变量都不可以,但是C99标准新增了变长数组(VLA)允许使用变量表示数组大小。

int n =5; 
int arr[n] ;//表示一个存放五个int类型元素的数组

  不过我们要注意,变长数组的 ‘变’不是指可以修改已创建的数组的大小,而是在创建数组时,可以用一个变量指定数组的大小 。

 在使用变长数组时要注意编译器支不支持c99标准,否则会报错。

四,复合字面量

       字面量是除符号常量外的常量,代表数组内容;

int arr[5] = { 1,2,3,4,5} ;//这是一个普通的整型数组

int [5] {1,2,3,4,5} ;//这是一个复合字面量

//也可以说是匿名数组,去掉声明中的数组名, int [5]是复合字面量的类型

  同数组初始化相同,复合字面量在初始化时也可以省略大小,编译器会根据实际初始化值的个数进行判断,如:

   (int []){1,2,3,4,5} ;  //内含五个字符的复合字面量

 复合字面量的类型名代表首元素的地址,也可以使用指针记录复合字面量的地址:

 int *p ;

 p = (int [2]){10,20} ;

使用复合字面量时应注意:

   1:复合字面量是匿名的,所以不能先创建再使用,必须在创建的同时使用它。

   2:复合字面量只是临时的一种手段,具有块作用域,离开了定义复合字面量的块,不一定能保           证还会存在。 

总结与补充

  1:数组是可以通过下标来访问的,下标是从0开始的。

  2:数组的大小可以通过计算得到 。

       int arr[10];

       int sz = sizeof(arr) / sizeof(arr[0]) ;

 3: 通常来说数组名是数组首元素的地址,但是有两个例外:

        (1) sizeof(数组名) :这里的数组名表示的是整个数组,计算的是整个数组的大小,单位字                                               节。

        (2) &数组名        : 取出的是整个数组的地址。

4:不管是一维数组还是二维数组在内存中都是连续存放的 

          (1)一维数组:在内存中连续存放,每增加一位,增加一个类型大小(比如 int 类型就是                                         增加4)。

                                     随着数组下标的增长,地址也是由低到高变化的。

          (2)二维数组 :在内存中也是连续存放的,行之间连续,跨行之间也是连续的。

                                       (第一行的最后一个元素的地址与第二行首元素的地址是连续的)。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值