C语言基础⑦——数组

注意:strlen函数和sizeof的区别

一、数组的概念

1、什么是数组

数组是相同类型有序数据的集合。

2、数组的特征

  • 数组中的数据被称为数组的元素,是同构的;
  • 数组中的元素存放在内存空间里( char player_name[6] :申请在内存中开辟6块连续的基于char类型的变量空间)

衍生概念:下标(索引)

  • 下标或索引代表了数组中元素距离第一个元素的偏移位置;
  • 数组中元素的地址值,下标越大,地址值越大;(每一块内存空间都有一个独有的内存地址)
  • 数组的下标是从0开始的。

二、一维数组

double a;

int b;

a = 1/b; ===> a = ( 1.0/b );

1、数组的定义

类型说明符 数组名[数组容量]

说明:

  • 数组的类型说明符由数组中的元素来决定,也就是元素是什么类型,数组就是什么类型;
  • 数组名也是标识符,我们所说的数组(名),大家可以理解为数据类型是数组的变量(名)
  • 数组容量也可以叫做常量表达式,举例:int ages[10]、int lcd[1024*768];

类型:代表了数组中元素的类型;

容量:数组中能存储多少个元素,数组容量可以是一个常量、常量表达式,还可以是符号常量,但必须是整型

深入理解:
  • 定义一个数组,相当于申请了一个可以容纳所指定元素数量的内存单元,所申请的内存单元是连续的
  • 定义一个数组,相当于定义了多个匿名变量,这些变量可以通过 数组名[下标] 来标识;

举例:

//定义一个数组
int arr[10];
//上面数组中最小下标是0,最大下标是9
分析可得:
数组的最大下标 = 数组元素个数(数组容量) - 1;

2、数组元素的访问

原则:数组中的元素不能一次性访问所有元素,只能一个一个地访问

访问方式:

数组名[下标];

举例:

//定义一个容纳10个元素的int数组
int arr[10];
//给数组的第一个元素进行赋值
arr[0] = 89;
//访问数组的第一个元素
int a = arr[0];

//问题:以下访问是否正确?
int b = arr[10];//error,下标越界异常

注意:数组元素的访问一定不能越界。

举例:

/*
   需求:一维数组案例-引用数组元素。利用循环给数组元素a[0]~a[9]赋值0~9,并且逆序输出
 */
#include <stdio.h>
int main()
{
    // 创建一个数组
    int arr[10];
    // 使用for循环给数组赋值
    for(int i = 0;i < 10;i++)
   {
        arr[i] = i;        
   }
    // 逆序输出
    // 我们通过循环将数组中的元素一个个取出来,称之为遍历
    for(int j = 9;j >= 0;j--)
   {
        printf("%d ",arr[j]);
   }
    printf("\n"); // 纯粹换行
    return 0;
}

3、数组的初始化

定义数组的同时,用指定数据来给对应元素赋值

简化数组定义后,需要对元素一一赋值操作。

语法规则:

类型 数组名[容量] = {常量1,常量2,常量3,...}

注意:

  • 数组可以部分初始化,也就是可以给数组中前几个元素初始化,未被初始化的元素系统将自动初始化,如0;如果定义数组时未指定数据容量,则系统会根据初始化元素的个数来决定数组容量。
//1.如果只给数组前几个初始化,后续剩余元素会自动完成初始化,比如赋值0
int arr[10] = {1,2,3,4,5}//推荐写法,等价于以下写法
int arr[10] = {1,2,3,4,5,0,0,0,0,0}

//2.如果定义数组时未指定数据容量,根据初始化元素个数来决定容量
int arr[] = {1,2,3,4,5}//推荐写法,等价于以下写法
int arr[5] = {1,2,3,4,5}

衍生概念:

  • 柔性数组:柔性数组的概念是在C99标准,针对结构体的最后一个成员可以是一个未指定大小的数组(广义简单理解:数组容量待定或者待确定的数组,举例:int arr[] = {1,2,3,4,5});

面试题:

  • 在不知道数组类型的情况下,如何确定数组元素的个数
int length = sizeof(arr) / sizeof(a[0])//  整个数组的空间大小 / 一个数的空间大小

说明:

  1.  arr就是我们计算的数组本身, sizeof(arr) 用来计算该数组中总的字节大小。
  2.  sizeof(arr[0]) 用来计算数组中一个元素所占的字节大小,因为数组中的元素类型相同,所以计算哪一个都行;
  3.  sizeof(arr) / sizeof(arr[0]) 就是用数组中总的字节数除以每一个元素所占的字节数

4、数组的默认值

  • int 数组的默认值是 0
  • char(当用作字符时)数组的默认值是 /0
  • float 和 double 数组的默认值是 0.0

局部数组(非静态)

