代码改变世界

学习C++ -> 一维数组

2012-12-03 01:03  wid  阅读(14386)  评论(2编辑  收藏  举报

学习C++ -> 一维数组

 

一、一维数组
    数组是一些按序排列的同类数据元素的集合, 数组的用途可以暂时理解为用来一次定义大量变量, 例如我们要存放100个int型的整数, 如果我们一个个声明就需要定义100个int型的变量, 例如:

    int a1, b1, c1, d1, e1, f1, g1, ... ;


    如此, 这样是十分复杂且不符合实际的, 这时我们就需要借助一维数组来帮忙, 定义一个能够放下100个int型整数的数组:

        int a[100] ;


    这样就相当于完成了100个int型变量的定义, 确实很方便, 那么我们如何使用它呢? 我们可以这样认为, 定义了一个int a[100]型的数组就相当于定义了:

        int a[0], a[1], a[2], a[3], ..., a[99] ;

    这时只需把a[0]、a[1]他们当做一个普通的变量名即可, 例如对其中的第一个数a[0], a[1]进行赋值操作:

        a[0] = 10 ;
        a[1] = 20 ;


    代码演示:

#include<iostream>

using namespace std ;

int main()
{
    int a[100] ;
    a[0] = 10 ;
    a[1] = 20 ;
    a[99] = 30 ;
    cout<< "a[0] = " << a[0] << endl ;
    cout<< "a[1] = " << a[1] << endl ;
    cout<< "a[99] = " << a[99] << endl ;

    return 0 ;
}


输出如下:

a[0] = 10
a[1] = 20
a[99] = 30

Process returned 0 (0x0)   execution time : 0.047 s
Press any key to continue.


    可以看出, 定义了一个 int a[100] ; 那么从 a[0] 一直到 a[99] 都可以用来当做一个普通的变量名使用, 其中 中括号 [] 之间的数称为数组的下标, 需要注意的是, 定义 a[100] 的一维数组他的下标范围是 0-99, 因为下标是从0开始的, 不是从1开始, 从0开始到99正好是一百个数, 也就是说如果定义一个大小为100的一维数组 a[100] , 那么它能够使用的下标范围是 0 - 99, 如果使用时下标不在 0-99 这个范围内就会发生不可预知的一些错误, 称为 下标越界 , 当下标越界时编译器是不会报错的, 但是运行时会发生严重的错误, 所以一定要避免下标越界这种错误的发生。
    


    1>. 一维数组的定义:
        在上面的示例中已经定义了一个int型的数组, 数组的类型不但可以是int型, 他还可以是 unsigned int型、long int型、float型、double型等基本数据类型, 也可以是以后我们将会学习的自定义的数据类型, 一旦声明了该数组的数据类型, 那么该数组中的所有元素都是声明时的数据类型, 例如:

            int a[100] ;          //从 a[0] - a[99] 都是int型数据
            float b[100] ;         //从 b[0] - b[99] 都是float型数据
            double c[100] ;        //从 c[0] - c[99] 都是double型数据

       
        数组定义的一般格式:

        数据类型 数组名[元素个数] ;

 

        元素个数的一般声明方式:
            ①. 元素个数的定义可以直接指定一个整数值, 比如 int a[10], b[20] ; 这里的 10、20就是我们直接指定的该数组的大小(也称为长度), 还可以包含些运算符来定义数组的大小, 如:

            int a[10*6] ;

            这样就说明该数组的长度为60。
        
            ②. 元素个数还可以通过字符常量进行定义, 看一段代码:

    #define N 10

    int main()
    {
        int a[N] ;
        return 0 ;
    }


            在上面的代码中我们定义了一个一维数组a, 并且指定了它的大小(长度)为10, 注意 #define N 10 这行代码, 这句的意思就表示将字符 N 定义为 常量数值10, 在下面的代码中, 出现 N 的地方就意味着将用数值10进行代替, 所以 int a[N] ;就相当于 int a[10] ;。
        
          ③. 在介绍这种声明数组元素个数之前, 需要知道的是, 这种定义方式不适合所有的编译器, 只有支持 C99 标准的编译器才支持这种定义方式, 否则在编译时会报错, 这种声明方式就是:
                使用 一个值为整数的变量 去声明一个数组的大小, 例如:

                    int n = 100 ;
                    float a[n] ;        //定义一个名为a, 大小为100的float型数组


    
    2>. 一维数组的初始化:
        数组的初始化是指在定义数组时, 同时对数组中的元素进行赋值的方法称为数组的初始化。
        初始化举例:

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

        这样就是在定义时并且对数组进行初始化了, 其中 a[0]的中的值为1, a[1]中的值为2, ... a[4]中的值为5, 我们声明了一个长度为5的数组a, 并且提供了5个初始值在大括号内, 中间用逗号隔开, 像这样的方式就是对数组的中的元素个数全部全部初始化。
        
        还可以对一个数组中的部分元素进行初始化:

            int a[5] = { 1, 2, 3 } ;

        这样是只对数组的前三个元素, a[0]、a[1]、a[2]进行初始化, 没有初始化到的部分默认以0填充, 此时 a[3]、a[4]中的值就是0。
        
        数组初始化的一般格式:
            ①. 形式一:

                数据类型 数组名[元素个数] = { 值1, 值2, 值3, ..., 值n } ;

                对于这种形式, 没有初始化到的部分将被赋上默认值0。


            ②. 形式二:

                数据类型 数组名[] = { 值1, 值2, 值3, ..., 值n } ;

                这种形式省略了数组元素个数的声明, 编译器会根据后面初始值的个数自动计算数组的长度, 例如:

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

                就相当于声明一个数组a, 其长度为5, 并进行初始化。可以看出, 这种初始化的方式也可以用来声明数组元素的个数。
        
        需要注意的是, 如果不对数组进行任何初始化操作, 仅定义一个数组, 那么数组中这些元素的值是不确定的, 是系统中随机的一个值。
        


    3>. 一维数组的使用:
        数组使用时需要指定下标的值, 一维数组的一般使用形式:

            数组名[下标]

        例如:

            int a[10] = {} ;       //定义并全部初始化为0
            int i = 3 ;          //定义一个普通整形变量, 初始值为3
            a[1] = 10 ;          //将数组a[1]赋值为10
            a[1+1] = 20 ;        //将数组a[2]赋值为20
            a[i] = 30 ;          //将数组a[3]赋值为30

        下标必须是一个整数, 可以是常量、变量、表达式, 例如 a[1]、a[i]、a[i+1]这样的使用都是合法的。
        
        由于编译器不做下标的越界检查, 所以必须要注意下标的越界问题, 避免下标越界这样的错误发生。
        


    4>. 一维数组使用举例:
        输入5个数并逆序输出
            输入: 15 13 11 8 26
            输出: 26 8 11 13 15
            输入时每个数中间用空格隔开。
        代码:

  #include<iostream>

  using namespace std ;

  int main()
  {
      int a[5] ;  //定义一个元素个数为5的数组
      int i ;     //用于控制for循环
      cout<< "Please input 5 numbers:" ;  //提示输入5个数
      for( i = 0; i < 5; i++ )    //输入
          cin >> a[i] ;
      for( i = 4; i >=0; i-- )    //控制下标从4到0逆序输出
          cout << a[i] <<" " ;

      return 0 ;
  }

 



二、进一步理解
    1>. 数组在内存中所占的空间大小
        我们已经知道, 一个int型元素所占的内存为4字节(以较新的GCC编译器为例), 那么如果定义一个 int a[10] ;这样的数组在内存中将会占用多大的内存呢?
        可以实际测量一下, 使用sizeof运算符,

#include<iostream>

using namespace std ;

int main()
{
    int a[10] ;
    cout<<sizeof(a)<<endl ;

    return 0 ;
}


        输出的结果为40, 也就代表是40个字节, 一个int型为4个字节, 数组的大小是10, 4 * 10正好是40, 如果不确定还可以从a[0]到a[9]一个个测量其占用的存储单元大小, 然后相加, 这里就不再贴出代码了。
        总结下就是:

            数组所占的内存单元大小 = 数组数据类型的大小 * 元素个数

        例如 double b[10] ;所占的内存大小就是 一个double型数据大小8 * 元素个数 10, 即80个字节。
    
    
    2>. 一维数组在内存中的存放状态
        一维数组在内存中实际上是一段连续的内存单元, 当定义好一个数组时, 一段连续的内存单元就被开辟出来用于存放数组中元素的值, 假如我们定义一个数组int a[10], 那么它在内存中的情况可以想象成如图所示的状态:


        可以看到, 数组中的每个元素实际上都有一个自己的地址, 图中的这些元素所对应的地址实际上全部都是为了方便表示而假设的, 数组在真实的运行中所使用的地址是根据当前系统的内存状态而定, 所以说即时运行同一个程序, 每次运行时数组所使用的内存单元地址也极有可能不同。
        
        从图中还可以看到一点, 从a[0]到a[9]的内存地址不是 1000、1001、1002... 这样连续的方式进行排列的, 而是 1000、1004、1008...这样每隔4个数出现一个, 这样的原因是因为一个int型是4个字节, 而一个存储单元的大小为一字节, 所以一个int型数据就需要4个存储单元, 也就是4个字节, 这里用一个方格表示一个元素是为了能够直观的进行表示。
        
        在内存中的存放状态这块, 目前我们只需先对其有个相关的印象即可, 更详细的介绍将会在以后将会学习的指针中进行。

 

--------------------

wid, 2012.12.03

 


上一篇: 学习C++ -> 循环语句与循环控制