C语言 ---数组

C语言 ---数组,第1张

数组:

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

    定义数组:类型 数组名[长度];

        int arr[5] <=> int n0,n1,n2,n3,n4;

    使用数组:数组名[下标];

        下标范围:[0,长度-1];

    初始化:类型 数组名[长度] = {0,1,2,4,...};

        1、使用数组定义出的变量与普通变量一样,默认值是不确定的。

        2、初始化语法只有定义数组时才能使用,这也是唯一一次能对数组批量访问的机会,数组定义完成后就只能单个访问,数组的初始化过程是编译器帮助完成的。

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

int arr[5] = {1,2,3,4,5,6,7};

        4、如果初始化数据不够,编译器会自动补0。

int arr[5] = {};

        5、初始化数组时,数组的长度可以省略,编译器会统计数据的个数,设置给数组。

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

            sizeof(arr)/sizeof(arr[0]) 

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

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

        size_t len = sizeof(arr)/sizeof(arr[0]);

        for(int i=0; i

        {

            printf("%d ",arr[i]);

        }

    练习9、定义个数组并随机初始化,计算出数组中的最大值、最小值、平均值。

#include

int main(int argc,const char* argv[])

{

int arr[] = {-1,1,3,5,7,6,19,8,4,2,10};

int min = arr[0] , max = arr[0] , sum = arr[0];

size_t len = sizeof(arr)/sizeof(arr[0]);

for(int i=1; i

{

if(arr[i] > max)

max = arr[i];

if(arr[i] < min)

min = arr[i];

sum += arr[i];

}

printf("%d %d %g\n",max,min,sum*1.0/len);

return 0;

}

    练习10、输入一个整数,分解显示,例如:输入12345,显示为:1 2 3 4 5。

#include

#include

int main(int argc,const char* argv[])

{

int num;

printf("请输入一个整数:");

scanf("%d",&num);

if(num < 0)

{

printf("- ");

num = abs(num);

}

char arr[10] , cnt=0;

while(num)

{

arr[cnt++] = num % 10;

num /= 10;

}

for(int i=cnt-1; i>=0; i--)

{

printf("%d ",arr[i]);

}

return 0;

}

           

变长数组:

    变长数组就是使用变量作为数组的长度,这种数组在编译时长度可以不确定,在执行数组的定义语句前,长度变量可以变化,当执行数组的定义语句后,数组的长度才确定下来,但确定下来后就不能再变。

    优点:可以根据实际情况设置数组的长度,达到节约内存的目的。

    缺点:变长数组不能初始化,原因是数组的初始化时编译器帮助完成的,而编译时编译器无法知道数组的长度。

   

    size_t len;

    // 这个过程中可以根据实际情况给len赋值

    int arr[len];

练习11:给定N个整数,计算它们的平均值,例如:7 5 -3.2 4.8 99 98 2.3 7.123 2.35。

#include

int main(int argc,const char* argv[])

{

size_t len;

scanf("%d",&len);

float num,sum = 0;

for(int i=0; i

{

scanf("%f",&num);

sum += num;

}

printf("%g\n",sum/len);

return 0;

}

二维数组:

一维数组相当于把变量排成一排,二维数组就是把变量排成一个方阵。

定义: 类型  数组名[行数][列数];

注意:二维数组在初始化时,其他特点与一维数组相同,不同的是列数必须确定。

练习1:输入矩阵的阶数n,按照螺旋顺序填充数字,n>=2。

#include

int main(int argc,const char* argv[])

{

    int n;

    printf("请输入矩阵的阶数:");

    scanf("%d",&n);

    int arr[n][n] , val = 1;

    arr[n/2][n/2] = n*n;

    // n/2计算出圈数

    for(int i=0; i

    {

        // 行下标:圈数,列下标:[圈数,n-1-圈数)

        for(int j=i; j

            arr[i][j] = val++;

        // 行下标:[圈数,n-1-圈数) 列下标:n-1-圈数

        for(int j=i; j

            arr[j][n-1-i] = val++;

        // 行下标:n-1-圈数 列下标:[n-1-圈数,圈数)

        for(int j=n-1-i; j>i; j--)

            arr[n-1-i][j] = val++;

        // 行下标:[n-1-圈数,圈数 列下标:圈数

        for(int j=n-1-i; j>i; j--)

            arr[j][i] = val++;

    }

    // 遍历矩阵

    for(int row=0; row

    {

        for(int col=0; col

        {

            printf("%2d ",arr[row][col]);

        }

        printf("\n");

    }

    return 0;

}

作业:

    1、定义个数组并随机初始化,计算出数组中第二大的值(要求使用速度最快的方法)。

#include

// 1、定义个数组并随机初始化,计算出数组中第二大的值(要求使用速度最快的方法)。

int main(int argc,const char* argv[])

{

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

    size_t len = sizeof(arr)/sizeof(arr[0]);

    int max = arr[0] , max2 = arr[1];

    for(int i=1; i

    {

        if(arr[i] > max)

        {

            max2 = max;

            max = arr[i];

        }

        else if(arr[i] > max2)

        {

            max2 = arr[i];   //   保证第二大的值就是第二大的值,而不单纯只是从max1退位下来的值

        }

    }

    printf("%d\n",max2);

    return 0;

}

    2、定义个数组并随机初始化,求该数组进行升序排序(使用任何排序方法都行)。

#include

#include

int main(int argc,const char* argv[])

{

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

    size_t len = sizeof(arr)/sizeof(arr[0]);

   

    // 经典排序

    for(int i=0; i

    {  

        for(int j=i+1; j

        {

            if(arr[i] > arr[j])

            {

                int tmp = arr[i];

                arr[i] = arr[j];

                arr[j] = tmp;

            }

        }

    }  

    // 冒泡排序:通过前后比较数据,把较大的数交换到后面,它每一趟排序都把当前待排序的最大值放在最后面,该过程非常像气泡在水底上升的过程,因此叫冒泡排序,这种排序算法的特点:对数据的有序性敏感,在排序过程中一旦数据已经排序完成,冒泡排序会立即结束。

    bool flag = true;

    for(int i=len-1; i>0 && flag; i--)

    {  

        flag = false;

        for(int j=0; j

        {

            if(arr[j] > arr[j+1])

            {

                int tmp = arr[j];

                arr[j] = arr[j+1];

                arr[j+1] = tmp;

                flag = true;

            }

        }

    }  

    // 选择排序:每次从先假定当前位置的数据是最小值,然后与它后面的数据进行比较(经典排序会立即交换),记录最小值的下标,如果最小值下标不是当位置,则把最小值与当前数据交换,与经典排序相比数据比较的次数没有变,但大大降低了数据的交换次数,以此提高排序速度。

    for(int i=0; i

    {  

        int min = i;

        for(int j=i+1; j

        {

            if(arr[min] > arr[j])

                min = j;

        }

        if(min != i)

        {

            int tmp = arr[min];

            arr[min] = arr[i];

            arr[i] = tmp;

        }

    }  

          // 遍历数组

    for(int i=0; i

    {  

        printf("%d ",arr[i]);

    }  

    return 0;

}

    3、输入一个整数,计算出每位数字出现的次数(参考练习10)。

#include

int main(int argc,const char* argv[])

{

    int num;

    printf("请输入一个整数:");

    scanf("%d",&num);

   

    int cnts[10] = {}; // 记录每个数字出现的次数

    do{

        cnts[num%10]++;

    }while(num/=10);

    for(int i=0; i<10; i++)

    {  

        if(cnts[i])

            printf("数字%d 出现了%d次\n",i,cnts[i]);

    }  

    return 0;

}

    4、输入一个整数,判断是否是回文数(左右对称的数字叫回文数)。

#include

int main(int argc,const char* argv[])

{

    int num;

    printf("请输入一个整数:");

    scanf("%d",&num);

    // 把num倒着拆分出来组成一个新的整数

    int tmp = num , new = 0;

    do{

        new = new*10+tmp%10;

    }while(tmp/=10);

    // 如果新组成的整数等于原来的整数则是回文数

    if(new == num)

        printf("是回文数!\n");

    else

        printf("不是回文数!\n");

    /*

    // 把整数的每一位数字拆分出来并记录位数

    char arr[10],cnt=0;

    do{

        arr[cnt++] = num % 10;

    }while(num/=10);

    // 把第一位与倒数第一位比较,把第二位与倒数第二位比较,... 只要有一次不相等它就不是回文数

    for(int i=0; i

    {

        if(arr[i] != arr[cnt-i-1])

        {

            printf("不是回文数!\n");

            return 0;

        }

    }

    printf("是回文数!\n");

    */

    return 0;

}

    5、计算并显示出100的阶乘(用数组模拟乘法的计算过程)。

#include

int main(int argc,const char* argv[])

{

    // 把数组当作一张非常长的纸,并且存储1×2×3的值

    char arr[200] = {6};

    int cnt = 1;

    for(int i=4; i<101; i++)

    {

        int carry = 0;

        for(int j=0; j

        {

            // 用i与数组中的每个数字相乘并加上前一位的进位

            int num = i*arr[j]+carry;

            // 计算出当前位的值

            arr[j] = num % 10;

            // 计算出下一位的进位

            carry = num / 10;

        }

        while(carry)

        {

            arr[cnt++] = carry % 10;

            carry /= 10;

        }

    }

    for(int i=cnt-1; i>=0; i--)

    {

        printf("%d",arr[i]);

    }

    return 0;

}

    6、计算出100000的阶乘末尾有多少个零(思考阶乘末尾的0是如何产生的)。

#include

int main(int argc,const char* argv[])

{

          // 分析:结尾的是*10产生的,2*5产生的10,因为2是无限的,所以只要计算出能拆分出多个5就能计算出末尾有多少个0。

    int cnt = 0;

    for(int i=5; i<=100000; i++)

    {  

        int num = i;

        while(0 == num%5)

        {

            num/=5;

            cnt++;

        }

    }  

    printf("%d\n",cnt);

    return 0;

}

    附加题:编程解决约瑟夫出圈问题。41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。

#include

// 约瑟夫出圈问题

int main(int argc,const char* argv[])

{

    // 用数组代表每个人,值为0表示人活着,值为1表示人死了

    int arr[41] = {};

    // 记录活人的数量,当cnt等于2时结束自杀

    int cnt = 41;

    // 用来遍历数组

    int index = 0;

    // 用来计数

    int num = 0;

    // 开始自杀

    while(cnt > 2)

    {

        // 判断人是否活着

        if(0 == arr[index])

        {

            // 计数加1

            num++;

        }

        // 判断是否数到3

        if(num == 3)

        {

            // 杀死数到3的人

            arr[index] = 1;

            // 记数归0

            num = 0;

            // 人数减1

            cnt--;

        }

        // 下一个人,当数数组的末尾时要回头

        if(41 == ++index)

            index = 0;

    }

    // 找出活着的人

    for(int i=0; i<41; i++)

    {

        if(0 == arr[i])

        {

            printf("%d\n",i+1);

        }

    }

    return 0;

}

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/2990260.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-09-23
下一篇2022-09-23

发表评论

登录后才能评论

评论列表(0条)

    保存