#include <stdio.h>  
  
int main() {  
    int intArray[5]; // 局部数组,未初始化,包含未定义的值  
    char charArray[5]; // 同样,未初始化,包含未定义的值  
    float floatArray[5]; // 未初始化,包含未定义的值  
    double doubleArray[5]; // 未初始化,包含未定义的值  
  
    // 打印这些数组的值将显示未定义的内容  
    // ...  
  
    return 0;  
}

全局或静态数组

#include <stdio.h>  
  
int globalIntArray[5]; // 全局数组,自动初始化为0  
static char staticCharArray[5]; // 静态数组,自动初始化为0  
  
int main() {  
    static float staticFloatArray[5] = {0}; // 显式初始化,但即使没有显式初始化也会是0.0  
    static double staticDoubleArray[5]; // 静态数组,自动初始化为0.0  
  
    // 打印这些数组的值将显示0或0.0  
    // ...  
  
    return 0;  
}

注意

在C++中,对于类类型的数组,如果你没有显式地初始化它们,并且它们是全局的或静态的,它们将使用默认构造函数(如果有的话)进行初始化。但是,对于基本数据类型(如intcharfloatdouble),上述规则仍然适用。

一维数组案例

举例:斐波拉契数列

/*
   需求:一维数组案例-非波拉契数列
 */
#include <stdio.h>
int main()
{
    int i;// 循环变量
    int f[20] = {1,1}; // 定义一个数组,用来存储数列,默认存储第1位和第2位
    
    int length = sizeof(f)/sizeof(f[0]);// 计算数组的元素个数  
    // 生出数列存入数组
    for(i = 2;i < length;i++)
   {
        // 给数组元素赋值,从数组的第3个元素开始
        f[i] = f[i - 2] + f[i - 1];
   }
    // 遍历数组
    // 通过循环将数组中的每一个元素取出来,称之为遍历
    for(i = 0;i < length;i++)
   {
        // 遍历的时候,要求一行显示5个数
        if(i % 5 == 0)
       {
            printf("\n");
       }
        
        printf("%6d",f[i]);
   }
    printf("\n");
    return 0;
}

6、数组的典型应用:数据排序

1.冒泡排序

  • 向后冒泡
思想:
  1. 一次只排好一个数,针对n个数,最差情况需要 n-1 次就可以排好;‘
  2. 每次排序将相邻数据两两比较,将较大或较小的数据向后交换,等所有数据都比较完成,将较大/较小的数就会出现在最后,这也是该数应有的位置;
  3. 在余下的数中,再次应用第2步的操作,直到只剩下一个数。
  • 向前冒泡
思想:
  1. 一次只排好一个数,针对n个数,最差情况需要 n-1 次就可以排好;‘
  2. 每次排序假定第个元素是最大/最小的,用第一个元素的后面的元素一一与第一个元素比较,遇到较大/较小的数和第一个元素交换,访问完数组的最后一个元素,就排好了一个数;
  3. 在余下的数中,再次应用第2步的操作,直到只剩下一个数。

一维数组案例

举例:冒泡排序_由小到大
/*
  需求:一维数组案例-冒泡排序
 */
#include <stdio.h>
int main()
{
    // 创建一个数组,用来存储排序的数列
    int arr[11];
    int i,j,temp;// i:比较的轮数,j:每一轮比较的次数,temp:临时变量,用来比较时交换数据
    
    printf("请输入11个测试整数:\n");
    
    // 计算数组的大小
    int length = sizeof(arr) / sizeof(int); // 这里 sizeof(int) 等价于 sizeof(arr[0]);
    // 通过循环录入数据
    for(i = 0;i < length; i++)
   {
       scanf("%d",&arr[i]);
   }
    
    printf("\n");
    // 对数组arr使用冒泡进行排序(注意:我们使用标准冒泡,大家也可以自行补充优化版的冒泡,如鸡尾酒排序法等等)
    
    // 外层循环:控制比较的轮数,因为有11个数,所以我们需要比较 length -1 轮,也就是比较10轮
    for(i = 0;i < length -1;i++)
   {
        // 内层循环:每一轮比较的次数,每一轮比较的次数为 length - 1 - i, 3-1-0=2,3-1-1=1,3-1-2=0
        for(j = 0;j < length-1-i;j++)
       {
            // 相邻的两个数进行比较,满足条件交换位置
            if(arr[j] > arr[j+1])
           {
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
           }
       }   
   }
    printf("冒泡排序后遍历数组:\n");
    for(i = 0; i < length; i++)
   {
        printf("%4d",arr[i]);
   }
    
    printf("\n");
    return 0;
}     

举例:输入年月日,计算并输出该日是该年的第几天
/*
   需求:一维数组案例-从键盘输入年、月、日,计算并输出该日是该年的第几天。
 */
