C语言之数组总结

回过头来复习基础,打铁需要自身硬


一概述:

    数组在C语言中有着特殊的地位,它有很多特性,例如它的存储是连续的,数组的名称就是数组的地址等。

          

二.  一维数组:

    1.注意:

     1.数组长度必须是固定的,必须为常量或常量表达式(2+1,2*3)或者不写,不能使用变量进行初始化。

 int len = 2;
 int a[len] = { 1, 2};//错误,不能使变量

     2.如果声明的同时进行赋值则长度可以忽略,编译器会自动计算素组长度。

    int b[] = { 1, 2, 3 };
//如果初始化的同时赋值则数组长度可以省略,当前长度个数为3

     3.数组不能先声明再一次性赋值.(当然可以对每一个元素一一赋值)

 //错误:
 int len[2];   //len == &len[0]第一个元素的地址就是整个数组的地址,
 len = {1,2,3}; //len是数组名,代表数组的地址,也是个常量,给常量赋值肯定是错的。
 len[2] = {1, 2, 3}; // 错误,代表着数组第3个元素,这里已经数组下标越界了,就算没有越界,应该赋值int类型不应该是{}.

 
//正确:   
  int c[2];
  c[0] = 1;
  c[1] = 2;
  c[2] = 3;//超过数组长度,但是编译器并不会检查,运行报错,数组遍历从下标0开始遍历,元素不能超过长度,否则数组越界.{leng-1};

4.在计算机中,遍历一般是从0开始遍历, 数组长度就是跟现实生活一样从1开始.

    int b['a'] = {1,2,3};//'a'=97,所以可以作为数组长度,但是后面的元素没有初始化,其值默认为0
    for (int i = 0; i < 97; ++i){
        printf("b[%d]=%d\n",i,b[i]);
    }

    

5.只能存放一种类型的数据,如全部是int型或者全部是char型,数组里的数据成为元素.


2.1.数组存储

    刚刚上面说了,知道 数组类型 和 数组名(等于第一个元素的地址) 就可以知道其他元素的地址.即第一个元素的地址就是整个数组的地址

#include <stdio.h>

int main(){
    int const l = 3;
    int a[l] = { 1, 2,3 };
    for (int i = 0; i < l; ++i){
        //由于当前在32位编译器下,int型长度为4个字节,可以判断出三个地址两两相差都是4
        printf("a[%d]=%d,address=%x\n", i, a[i], &a[i]);
    }
    /*当前输出结果:
    a[0] = 1, address = c9f95c
    a[1] = 2, address = c9f960
    a[2] = 3, address = c9f964*/
}


额外:数组名代表着整个数组的地址,如果一维数组的名字作为函数实参,传递的是整个数组,即形参数组和实参数组完全等同,是存放在同一存储空间的同一个数组。这样形参数组修改时,实参数组也同时被修改了

#include <stdio.h>
//形参
void changeValue(int a[]){ 
   a[0] = 10;
}

int main(){
    int a[2] = {1,2};
    changeValue(a); //实参
   for (int i = 0; i < 2; ++i){
        printf("a[%d]=%d\n",i,a[i]);
    } /*打印结果
    a[0]=10
    a[1]=2
    */
}
如果把一位数组的元素(a[0])作为函数的实参,只是把元素的值传给形参,形参不会改变实参


三.多维数组:

 二位数组是一个特殊的一维数组,它的元素是一位数组.

例如int a[2][3]可以看作由一维数组a[0]和一维数组a[1]组成,这两个一维数组都包含了长度为3的int类型3个元素

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


* 二维数组的存放顺序是按行存放的,先存放第一行的元素,再存放第2行的元素。例如int a[2][3]的存放顺序是:a[0][0] → a[0][1] → a[0][2] → a[1][0] → a[1][1] → a[1][2]

        


#include <stdio.h>

int main(){
    int a[2][3];//2行3列,二维数组可以看成是一个特殊的一维数组,只是它的每一个元素又是一个一维数组
    a[0][0] = 1;
    a[0][1] = 2;
    a[0][2] = 3;
    a[1][0] = 4;
    a[1][1] = 5;
    a[1][2] = 6;
    for (int i = 0; i < 2; ++i){
        for (int j = 0; j < 3; ++j){
            printf("a[%d][%d]=%d,address=%x\n", i, j, a[i][j], &a[i][j]);
        }
    }
    /*打印结果
    a[0][0]=1,address=f8fb24
    a[0][1]=2,address=f8fb28
    a[0][2]=3,address=f8fb2c
    a[1][0]=4,address=f8fb30
    a[1][1]=5,address=f8fb34
    a[1][2]=6,address=f8fb38
    */
    //初始化并直接赋值
    int b[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
    //由于数组的赋值顺序是先从第一行第一列,再第一行第二列...然后第二行第一列...,所以我们也可以写成如下形式
    int c[2][3] = { 1, 2, 3, 4, 5, 6 };
    //也可以只初始化部分数据,其余元素默认为0
    int d[2][3] = { 1, 2, 3, 4 };
    for (int i = 0; i < 2; ++i){
        for (int j = 0; j < 3; ++j){
            printf("d[%d][%d]=%d\n", i, j, d[i][j]);
        }
    }
    /*打印结果
    d[0][0]=1
    d[0][1]=2
    d[0][2]=3
    d[1][0]=4
    d[1][1]=0
    d[1][2]=0
    */
    //当然下面赋值也可以
    int e[2][3] = { {}, { 4, 5, 6 } };
    //可以省略行号,但是绝对不可以省略列号,因为按照上面说的赋值顺序,它无法判断有多少行
    int f[][3] = { {1,2,3},{4,5,6} };
}

    存储内存:


a[0]、a[1],也是数组,是一维数组, 而且a[0]、a[1]就是数组名,因此a[0]、a[1]就代表着这个一维数组的地址.

1> 数组a的地址是f8fb24,数组a[0]的地址也是f8fb24,即a = a[0];


2> 元素a[0][0]的地址是f8fb24,所以 数组a[0]的地址 和 元素a[0][0]的地址 相同,即a[0] = &a[0][0];


3> 最终可以得出结论:a = a[0] = &a[0][0],以此类推,可以得出a[1] = &a[1][0]

猜你喜欢

转载自blog.csdn.net/null959_/article/details/80305844