【C++】细说C++中的数组之“静态”数组

fishing-panhttps://blog.csdn.net/u013921430转载请注明出处】

前言

     数组是C/C++以及各种编程语言中最常用的一种数据结构,了解数组的性质并且学会使用数组是对于程序员最基本的要求。今天给大家介绍一下数组,介绍主要分为静态数组与动态数组两部分。

      注:这里讲到的静态数组不是使用static 关键字修饰的数组,而是普通的数组,为了与后面的动态数组分离开,才说明它是静态数组。

静态数组

     数组是一种复合的类型,因此在定义数组时必须显式指定数组的类型,不能使用auto关键字,静态数组的声明形如a[d]; a是数组的名字,d是数组的维度。维度说明了数组中元素的个数,因此d必须大于0。

      在进行编译时,d必须是已知的,即编译器在编译时d已经是可以确定的值,因此数组的维度必须是一个常量表达式。

补充:常量表达式是指不会改变且在编译过程就能得到计算结果的表达式,显然字面值属于常量表达式。

静态数组的初始化

   

 int S = 10;

 int arr[S];          //错误,S不是常量表达式

 int *prr[10];        //正确,10是常量表达式


 const int M = 10;

 int A[M] = { 10 };   //正确,M是常量表达式
 
 string C = "fishing_pan";

 const int N = C.length();

 char B[N];          //错误,N不是常量表达式,因为N在运行时候才被初始化 

      在上面的数组中可以看到,数组的维度必须是常量表达式。

      在定义的时候可以对静态数组进行列表初始化,而进行列表初始化时,可以不声明数组的维度,如果没有声明数组的维度,那么编译器会根据初始值推测数组的大小。如果声明了维度,那么数组的初始值的数量不能超过维度,如下面的例子所示。

int arr1[4] = {0, 1, 2 };             //数组大小为4,值分别是0,1,2,0,未列出的值进行默认初始化;

char arr2[] = {'P', 'A', 'N' };         //未声明大小,大小为3

double arr3[4] ={0,1,2,3,4}         //错误,初始值过多

    字符数组的特殊性

      在字符数组的定义中,可以使用字符串字面值进行定义,这个时候要注意了,字符串默认在结尾处还有一个空字符,空字符需要占用一个位置。

      从下面的例子可以看出,初始化字符数组时,可以不标明大小,这样不会出错。

char arr4[3] ="pan";     //错误,"pan"是const char[4]类型,不能用于初始化char arr4[3]

char arr5[] ="pan";      //正确,arr5大小为4;

    不允许拷贝和赋值

     不能将数组内容拷贝给其他数组进行初始化,也不能用数组为其他数组赋值。

数组元素访问

      数组元素可以用下标进行访问,也可以实现指针进行访问,需要注意的是,数组的第一个元素的编号是0,而不是1;一个100大小的数组,索引编号是0-99。    

char arr5[] = "pan";

char c=arr[2];          //c=’n’;

     数组与指针

      在C++中,数组与指针的关系非常紧密。指针一般使用取地址符来指向某一对象。同样也可以用于指向一个数组,不同的是,指针不会指向整个数组,而是指向数组中的某个位置;例如

int arr1[4] = { 0, 1, 2 };

int *p = &arr1[1];            //指向arr1的第二个数;

      直接将数组的名字传给指针时,默认指向数组的第一个值。

int arr1[4] = { 0, 1, 2 };

int *p = arr1;            //等价于p=&arr1[],指向arr1的第1个数;

     指针迭代与迭代器

      当遍历数值的值时,可以使用指针进行迭代,只需移动指针即可;

int arr1[4] = { 0, 1, 2 };

int *p = &arr1[1];

++p;              //此时p指向arr1[2];

       使用指针遍历虽然简单,但是容易出现超出范围的内存错误。因此可以使用迭代器;  

 int *beg = begin(arr1);     //指向数组首元素

 int *ends = end(arr1);      //指向数组末尾元素的下一位

  while(beg!=ends)          //进行遍历。

    {

        cout<< *beg<<endl;     //解引用输出数组值。

        beg++;

    }

多维静态数组

     在有些时候,为了使用方便或者观察方便,会定义多维数组,比如读取一张图像,可以用一张二维数组存储图像中对应坐标的灰度值。

     多维数组其实就是元素是数组的数组,拿一个二维数组为例,第一个维度表示的是数组的大小,也就说是数组本身有多少个元素。第二个维度表示其元素的大小。

inttwodArr1[4][5];   //定义一个本身大小为4,元素大小为5的数组,共可存储20个整型数据

     对于二维数组来说,我们常常把第一个维度称为行,第二个维度称为列,上式定义了一个4行5列的数组。

    多维静态数组的初始化

     除了一维数组中提到的注意事项外,多维数组进行初始化时,也有一个需要注意的问题。

    为了方便理解,可以使用花括号将每一行括起来。

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

也可以不适用花括号,由编译器自己判断;

int twodArr3[2][5]= { 0, 1, 2, 3, 4, 5, 6 };   //等价于int twodArr2[2][5] = { {0, 1, 2, 3, 4},{ 5, 6 ,0,0,0}};

注意:定义多维数组时,如果不对它进行初始化,必须标明每个维度的大小;如果进行了显式的初始化,可以不标明最高维度的大小,(也就是第一个维度,当第一个维度不标明大小,则不需进行初始化);

inttwodarr4[][][5] = { 0, 1, 2, 3, 4, 5, 6 };    //错误,需标明第二个维度的大小

inttwodarr5[][5] = { 0, 1, 2, 3, 4, 5, 6 };       //正确;

inttwodarr5[][5];                                         //错误,必须声明每一个维度的大小

    多维数组与指针及迭代器

int twodarr[3][4];

int(*p3)[5]= twodArr2;        //指向twodArr2的第一行

p3= &twodArr2[1];              //指向twodArr2的第二行

cout << *(*p3) << endl;            //输出为5,第二行第一个数字

        可以看出,我们使用指针对数组进行迭代,当然,也可以使用迭代器;

for (auto p = begin(twodArr2); p !=end(twodArr2); p++)

       {

              for(auto q = begin(*p); q != end(*p); q++)

              {

                     cout<< *q << " ";

              }

              cout<< endl;

       }
       至此,静态数组讲解的差不多了,如果大家有不理解的地方,可以把上面的代码都自己写一下,就能够明白为什么。后面,会写一篇动态数组的博文。并且讲一下静态数组与动态数组的区别。

       未完.......

相关文章  细说C++中的数组之动态数组
  • 20
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值