#include <stdio.h>
int main()
{
    // 定义变量:年,月,日,统计总天数,循环变量,用来遍历当前月前面的月份
    int year,month,day,sum,k;
    // 定义一个数组,用来存放1~12月每月的天数
    int t[] = {31,0,31,30,31,30,31,31,30,31,30,31};// 柔性数组
    printf("请输入年份、月份、天:\n");
    scanf("%d,%d,%d",&year,&month,&day);
    // 因为二月比较特殊,存在平年和润年这样的因素,所以需要进行平年和润年的判断
    if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
   {
        t[1] = 29; // 润年 2月 29天
   }
    else
   {
        t[1] = 28; // 平年 2月 28天
   }
    sum = day; // 默认记录最后一个月的天数
       // 这是该年的第几天
    for(k = 0; k < month -1;k++)
   {
        sum += t[k]; // 叠加前几个月的天数
   }    
    printf("%d月%d日是%d年的第%d天。\n",month,day,year,sum);
    return 0;    
}

三、二维数组

1、定义

二维数组本质上是一个行列式的组合,也就是说二维数组是由两部分构成。二维数组数据是通过行列进行解读。

二维数组可被视为一个特殊的一维数组,相当于二维数组又是一个一维数组,只不过它的元素是一维数组。

2、语法(数组arr[],第row行,第col列)

类型 数组名[行数][列数];//这里的数是元素的个数,是数值,有n行n列

举例:

int arr[3][3] = {{1,2,3},{4,5,6},{7,8,9}};//等价于以下写法,这里的数是下标,从0-n
int arr[][] = {{1,2,3},{4,5,6},{7,8,9}};//柔性数组

int arr[3][] = {{1,2},{4,5,6},{7}}//等价于{{1,2,0},{4,5,6},{7,0,0}}

3、应用场合

主要应用于数据有行列要求的情况。

4、特殊写法

5、初始化

  • 分行给二维数组赋初值
int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}}
  • 可将所有数据写在一个花括号内,按照排列顺序对元素赋值
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};//等价于上面的写法
  • 可对部分元素赋初值,其余未赋值部分自动填充 0  |  \0  |  0.0...
int a[3][4] = {{1},{5,6},{9}};//等价于 int a[3][4] = {{1,0,0,0},{5,6,0,0},{9,0,0,0}}
  • 若对全部元素赋初值,自定义数组时可以省略第一维为数组的长度说明,第二维数组的长度必须指明。
