C语言基础3-数组

目录

一、数组

    什么是数组

    如何定义数组

    访问数组中的变量

    遍历数组

    数组的初始化

    数组与sizeof

    数组越界

    数据越界的后果

    一些使用数组实现的简单功能

         输入一个整数,分解显示

        计算显示出100的阶乘的结果,使用数组模拟乘法的运算过程

        输入n,显示前n项斐波那契数列

        显示9*9乘法表   

        显示出100-1000之间所有的素数

        输入一个日期(yyyy-mm-dd),计算该日期自(1年1月1日)过了多少天

二、二维数组

    什么是二维数组

    定义二维数组

    访问二维数组元素

    二维数组的遍历

    二维数组的初始化

    一些使用二维数组实现的简单功能

        定义一个5*5的二维数组并随意初始化,找出每一行的最大值、每一列的最小值、和所有数据的平均值(尽可能少遍历)

        定义一个5*5的二维数组并初始化,计算出最小值周围一圈数据之和(先找出最小值的行下标、列下标、然后再计算周围八个位置是否合法,合法就累加)

三、变长数组

    定长数组

    变长数组

    变长数组的优缺点


一、数组

    什么是数组

        数组就是变量的组合,是一种批量定义变量的方式

    如何定义数组

        类型名 数组名[数量];

    int arr[8];//   相当于定义了8个int类型的变量
    int a1,a2,a3,...;

    访问数组中的变量

        数组名[下标];

        下标从0开始,范围0~数量-1

    遍历数组

        与for循环配合,使用循环变量作为数组遍历的下标

    int arr[10];
    for(int i=0; i<10; i++)
    {  
        printf("%d\n",arr[i]);
    }

    数组的初始化

        数组的元素的默认值也是随机的,如果想要对数组初始化可以使用以下语法:

                                        类型名 数组名[数量] = {v1,v2,v3,...};

        注意:

        1、如果初始化数据过多,编译器会产生警告并丢弃

        2、如果初始化数据不足,编译器会自动补0

        3、对数组初始化时,数组的初始值可以省略,大括号不能省略,编译器会自动全部补0

        4、当使用初始化语法时,数组的数量可以省略,编译器会计算出大括号中数据的个数,然后确定数组的数量

        5、初始化语法只能在定义数组时使用,这也是唯一一次能对数组批量访问的机会,后序只能单个元素访问

    数组与sizeof

使用方法功能
sizeof(数组名)计算整个数组的总字节数
sizeof(数组名[下标])sizeof(arr[0])    计算某个元素的字节数    
sizeof(数组名)/sizeof(数组名[0])计算数组的元素个数

    数组越界

        使用非法的下标访问该下标的数组元素,该动作称为数组越界

int arr[10];
arr[10] = 10;  

        C语言中当数组越界访问时,编译器不会报错,因为C编译器是不检查数组下标是否合法的,因为这样可以提高代码的编译速度、运行速度

    数据越界的后果

        1、运气好,一切正常

        2、段错误,操作系统发现程序非法访问内存,主动杀死程序

        3、脏数据,数据越界访问到了其它程序、数组、变量的数据,破坏了别人的数据

    一些使用数组实现的简单功能

         输入一个整数,分解显示

                输入12321  输出 1 2 3 2 1

                输入-12321  输出 - 1 2 3 2 1

​​int main(int argc,const char* argv[])
{
    int num = 0,cnt = 0;
    printf("请输入一个整数:");
    scanf("%d",&num);
    char arr[10] = {};

    if(num < 0)
    {
        printf("- ");
        num = -num;  // num = abs(num);                                                          
    }
    while(num)
    {
        arr[cnt++] = num % 10;
        num /= 10;
    }

    for(int i=cnt-1; i>=0; i--)
    {
        printf("%hhd ",arr[i]);
    }                                                                                   
}
        计算显示出100的阶乘的结果,使用数组模拟乘法的运算过程
​int main(int argc,const char* argv[])
{
    char result[256] = {6};
    int cnt = 1;    //  当前结果的位数

    for(int i=4; i<=100; i++)
    {
        int carry = 0;  //  进位
        for(int j=0; j<cnt; j++)
        {
            int num = i * result[j] + carry;
            result[j] = num % 10;
            carry = num / 10;
        }
        while(carry)
        {
            result[cnt++] = carry % 10;
            carry /= 10;
        }
    }

    for(int i=cnt-1; i>=0; i--)
    {
        printf("%hhd",result[i]);
    }                                                                                        
}
        输入n,显示前n项斐波那契数列
int main(int argc,const char* argv[])
{
    int n1 = 1, n2 = 0, n3 = 0;
    int N = 0;
    printf("请输入N的值:");
    scanf("%d",&N);
    for(int i=0; i<N; i++)
    {  
        n3 = n1 + n2;
        printf("%d ",n3);
        n1 = n2;
        n2 = n3;
    }  
}
        显示9*9乘法表   
int main(int argc,const char* argv[])
{
    for(int i=1; i<10; i++)
    {  
        for(int j=1; j<=i; j++)
        {
            printf("%d*%d=%02d ",i,j,i*j);                    
        }
        printf("\n");
    }  
}
        显示出100-1000之间所有的素数
