第四次集训

190 阅读5分钟

数组

  • 为什么需要数组?

    • 为了解决大量同类型数据的存储和使用问题
    • 为了模拟现实世界
  • 数组的分类

    • 一维数组(线)

      • 定义 : 1.为n个变量连续分配存储空间

      2.所有的变量数据类型必须相同

      3.所有变量所占的字节大小必须相等

      例子:

      int a[5];

      有关一维数组的操作

      • 初始化

        • 完全初始化

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

        • 不完全初始化,未被初始化的元素自动为零

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

        • 不初始化,所有元素是垃圾值

        int a[5];

        • 清零

        int a[5] = {0};

        • 错误写法: int a[5];

        a[5] = {1,2,3,4,5};//错误

        只有在定义数组的同时才可以整体赋值, 其他情况下整体赋值都是错误的

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

        a[5] = 100;//error 因为没有a[5]这个元素,

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

        int b[5];

        如果要把a组数全部赋值给b组数组

        错误的写法:

        b = 2;//error

        正确的写法

        for(i = 0;i<5;++i) b[i] = a[i];

      • 赋值

      • 排序

      • 求最大/最小值

      • 倒置

      • 查找

      • 插入

    • 二维数组(面)

      • int a[3] [4]; 总共是12个元素,可以当做3行4列看待,这12个元素名字依次是

    a[0][0] a[0][1] a[0][2] a[0][3]

    a[1][0] a[1][1] a[1][2] a[1][3]

    a[2][0] a[2][1] a[2][2] a[2][3]

    a[i][j] 表示第i+1行 j+1列

    int a[m][n] 该二维数组右下角位置的元素只能是a[m-1][n-1]

-初始化

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}
                  };
                   

输出二维数组的内容

#include<stdio.h>
int main (void)

{
    int a[3][4] = {
        {1,2,3,4},
        {5,6,7,8},
        {9,10,11,12}

    };
    int i,j;

    for (i = 0;i<3;++i)
    {
        for (j = 0;j<4;++j)
            printf("%d\n",a[i][j]);
            printf("/n");
    }

        return 0;

}
  • 对二维数组排序
  • 求每一行的最大值
  • 判断矩阵是否对称
  • 矩阵的相乘

多维数组(空间或者加上时间)

  • 是否存在多维数组

    不存在

    • 因为内存是线性唯一的

    • n维数组可以当做每个元素是n-1维数组的一维数组

      比如: int a[3] [4];

      该数组是含有3个元素的一维数组
      
      只不过每个元素都可以再分成4个小元素
      

      int a[3] [4] [5];

      该数组是含有3个元素的一维数组
      
      只不过每个元素都是4行5列的二维数组
      