int a[][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
  • 在分行赋初值时,也可以省略第一维的长度。
int a[][4] = {{1,2,3},{0},{0,10}}//等价于int a[][4] = {{1,2,3,0},{0,0,0,0},{0,10,0,0}}

举例:二维数组的遍历

/**
 * 案例:二维数组的遍历
 */
#include <stdio.h>
int main()
{
    int arr[][3] = {{1},{2,4},{5,6,7}};// 经过论证:二维数组我们必须指明第2维的数组的长度
    // 获取行元素的大小
    int length = sizeof(arr) / sizeof(arr[0]); // 如果是二维数组,第1维的长度,应该是如左侧这样获取
    printf("length:%d\n",length);
    // 遍历二维数组,需要使用双层for循环,外层遍历行,内层遍历每一行的列
    for(int row = 0;row < length;row++)
   {
        // 获取列元素的总大小
        int len = sizeof(arr[row]) / sizeof(int); 
        for(int col = 0; col < len; col++)
       {
            // 获取列元素
            printf("%3d",arr[row][col]);// 意思是获取数组arr 第row行第col列
       }
        
        printf("\n");
   }
    return 0;
}

举例:二维数组_矩阵的转置

/**
 * 需求:二维数组案例-矩阵的转置(就是将一个2行3列的数组转换为3行2列的数组)
 */
#include <stdio.h>
int main()
{
    // 准备2个数组,存放转前和转后的数据
    int arr_before[2][3] = {1,2,3,4,5,6};
    int arr_after[3][2] = {0};// 初始化,每一列上都是0
    // 遍历arr_before
    for(int i = 0;i < sizeof(arr_before)/sizeof(arr_before[0]);i++)
   {
        for(int j = 0;j < sizeof(arr_before[i])/sizeof(int);j++)
       {
            // 转置
            arr_after[j][i] = arr_before[i][j];
       }
   }
    
    // 遍历arr_after
    
    for(int i = 0;i < sizeof(arr_after)/sizeof(arr_after[0]);i++)
   {
        for(int j = 0;j < sizeof(arr_after[i])/sizeof(int);j++)
       {
            // 输出
            printf("%4d",arr_after[i][j]);
       }
        printf("\n");
   }
    return 0;
}

举例:准备一个int类型的二维数组,求该数组中大的最大值,以及对应的行号,列号

/**
 * 需求:二维数组案例-准备一个int类型的二维数组,求该数组中大的最大值,以及对应的行号,列号
 */
#include <stdio.h>
int main()
{
    // 准备一个二维数组
    int arr[3][4] = {{1,2,3,4},{9,8,7,6},{-10,10,-5,2}};
    // 创建变量,用保存最大值、行号、列号
    int max = arr[0][0],row=0,col=0;
    // 遍历集合
    for(int i = 0;i < sizeof(arr) / sizeof(arr[0]);i++)
   {
        for(int j = 0;j < sizeof(arr[i]) / sizeof(arr[i][0]);j++)
       {
            // 判断最大值
            if(arr[i][j] > max)
           {
                max = arr[i][j];
                row = i;
                col = j;
           }
       }
   }
    
    printf("max=%d,row=%d,col=%d\n",max,row,col);
    return 0;
}

四、字符数组

1、概念

元素类型为char字符型的数组,字符数组往往是用来存储字符串数据的。需要注意的一点是,我们C语言中的字符是字节字符

字节字符:也就是一个字符占1个字节

测试题:

char a = 'A';//true
char b = '1';//true
char c = 65;//true,这是ASCII编码,对应的值为'A'
char d = "A";//error,这是字符串的写法,也是char数组的写法,char d[1] = "A"
char e = '马';//error,中文一个字符超过一个字节

2、语法

char 数组名[容量];
char 数组名[行容量][列容量];

字符数组的语法就是之前所学一维数组和二维数组的语法,只不过数据类型是char而已。

注意:

如果我们的char数组初始化的时候,没有完全赋完值的时候,空出来的地方使用 \0 来填充。

举例:输出一个字符串(I love you!)

/**
 * 需求:字符数组案例-输出一个字符串(I LOVE YOU!)
 */
#include <stdio.h>
int main()
{
    // 准备一个测试字符串 I LOVE YOU!
    char arr[11] = {'I',' ','L','O','V','E',' ','Y','O','U','!'};
    // 通过一个for循环进行遍历输出
    for(int i = 0;i < sizeof(arr)/sizeof(char);i++)
   {
        printf("%c",arr[i]);
   }
    printf("\n");
    return 0;
}

举例:输出由字符组成的一个菱形图案

/**
 * 需求:字符数组案例-输出一个用字符组成的菱形图案
 */
#include <stdio.h>
int main()
{
    // 准备数据
    char arr[5][5] = {{' ',' ','*',' ',' '},{' ','*',' ','*',' '},{'*',' ',' ',' ','*'},{' 
','*',' ','*',' '},{' ',' ','*',' ',' '}};
    
    // 遍历数组
    for(int i = 0;i < sizeof(arr)/sizeof(arr[0]);i++)
   {
        for(int j = 0;j < sizeof(arr[i])/sizeof(char);j++)
       {
            // 打印菱形
            printf("%c",arr[i][j]);
       }
        
        // 内层循环每结束一轮,就是一行
        printf("\n");
   }
    
    printf("\n");
    return 0;
}

3、字符串和字符串结束标志

说明:

字符数组的多样表示

我们的char数组可以以数组的方式一个个输出每个字符;我们的char数组也可以以字符串的方式整体进行输出所有字符

举例:字符数组 --> 字符串

/*
   需求:字符数组->字符串
 */
#include <stdio.h>
int main()
{
    // 字符串第1种表示:
    char s1[] = {'h','e','l','l','o',' ','w','o','r','l','d'};
    // 字符串第2种表示:
    char s2[] = {"hello world"};
    // 字符串第3种表示:
    char s3[] = "hello world";
   // 测试,使用字符串方式打印,这样就不用一一遍历
    printf("%s\n",s1);
    printf("%s\n",s2);
    printf("%s\n",s3);
    return 0;
}

注意:

  • 字符串的长度与字符数组的长度不一定相同;
  • 利用字符串常量可以对字符数组进行初始化,但不能用字符串常量为字符数组赋值
// 正确写法:利用字符串常量给字符数组初始化
char b[15] = "China";
// 错误写法:利用字符串常量给字符数组赋值
char b[15];
b[15] = "China";

4、字符串的基础操作

1.字符串输入

  • scanf("%s",数组名)
举例:字符数组_字符串的输入输出
/*
 * 需求:字符数组-字符串的输入输出
 */
#include <stdio.h>
int main()
{
    // 创建一个变量,用来存放人的名字
    char name[20];
    printf("请输入您的姓名:\n");
   
    scanf("%s",name);// 如果是字符串,这里不是变量地址,是变量名
    printf("您的姓名是:%s\n",name);
    return 0;
}

注意:

采用scanf进行字符串输入,要求字符串中不能存在空格,否则字符串遇到空格会结束。

  • fgets(数组名,数组容量,stdin)
说明:

采用fgets进行字符串输入,可获取所有输入的字符串,包含 \n ,在实际的字符串处理时,我们 可能需要处理 \n

举例:字符数组_字符串的输入输出
/*
 * 需求:字符数组-字符串的输入输出
 */
#include <stdio.h>
int main()
{
    // 创建一个变量,用来存放人的名字
    char name[20];
    printf("请输入您的姓名:\n");
    
    fgets(name,sizeof(name)/sizeof(char),stdin);// 输入,返回地址
 
 puts(name);// 输出
    return 0;
}

注意:

  1. 如果输入的字符串不包含 空格 和 换行 ,可以使用scanf() | fgets();
  2. 如果输入的字符串需要包含 空格 和 换行 ,只能使用fgets();
  3. 经过对比,我们发现,在字符串的输入中,fgets()更好。

2.字符串输出

  • puts(数组名)
举例:字符数组_字符串的输入输出
/*
 * 需求:字符数组-字符串的输入输出
 */
#include <stdio.h>
int main()
{
    // 创建一个变量,用来存放人的名字
    char name[20];
    printf("请输入您的姓名:\n");
    
    scanf("%s",name);
 
 puts(name);// 输出 问题?字符串如何拼接
    printf("您的姓名是:%s\n",name);
    return 0;
}

  • printf("%s",数组名)
举例:字符数组_字符串的输入输出
/*
 * 需求:字符数组-字符串的输入输出
 */
#include <stdio.h>
int main()
{
    // 创建一个变量,用来存放人的名字
    char name[20];
    printf("请输入您的姓名:\n");
    
    scanf("%s",name);
 
    printf("您的姓名是:%s\n",name);
    return 0;
}

3.字符串拼接

  • strcat(数组名,"需要拼接的字符串")

注意:

需要引入 #include <string.h>

举例:字符数组_字符串的输入输出
/*
 * 需求:字符数组-字符串的输入输出
 */
#include <stdio.h>
#include <string.h>
int main()
{
    // 创建一个变量,用来存放人的名字
    char name[20];
    printf("请输入您的姓名:\n");
    
    fgets(name,sizeof(name)/sizeof(char),stdin);// 输入,返回地址
 
    puts(strcat(name," 跑着!"));// 拼接
    return 0;
}

4.字符串拷贝

  • strcpy(数组名,字符串)

注意:

需要引入<string.h>库

说明:这个方法适合给字符串赋值用。

char str[16] = "马杰克"  // true,初始化
char str[16]; str[16] = "马杰克"  //error, 赋值
char str[16]; strcpy(str,"马杰克")  // true,赋值,结果:马杰克
举例:字符数组_字符串的输入输出
/*
 * 需求:字符数组-字符串的输入输出
 */
#include <stdio.h>
#include <string.h>
int main()
{
    // 创建一个变量,用来存放人的名字
    char name[20];
    printf("请输入您的姓名:\n");
 
 scanf("%s",name);
    
    strcpy(name,"你好");
 
 printf("%s\n",name);// 输出
    return 0;
}

5.字符串比较

  • strcmp(字符串1,字符串2)

注意:

  1. 需要引入<string.h>
  2. 返回的结果是boolean
举例:字符数组_字符串的输入输出
/*
 * 需求:字符数组-字符串的输入输出
 */
#include <stdio.h>
#include <string.h>
int main()
{
    // 创建一个变量,用来存放人的名字
    char username[20];
    printf("请输入您的账户:\n");
 
 scanf("%s",username);
    
    if(strcmp(username,"admin"))
   {
 printf("账户输入错误!\n");
 }
 else
 {
 printf("账户输入正确!\n");
 }
 
    return 0;
}

7.获取字符串长度

  • strlen(字符串)

注意:

  1. 需要<string.h>
  2. 返回字符串长度
举例:字符数组_字符串的输入输出
/*
 * 需求:字符数组-字符串的输入输出
 */
#include <stdio.h>
#include <string.h>
int main()
{
    // 创建一个变量,用来存放人的名字
    char username[20];
    printf("请输入您的账户:\n");
 
 scanf("%s",username);
 
 // 获取字符串长度
 unsigned long len = strlen(username);
    
    if(strcmp(username,"admin"))
   {
 printf("账户输入错误!%lu\n",len);
 }
 else
 {
 printf("账户输入正确!%lu\n",len);
 }
 
    return 0;
}

四、作业

1、一维数组练习题

1. 键盘录入一组数列,利用冒泡排序将数据由大到小排序

代码:
 /*
 冒泡数列:由大到小排列
*/

#include <stdio.h>
int main()
{
    // 创建一个数组,用来存储排序的数列
    int arr[11];
    int i,j,temp;// i:比较的轮数,j:每一轮比较的次数,temp:临时变量,用来比较时>交换数据

    printf("请输入11个测试整数:\n");

    // 计算数组的大小
    int length = sizeof(arr) / sizeof(int); // 这里 sizeof(int) 等价于 sizeof(arr[0]);
    // 通过循环录入数据
    for(i = 0;i < length; i++)
   {
       scanf("%d",&arr[i]);
   }

    printf("\n");
    // 对数组arr使用冒泡进行排序(注意:我们使用标准冒泡,大家也可以自行补充优化
版的冒泡,如鸡尾酒排序法等等)

    // 外层循环:控制比较的轮数,因为有11个数,所以我们需要比较 length -1 轮,也
就是比较10轮
    for(i = 0;i < length -1;i++)
   {
        // 内层循环:每一轮比较的次数,每一轮比较的次数为 length - 1 - i, 3-1-0=2,3-1-1=1,3-1-2=0
        for(j = 0;j < length-1-i;j++)
       {
            // 相邻的两个数进行比较,满足条件交换位置
            if(arr[j + 1] < arr[j])
           {
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
           }
       }
   }
    printf("冒泡排序后遍历数组:\n");
    for(i = 0; i < length; i++)
   {
        printf("%4d",arr[i]);
   }

    printf("\n");
    return 0;
}
运行效果:

2. 从键盘输入年、月、日,计算并输出该日是该年第几天

代码:
 /*
   需求:一维数组案例-从键盘输入年、月、日,计算并输出该日是该年的第几天。
 */
#include <stdio.h>
int main()
{
    // 定义变量:年,月,日,统计总天数,循环变量,用来遍历当前月前面的月份
    int year,month,day,sum,k;
    // 定义一个数组,用来存放1~12月每月的天数
    int t[] = {31,0,31,30,31,30,31,31,30,31,30,31};// 柔性数组
    printf("请输入年份、月份、天:\n");
    scanf("%d,%d,%d",&year,&month,&day);
    // 因为二月比较特殊,存在平年和润年这样的因素,所以需要进行平年和润年的判断
    if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
   {
        t[1] = 29; // 润年 2月 29天
   }
    else
   {
        t[1] = 28; // 平年 2月 28天
   }
    sum = day; // 默认记录最后一个月的天数
       // 这是该年的第几天
    for(k = 0; k < month -1;k++)
   {
        sum += t[k]; // 叠加前几个月的天数
   }    
    printf("%d月%d日是%d年的第%d天。\n",month,day,year,sum);
    return 0;    
}
运行效果:

3. 键盘录入一组数列,求最大数、最小数、均值

代码:
/*
输入一组数列,求最大值,最小值,均值;
*/

#include <stdio.h>

int main()
{

    int n, i;
    int arr[5];//创建数组
    int max,min;//最大值,最小值  
    float sum = 0.0,aver,temp;//和,均值  

    printf("请输入数列的元素: ");

    int length = sizeof(arr)/sizeof(int);
    for (i = 0; i < length; i++)
    {
        scanf("%d", &arr[i]);
        // 初始化max和min为数列中第一个元素  
        if (i == 0)
        {
            max = min = arr[i];
        }
        if (arr[i] > max)//最大值 
        {
                max = arr[i];
        }
        else if(arr[i] <= min)
        {
                min = arr[i];//最小值  
        }
        sum += arr[i];
    }

    aver = sum / 5;

    printf("最大数是: %d\n", max);
    printf("最小数是: %d\n", min);
    printf("均值是: %.2f\n", aver);

    return 0;
}
运行效果:

4. 从键盘录入一组数列,判断是否是回文,举例:12321,abba,121

代码:
 /*
* 从键盘录入一组数列,判断是否是回文,举例:12321,abba,121
*/
#include <stdio.h>

int main()
{
    int arr[5];//创建数组
    int i;

    printf("请输入数列的元素:\n");

    for(i=0;i<5;i++)
    {
        scanf("%d",&arr[i]);//录入数组中的元素
    }

    if(arr[0]==arr[4] && arr[1]==arr[3])
    {
        printf("该数列是回文!");
    }
    else
    {
        printf("该数列不是回文!");
    }
}
运行效果:

5. 用数组存储10个整型数,通过键盘输入一个数,找出该数在数组中的下标值;

代码:
 /*
 用数组存储十个整数,通过键盘输入一个数,找出该数在数组中的下标值
*/
#include <stdio.h>

int main()
{
    int arr[10]={1,2,3,4,5,6,7,8,9,10};//定义数组
    int i,j,num=0;//定义变量

    for(int i = 0;i < 10;i++)//循环打印数组内元素
    {
        printf("%4d",arr[i]);
    }

    printf("请输入一个整数:\n");//输入整数
    scanf("%2d\n",&num);

    for(int j = 0;j < 10;j++)//输出输入整数对应的下标值
    {
        if(arr[j] == num)
        {            
             printf("您所输入的数在该数组中的下标值为:%d\n",num-1);
        }
    }
    return 0;
}
运行效果:

6. 通过键盘输入 10 个学员成绩,

1)输出不及格学员的成绩和下标。

2)求最高分的下标值