int main(int argc,const char* argv[])
{
    for(int i=100; i<1000; i++)
    {  
        int j;
        for(j=2; j<=i/2; j++)
        {
            if(0 == i%j) break;
        }

        if(j > i/2)
        {
            printf("%d ",i);
        }                                                    
    }  
}
        输入一个日期(yyyy-mm-dd),计算该日期自(1年1月1日)过了多少天
int main(int argc,const char* argv[])
{
    unsigned short year = 0;
    unsigned char month = 0,day = 0;
    printf("请输入一个日期(yyyy-mm-dd):");
    scanf("%hu-%hhu-%hhu",&year,&month,&day);
    if(month > 12 || month == 0 || day > 31 || day == 0)
    {
        printf("日期有误\n");
        return 0;
    }
    int sum = 0;
    for(int y=1; y<year; y++)
    {
        sum += 365 + (0==y%4 && 0!=y%100 || 0==y%400);
    }
    for(int m=1; m<month; m++)
    {
        switch(m)
        {
            case 2:
            sum += 28 + (0==year%4 && 0!=year%100||0==year%400);
            break;
            case 4: case 6: case 9: case 11:
            sum += 30;
            break;
            default:
            sum += 31;                                                                                                        
            break;
        }
    }
    printf("共过了%d天\n",sum + day -1);
}

二、二维数组

    什么是二维数组

        普通一维数组,可以看做若干个变量排成一排

        二维数组,可以把若干个类型相同的变量排成一个方阵

    定义二维数组

        类型名 数组名[行数][列数];

    访问二维数组元素

        数组名[行下标][列下标];

        行下标:0 ~ 行数-1

        列下标:0 ~ 列数-1

    二维数组的遍历

        一般与双层for循环配合,一般外层循环遍历行,内层循环遍历列

    int arr[3][5];
    for(int i=0; i<3; i++)
    {  
        for(int j=0; j<5; j++)
        {
            printf("%d ",arr[i][j]);
        }
        printf("\n");
    }  

    二维数组的初始化

        二维数组在初始化时,其它特点与一维数组基本相同

注意:二维数组初始化时,可以省略行数,但是一定不能省略列数,并且要提供初始化数据才可以省略行数,编译器会自动计算元素个数

        类型名 数组名[行数][列数] = {{第一行},{第二行},...};

    一些使用二维数组实现的简单功能

        定义一个5*5的二维数组并随意初始化,找出每一行的最大值、每一列的最小值、和所有数据的平均值(尽可能少遍历)
int main(int argc,const char* argv[])
{  
    int arr[5][5];
    for(int i=0; i<5; i++)
    {
        for(int j=0; j<5; j++)
        {
            arr[i][j] = i*5+j;
            printf("%d ",arr[i][j]);
        }
        printf("\n");
    }

    float avg = 0;
    for(int i=0; i<5; i++)
    {
        int max = arr[i][0];
        int min = arr[0][i];
        for(int j=0; j<5; j++)
        {
            if(max < arr[i][j]) max = arr[i][j];
            if(min > arr[j][i]) min = arr[j][i];
            avg += arr[i][j]/25.0;
        }
        printf("第%d行的最大值%d,第%d列最小值是%d\n",i,max,i,min);
    }
    printf("平均值:%f\n",avg);
}
        定义一个5*5的二维数组并初始化,计算出最小值周围一圈数据之和(先找出最小值的行下标、列下标、然后再计算周围八个位置是否合法,合法就累加)
​int main(int argc,const char* argv[])
{  
    int arr[5][5];
    for(int i=0; i<5; i++)
    {
        for(int j=0; j<5; j++)
        {
            arr[i][j] = i*5+j;
            printf("%d ",arr[i][j]);
        }
        printf("\n");
    }
    
    int min_x = 0, min_y = 0;
    for(int i=0; i<5; i++)
    {
        for(int j=0; j<5; j++)
        {
            if(arr[i][j] < arr[min_x][min_y])
            {
                min_x = i;
                min_y = j;
            }
        }
    }
    int sum = 0;
    for(int i=min_x-1; i<=min_x+1; i++)
    {
        for(int j=min_y-1; j<=min_y+1; j++)
        {
            if(i>=0 && i<=4 && j>=0 && j<=4)
            {
                   sum += arr[i][j];
            }
        }
    }
    printf("sum=%d\n",sum-arr[min_x][min_y]);
}

三、变长数组

    定长数组

        使用常量作为定义数组的长度参数,或者使用初始化数据定义数组时省略长度参数,这些数组都称为定长数组,由编译器最终确定数组的长度

    变长数组

        使用变量作为定义数组的长度参数时,称为变长数组,当程序运行时,执行定义数组的语句前,可以改变数组的长度变量,所以数组的长度可以每一次运行都不同,但是一旦数组的长度确定后,都无法改变

int len;
scanf("%d",&len);
int arr[len];

    变长数组的优缺点

        优点:可以根据运行的实际需求定义数组的长度,从而节约内存空间

        缺点:变长数组不能初始化,对数组的初始化是发生在编译器编译期间,而变长数组的长度是运行到定义语句后才能确定,因此编译器在编译期间无法得知变长数组的长度,因此无法初始化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值