函数

  • 为什么需要函数?

    • 避免了重复性操作
    • 有利于程序的模块化
  • 什么叫函数?

    • 逻辑上:能够完成特定功能的独立代码单元

    • 物理上:能接受数据(当然也可以不接受数据

      能够对接受的数据进行处理

      能够将数据处理的结果返回(当然也可以不返回任何值

      • 总结:函数是个工具,它是为了解决大量类似问题而设计的

        函数可以当做一个黑匣子

  • 如何定义函数

    • 函数的返回值 函数的名字(函数的形象列表)

    { 函数的执行体 }

    1.函数定义的本质是详细描述函数之所以能够实现某个特定功能的具体方法

    2.return表达式:

    • 终止被调函数,向主调函数返回表达式的值,不向被调函数返回任何值

    • 如果表达式为空,则只终止函数,不向被调函数返回任何值

    • break是用来终止循环和Switch的,return是用来终止函数

    例子:

    void (f)
    {
            return;//return只用来终止函数,不想被调函数返回任何函数值
    }
    
    int (f)
    {
        return 10//终止函数且向被调函数返回10
    }
    

3.函数返回值的类型也称为函数的类型,因为如果函数名前的返回值类型和函数执行体中的return表达式;表达式的类型不同的话,则最终函数返回值的类型以函数名前的返回值类型为准

附两张程序运行图说明:最终函数返回值的类型以函数名前的返回值类型为准

image.png

image.png

  • 函数分类

    • **有参函数和无参函数

    • 有返回值 和 无返回值函数

    • 库函数 和 用户自定函数

    • 普通函数 和 主函数(main函数)**

      • 一个程序必须有且只能有一个主函数

      • 主函数可以调用普通函数 普通函数不能调用主函数

      • 普通函数可以相互调用

      • 主函数是程序的入口,也是出口*

  • 注意的问题

    • 函数调用和函数定义的顺序

      • 如果函数调用写在了函数定义的前面,则必须加函数前置声明

      • 函数前置声明:

        1.告诉编译器即将可能出现的若干个字母代表的是一个函数

        2.告诉编译器即将可能出现的若干个字母所代表的函数的形参和返回值的具体情况

        3.函数声明是一个语句,末尾必须加分号

        4.对库函数的声明是通过 #include <库函数>来实现的和声明的系统函数

形参和实参

6af643860944dc21f6b44815c8143c4.jpg 个数相同;位置一一对应;数据类型必须相互兼容

  • 如何在软件开发中合理的设计函数来解决实际问题

    • 一个函数的功能尽量独立,单一

函数是C语言的基本单位

  • 常用的系统函数

    • double sqrt (double x);

      求的x的平方根

    • double fabs (double x)

      求x的绝对值

    • int abs(int x)

      求x的绝对值

专题:

递归

  • 变量的作用域和存储方式

    • 按作用域分:

      • 全局变量

        -在所有函数外部定义的变量

      • 使用范围:从定义开始到整个程序结束

      • 局部变量

        -在一个函数内部定义的变量或者函数的行参 都统称为局部变量

  • 按变量的存储方式

    • 静态变量

    • 自动变量

    • 寄存器变量

代码实操

1.数组的倒置

int main(void)
{
    int a[7] = {1,2,3,4,5,6,7};
    int i,j;
    int t;

    i = 0;
    j = 6;
    while (i<j)
    {
        t = a[i];
        a[i] = a[j];
        a[j] = t;

        i++;
        --j;
    }

    for (i = 0;i<7;++i)
        printf ("%d\n",a[i]);

return 0;
}

d0d0e324e8c5ed7df0abe97c4abd13f.png

2.二维数组的使用

4aade65bc14fc167c1c8aab91b89be0.png

int main (void)

{
    int a[3][4] = {
        {1,2,3,4},
        {5,6,7,8},
        {9,10,11,12}

    };
    int i,j;

    for (i = 0;i<3;++i)
    {
        for (j = 0;j<4;++j)
            printf("%d\n",a[i][j]);

    }

        return 0;


}

3.break和return的区别

break image.png

#include <stdio.h>

void f(void)
{
    int i;

    for (i = 0;i<5;++i)
    {
        printf("花哥真美丽!\n");
        break;
    }
    printf ("花哥是腊梅!\n");
}

int main(void)
{
    f();
    return 0;
}

return

#include <stdio.h>

void f(void)
{
    int i;

    for (i = 0;i<5;++i)
    {
        printf("花哥真美丽!\n");
        return;
    }
    printf ("花哥是腊梅!\n");
}

int main(void)
{
    f();
    return 0;
}

image.png

总结 :break终止循环语句
return终止函数

4.** 素数的判断**

#include<stdio.h>

int main(void)
{
    int val;
    int i;

    scanf ("%d",&val);
    for (i = 2; i<val;++i)
    {
        
        if (val % i == 0 )
        {
            break;
        }
        
    }
if (i == val)
    printf ("Yes!\n");
else 
    printf("No!\n");

    return 0;
}

image.png 5.**** 函数实例****

#include <stdio.h>

int f(int i)
{
    return 10.8;
}

int main (void)
{
    float i = 99.9;

    printf ("%f\n",i);
    i = f(5);
    printf ("%f\n",i);

    return 0;
}

image.png

(可以从这个例子得出程序无法精确存储浮点数)

习题集

image.png 1.

int main(void)

{
    char a,b,c,d,t;
    while(scanf("%c%c%c%*c",&a,&b,&c,&t)!=EOF) //%后的"*"为附加说明符,用来表示跳过相应的数据
     {
         if (a>b)
         {
             d = b;
             b = a;
             a = d;
         }
         if (b>c)
         {
             d = c;
             c = b;
             b = d;
         }
         if (b>c)
         {
             d = c;
             c = b;
             b = d;
         }
         if (a>b)
         {
             d = b;
             b = a;
             a = d;
         }
         printf ("%c %c %c\n",a,b,c);
         
     }
     return 0;
}

解题思路:首先题目要求(输入数据有多组,每组占一行,有三个字符组成,之间无空格。)且要求(输入三个字符后,按各字符的ASCII码从小到大的顺序输出这三个字符。)所以第一时间想到网课中三个变量互换位置,然后用if语句不断判断三个字符的大小,将最小的排在最前即可

2.计算两点间的距离

#include <math.h>

int main(void)
{
        double d[4];
        while(scanf("%lf %lf %lf %lf",d,d+1,d+2,d+3)==4)
    {
        d[0] = (d [2]-d[0])*(d[2]-d[0])+(d[3]-d[1])*(d[3]-d[1]);
        d[0] = sqrt(d[0]);
        printf ("%.2f\n",d[0]);
    }
return 0;
}

解题思路:输入两点坐标(X1,Y1),(X2,Y2),计算并输出两点间的距离。输入数据有多组,每组占一行,由4个实数组成,分别表示x1,y1,x2,y2,数据之间用空格隔开。

3.计算球体积

#include<math.h>
#define PI 3.1415927

int main (void)
{   
    double R,V;
   while(scanf ("%lf",&R)!=EOF)
{  
    V = 4.0/3.0 * PI * R * R * R;
    printf ("%.3f\n",V);
}
    return 0;
}

解题思路:这道题很简单,唯一注意就是题目是需要输入两组数据,所以需要用while循环,再用!=EOF跳出相应数据,再从数学库引出体积公式即可

4.求绝对值

#include<math.h>

int main (void)
{
double a,b;
while(scanf("%lf",&a)!=EOF)
{
    b = fabs(a);
    printf ("%.2f\n",b);
}
    return 0;
}

解题思路:首先想到运用函数解题,从数学库引出fabs函数来对浮点数取绝对值,因为需要输入多组数据,采用循环即可。

5.成绩转换

#include <stdio.h>

int main(void)
{   
    int score;

    while (scanf("%d",&score)!=EOF)
    {
    if (score>100 || score<0)
        printf ("Score is error!\n");
    else if (score >= 90 && score <= 100)
            printf ("A\n");
    else if (score >= 80 && score < 90)
            printf ("B\n");
    else if (score >= 70 && score < 80)
            printf ("C\n");
    else if (score >= 60 && score < 70)
            printf ("D\n");
    else 
            printf ("E\n");
    }
    return 0;
}

解题思路:很简单,直接写的,没思路。但是有个小技巧,第一行直接将大于100和小于0的情况总结在一起,最后就可以用else写

6.第几天?

#include<stdio.h>
int main()
{
 int y, m, d, n;
 while (~scanf("%d/%d/%d", &y, &m, &d))
 {
  if (m == 1)
   n = d;
  else if (m == 2)
   n = 31 + d;
  else if (m == 3)
   n = 31 + 28 + d;
  else if (m == 4)
   n = 31 + 28 + 31 + d;
  else if (m == 5)
   n = 31 + 28 + 31 + 30 + d;
  else if (m == 6)
   n = 31 + 28 + 31 + 30 + 31 + d;
  else if (m == 7)
   n = 31 + 28 + 31 + 30 + 31 + 30 + d;
  else if (m == 8)
   n = 31 + 28 + 31 + 30 + 31 + 30 + 31 + d;
  else if (m == 9)
   n = 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + d;
  else if (m == 10)
   n = 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + d;
  else if (m == 11)
   n = 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + d;
  else if (m == 12)
   n = 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + d;
  if ((y%4==0&&y%100!=0||y%400==0)&&m>=3)
   n = n + 1;
  printf("%d\n", n);
 }
 return 0;
}

解题思路:有点做不来,就把十二个月的各种情况都一一例举(先默认该年是闰年),采用if语句,符合条件,就进入对应语句执行。再从网上四年一闰,百年不闰,四百年再闰。即可筛选出闰年。最后在2月天数加1即可

7.求奇数的乘积

#include <stdio.h>
int main()
{
    int n, number, multiplication;
    while( scanf( "%d", &n) != EOF )
    {
        multiplication = 1;
        for( int i=1; i<=n; i++)
        {
            scanf( "%d", &number );
            if( number%2 == 1 ) multiplication*=number;
        }
        printf( "%d\n", multiplication );
    }
}

解题思路:题目要求“包含多个测试实例”,说明要用while(scanf("%d",&n)!=EOF)循环进行嵌套。赋值multiplication=1需注意在while循环内、for循环外即可

8.平方和与立方和

#include<stdio.h>
int main()
{
    int m,n,x,y;
    while (scanf("%d %d",&m,&n)!=EOF)
    {
        x = 0;
        y = 0;
        for(int i=m;i<=n;i++)
        {
            if (i%2==0)
                x+=i*i;
            else
                y+=i*i*i;
        }
        printf ("%d %d\n",x,y);
    }
    return 0;
}

调试很多遍,一直通过不了,不知道哪里有问题