3)求最低成绩的下标值

4)求总成绩及平均成绩

代码:
 /*
*通过键盘输入十个学员成绩:1)输出不及格学员的成绩和下标;2)求最高分的下标值;3)
求最低成绩的下标值;4)求总成绩及平均成绩;
*/
#include <stdio.h>

int main()
{
    int n, i;
    int arr[10];//创建数组
    int max,min;//最高分,最低分  
    float sum = 0.0,aver;//总成绩,平均成绩  

    printf("请输入数列的元素: ");

    int length = sizeof(arr)/sizeof(int);
    for (i = 0; i < length; i++)
    {
        scanf("%d", &arr[i]);//输入学员成绩
        // 初始化max和min为数列中第一个元素  
        if (i == 0)
        {
            max = min = arr[i];
        }
        if (arr[i] > max)//最大值 
        {
            max = arr[i];
        }
        else if(arr[i] <= min)
        {
            min = arr[i];//最小值  
        }
        sum += arr[i];//总成绩
    }

    aver = sum / 10;//平均成绩

    for(int j = 0;j < 10;j++)
    {
        if(arr[j] <= 59)//不及格
        {
            printf("不及格成员的成绩和下标值为:%d,%d\n",arr[j],j);
        }
        if(arr[j] == max)
        {
            printf("最高分的下标值为:%d\n",j);
        }
        if(arr[j] == min)
        {
            printf("最低分的下标值为:%d\n",j);
        }
    }

    printf("总成绩为:%.2f\n",sum);
    printf("平均成绩是: %.2f\n", aver);

    return 0;
}
运行效果:

2、二维数组练习题

7. 一个二维数组赋了初值,用户输入一个数,在该二维数组中查找。找到则返回行列位置,没找到则 提示。

代码:
 /*
*一个二维数组赋了初值,用户输入一个数,在该二维数组中查找。找到则返回行列位置,>未找到则提示
*/
#include <stdio.h>

int main()
{
    int arr[3][3] = {{1},{2,3,4},{7,8,9}};//对二维数组赋初值
    int i,j;
    int num=arr[0][0];
    int row=-1;
    int col=-1;//i:数 ;num:输入的数;row:输入的数的行;col:输入的数的列
;
        printf("请输入一个整数:\n");
        scanf("%d",&num);

    int length = sizeof(arr)/sizeof(arr[0]);
    for(int i=0;i<length;i++)
    {
        //printf("请输入一个整数:\n");
        //scanf("%d",&num);

        for(int j=0;j < sizeof(arr[i])/sizeof(arr[i][0]);j++)
        {
            printf("%3d",arr[i][j]);
            if(num == arr[i][j])
            {
                num = arr[i][j];
                row = i;
                col = j;

            }
            //else 

            //    printf("未找到该数!\n");
               // break;

        }
    }

    if(row != -1)
    {
        printf("您所输入的数%2d的位置为:%2d行%2d列\n",num,row,col);
    }
    else
    {
        printf("未找到该数!\n");
    }

    return 0;
}
运行效果:

8. 二维整型数组,求所有元素平均值,求每行最大值,求每列最小值。

代码:
/*
*二维整型数组,求所有元素平均值,求每行最大值,求每列最小值
*/
#include <stdio.h>

int main()
{
    int arr[3][3] = {{1,2,3},{4,5,6},{7,8,9}};//对二维数组赋初值
    int i,j;
    float sum=0.0,aver=0;
    int max,min;
    int num=arr[0][0];
    int row=0;
    int col=0;//i:数 ;num:输入的数;row:输入的数的行;col:输入的数的列
;
       // printf("请输入一个整数:\n");
       // scanf("%d",&num);

    int length = sizeof(arr)/sizeof(arr[0]);
    int width = sizeof(arr[i])/sizeof(arr[i][0]);

    //行
    for(int i=0;i<length;i++)
    {
        max = arr[i][0];
        for(int j=0;j<width;j++)
        {
            printf("%5d",arr[i][j]);
            if(arr[i][j] > max)
            {
                max = arr[i][j];
            }
        sum += arr[i][j];
        }
        printf("第%d行的最大值为:%d\n",i+1,max);
        printf("\n");
    }


    for(int j=0;j<width;j++)
    {
        min = arr[0][j];
        for(int i=0;i<length;i++)
        {
            if(min > arr[i][j])
            {
                min = arr[i][j];
            }
        }
        printf("第%d列的最小值为:%d\n",j+1,min);
        printf("\n");
    }

    aver = sum / 9.0;
    printf("均值为:%.2f\n",aver);
    return 0;
}
运行效果:

9. 在行列相等数组计算主对角线元素的和

代码:
 /*
*在行列相等数组计算主对角线的和
*/
#include <stdio.h>

int main()
{
    int arr[3][3] = {{1,2,3},{4,5,6},{7,8,9}};//对二维数组赋初值
    int i,j;
    int sum=0;

    int length = sizeof(arr)/sizeof(arr[0]);
    int width = sizeof(arr[i])/sizeof(arr[i][0]);

    //行
    for(int i=0;i<length;i++)
    {
        for(int j=0;j<width;j++)
        {
            printf("%5d",arr[i][j]);
            if(i == j)
            {
                sum += arr[i][j];
            }
        }
        printf("\n");
    }

    printf("数组主对角线元素的和为:%d\n",sum);
    return 0;
}
运行效果:

10. 计算一个矩阵下三角元素的和

代码:
/*
*计算一个矩阵下三角的和
*/

#include <stdio.h>
int main()
{
    int arr[3][3] = {{9,8,7},{6,5,4},{3,2,1}};
    int i = 0;
    int sum = 0;

    int length = sizeof(arr) / sizeof(arr[0]);
    int width = sizeof(arr[i]) / sizeof(arr[i][0]);

    for(int i = 0;i < length;i++)
    {
        for(int j = 0;j < width;j++)
        {
            printf("%4d",arr[i][j]);
            if(i >= j)
            {
                 sum += arr[i][j];
            }
        }
        printf("\n");
    }
    printf("该矩阵下三角元素的和为:%d\n",sum);
    return 0;
}
运行效果:

11. 电影院为了答谢影迷的支持,在某一排的某一列座位上放置了一个大礼包,放置礼物的位置具有这 样的规则(行和列的平方和为开店日期 512(5月12日)); 请设计程序找出大礼包的位置,(假定电影院有20排,每排25个座位)

代码:
/*
*需求:电影院为了答谢影迷的支持,在某一排的某一列座位上放置了一个大礼包,
放置礼物的位置具有这样的规则(行和列的平方和为开店日期 512(5月12日));
请设计程序找出大礼包的位置(假定电影院有20排,每排25个座位)
*/
#include <stdio.h>

int main()
{
    int arr[20][25];
    int i,j;

    int length = sizeof(arr) / sizeof(arr[0]);
    int width = sizeof(arr[i]) / sizeof(arr[i][0]);

    for(i = 0;i<length;i++)
    {
         for(j = 0;j<width;j++)
         {
              if((i + 1) * (i + 1) + (j + 1) * (j + 1) == 512)
              {
                   printf("该大礼包在第%d行,第%d列\n",i + 1,j + 1);
              }
         }
    }
    return 0;
}

运行效果:

3、字符数组练习题

12. 编写一个程序,读取用户输入的字符串,并将其反转输出。

代码:
/***
*编写一个程序,读取用户输入的字符串,并将其反转输出
*/
#include <stdio.h>
#include <string.h>

int main()
{
    char str1[100] = {0};
    char str2[100] = {0};
    printf("请用户输入字符串:");
    scanf("%s",str1);
    int t = strlen(str1);
    for(int i =0;i < t;i++)
    {
         str2[i] = str1[t-1-i]; //直接从后往前置换
    }
    printf("字符串反转输出为:%s\n",str2);
    return 0;
}
运行效果:

13. 编写一个程序,判断用户输入的字符串是否为回文(即正反读都一样的字符串)。

代码:
/*
*编写一个程序,判断用户输入的字符串是否为回文(即正反读都一样的字符串)
*/
#include <stdio.h>
#include <string.h>

int main()
{
    int j,i,n;
    char str1[100],str2[100];

    printf("请输入字符串: ");
    scanf("%s",str1);   
    n=strlen(str1); 
   
    for(i=0,j=n-1;i<n;i++,j--)
    {
        str2[j] = str1[i];
    }

    for(i=0;i<n;i++)
    {
        if(str2[i] != str1[i])
        {
             break; 
        }
    }

    if(i==n)
    {
        printf("该字符串是回文!\n");      
    }
    else
    {
        printf("该字符串不是回文!\n");
    }
    return 0;
}
运行效果:

4、思考题【选做】:

14. 求出一个矩阵的鞍点。鞍点的含义为行上最大同时列上也最大。

代码:
 
运行效果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值