C语言 基于结构体的程序设计(PTA)

本文介绍了C语言中结构体的使用,包括结构体变量的定义和引用,以及如何通过结构指针传递结构数据。实验内容涵盖计算职工工资、学生平均成绩、最高总分学生、通讯录管理和复数运算等实际问题,通过编程实现解决这些任务,锻炼了对结构体和数组的操作能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、实验目的

1.掌握C语言中结构体类型的定义和结构体变量的定义和引用。

2.掌握用结构指针传递结构数据的方法。

二、实验内容

1、 计算职工工资

给定N个职员的信息,包括姓名、基本工资、浮动工资和支出,要求编写程序顺序输出每位职员的姓名和实发工资(实发工资=基本工资+浮动工资-支出)。

输入格式:输入在一行中给出正整数N。随后N行,每行给出一位职员的信息,格式为“姓名 基本工资 浮动工资 支出”,中间以空格分隔。其中“姓名”为长度小于10的不包含空白字符的非空字符串,其他输入、输出保证在单精度范围内。

输出格式:按照输入顺序,每行输出一位职员的姓名和实发工资,间隔一个空格,工资保留2位小数。

2、 计算平均成绩

给定N个学生的基本信息,包括学号(由5个数字组成的字符串)、姓名(长度小于10的不包含空白字符的非空字符串)和成绩([0,100]区间内的整数),要求计算他们的平均成绩,并顺序输出平均线以下的学生名单。

输入格式:输入在一行中给出正整数N(≤10)。随后N行,每行给出一位学生的信息,格式为“学号 姓名 成绩”,中间以空格分隔。

输出格式:首先在一行中输出平均成绩,保留2位小数。然后按照输入顺序,每行输出一位平均线以下的学生的姓名和学号,间隔一个空格。

3、 找出总分最高的学生

给定N个学生的基本信息,包括学号(由5个数字组成的字符串)、姓名(长度小于10的不包含空白字符的非空字符串)和3门课程的成绩([0,100]区间内的整数),要求输出总分最高学生的姓名、学号和总分。

输入格式:输入在一行中给出正整数N(≤10)。随后N行,每行给出一位学生的信息,格式为“学号 姓名 成绩1 成绩2 成绩3”,中间以空格分隔。

输出格式:在一行中输出总分最高学生的姓名、学号和总分,间隔一个空格。题目保证这样的学生是唯一的。

4、 通讯录的录入与显示

通讯录中的一条记录包含下述基本信息:朋友的姓名、出生日期、性别、固定电话号码、移动电话号码。 本题要求编写程序,录入N条记录,并且根据要求显示任意某条记录。

输入格式:输入在第一行给出正整数N(≤10);随后N行,每行按照格式姓名 生日 性别 固话 手机给出一条记录。其中姓名是不超过10个字符、不包含空格的非空字符串;生日按yyyy/mm/dd的格式给出年月日;性别用M表示“男”、F表示“女”;固话和手机均为不超过15位的连续数字,前面有可能出现+。

在通讯录记录输入完成后,最后一行给出正整数K,并且随后给出K个整数,表示要查询的记录编号(从0到N−1顺序编号)。数字间以空格分隔。

输出格式:对每一条要查询的记录编号,在一行中按照姓名 固话 手机 性别 生日的格式输出该记录。若要查询的记录不存在,则输出Not Found。

5、 复数四则运算

本题要求编写程序,计算2个复数的和、差、积、商。

输入格式:输入在一行中按照a1 b1 a2 b2的格式给出2个复数C1=a1+b1i和C2=a2+b2i的实部和虚部。题目保证C2不为0。

输出格式:分别在4行中按照(a1+b1i) 运算符 (a2+b2i) = 结果的格式顺序输出2个复数的和、差、积、商,数字精确到小数点后1位。如果结果的实部或者虚部为0,则不输出。如果结果为0,则输出0.0。

6、 考试座位号

每个 PAT 考生在参加考试时都会被分配两个座位号,一个是试机座位,一个是考试座位。正常情况下,考生在入场时先得到试机座位号码,入座进入试机状态后,系统会显示该考生的考试座位号码,考试时考生需要换到考试座位就座。但有些考生迟到了,试机已经结束,他们只能拿着领到的试机座位号码求助于你,从后台查出他们的考试座位号码。

输入格式:输入第一行给出一个正整数 N(≤1000),随后 N 行,每行给出一个考生的信息:准考证号 试机座位号 考试座位号。其中准考证号由 16 位数字组成,座位从 1 到 N 编号。输入保证每个人的准考证号都不同,并且任何时候都不会把两个人分配到同一个座位上。

考生信息之后,给出一个正整数 M(≤N),随后一行中给出 M 个待查询的试机座位号码,以空格分隔。

输出格式:对应每个需要查询的试机座位号码,在一行中输出对应考生的准考证号和考试座位号码,中间用 1 个空格分隔。

三、实验源程序及结果截图

1、求最大值及其下标

#include <stdio.h>

int main()
{
    int n,i,j,max,a[10];
    do
    {
        scanf("%d",&n);
    }while(n <= 1 || n > 10);       //限制输入的n的范围
    for(i = 0;i < n;i++)
    {
        scanf("%d",&a[i]);        //通过循环输入数组a的初值
    }
    max = a[0];                 //令max初值等于数组a的第一个值
    j = 0;                       // j表示max的值对应的数组a内的下标
    for(i = 0;i < n;i++)
    {
        if(a[i] > max)
        {
            max = a[i];          //通过循环使数组a的每一个数都与max进行比较,
            j = i;                 当a[i]>max时将该值赋给max,并且将其下标i赋
        }                        给j
    }
    printf("%d %d",max,j);        //输出最大值及其对应的下标
    return 0;
}

2、冒泡法排序 

#include <stdio.h>

int main()
{
    int k,n,i,j,l,a[100];
    do
    {
        scanf("%d %d",&n,&k);
    }while(k < 1 || n > 100 || k >= n);      //控制输入的n和k的大小
    for(i = 0;i < n;i++)
    {
        scanf("%d",&a[i]);             //通过循环输入数组a的初值
    }
    for(i = 0;i < k;i++)                 //扫描k次
    {
        for(j = 0;j < n - i - 1;j++)       //每一次扫描,扫描第i+1个数后面的所有数
        {                           即循环n - i - 1次
            if(a[j+1] < a[j])
            {
                l = a[j+1];
                a[j+1] = a[j];        //如果前一个数大于后一个数则进行交换
                a[j] = l;
            }
        }
    }
    for(i = 0;i < n;i++)
    {
        if(i != n - 1)           //当输出的数不是数组的最后一个数时输出数字加空格
        printf("%d ",a[i]);
        else                //当输出的数是数组的最后一个数时仅输出数字
        printf("%d",a[i]);
    }
    return 0;
}

3、数组循环左移 

#include <stdio.h>

int main()
{
    int n,m,i,j,lin,a[100];
    do
    {
        scanf("%d %d",&n,&m);
    }while(n > 100 || n < 1 || m < 0);    // 控制输入的n和m的大小
    for(i = 0;i < n;i++)
    {
        scanf("%d",&a[i]);          //通过循环输入数组a的初值
    }
    for(i = 0;i < m;i++)              //循环m次使数组内容左移m次
    {
        lin = a[0];                 //把数组a的第一个值赋给临时变量lin
        for(j = 0;j < n-1;j++)        //利用循环使数组a第2到第n个数左移一位
        {
            a[j] = a[j+1];
        }
        a[n-1] = lin;               //将lin的值赋给数组a的最后一个数
    }
    for(i = 0;i<n;i++)
    {
        if(i != n-1)           //当输出的数不是数组的最后一个数时输出数字加空格
        printf("%d ",a[i]);
        else                //当输出的数是数组的最后一个数时仅输出数字
        printf("%d",a[n-1]);
    }
    return 0;
}

4、将数组中的数逆序存放 

#include <stdio.h>

int main()
{
    int n,i,lin,a[10];
    do
    {
        scanf("%d",&n);
    }while(n<1 || n>10);            //控制n的范围
    for(i = 0;i < n;i++)
    {
        scanf("%d",&a[i]);             //通过循环输入数组a的初值
    }
    for(i=0;i < n/2;i++)
    {
        lin = a[i];               //将数组a的第i个数的值赋给变量lin
        a[i] = a[n-1-i];  //将与第i个数关于中心对称的数即第n-i-1个数的值赋给第i个数
        a[n-1-i] = lin;   //将lin的值赋给第n-i-1个数
    }
    for(i = 0;i<n;i++)
    {
        if(i != n-1)           //当输出的数不是数组的最后一个数时输出数字加空格
        printf("%d ",a[i]);
        else                //当输出的数是数组的最后一个数时仅输出数字
        printf("%d",a[i]);
    }
    return 0;
}

5、查找整数 

#include <stdio.h>

int main()
{
    int n,x,i,j=0,a[20];
    do
    {
        scanf("%d %d",&n,&x);
    }while(n > 20 || n <= 0);            //控制n的范围
    for(i = 0;i < n;i++)
    {
        scanf("%d",&a[i]);            //通过循环输入数组a的初值
    }
    for(i=0;i<n;i++)
    {
        if(a[i] == x)
        {
            printf("%d",i);           //如果数组a中存在x则输出该数
            j++;                   // j 的初值为0,若存在则j加一,若不存在则j=0
        }
    }
    if(j == 0)                      //若j=0 则说明不存在该数
    printf("Not Found");
    return 0;
}

 6、矩阵运算

#include <stdio.h>

int main()
{
    int n,i,j,sum = 0,a[10][10];
    do
    {	
        scanf("%d",&n);
    }while(n <= 1 || n > 10);            //控制n的范围
    for(i = 0;i < n;i++)
    {
        for(j = 0;j < n;j++)
        {
            scanf("%d",&a[i][j]);            //通过循环输入数组a的初值
        }
    }
    for(i = 0;i < n-1;i++)
    {
        for(j = 0;j < n-1;j++)
        {
            if(i + j != n - 1)   // i+j不等于 n-1即为除副对角线、最后一列最后一行的数
            sum = sum + a[i][j];    //求和
        }
    }
    printf("%d",sum);            //输出和
    return 0;
}

7、求矩阵各行元素之和 

#include <stdio.h>

int main()
{
    int n,m,i,j,sum[6]={0,0,0,0,0,0},a[6][6];
    do
    {
        scanf("%d %d",&m,&n); 
    }while(n<1 || n>6 || m<1 || m>6);           //控制n和m的范围
    for(i = 0;i < m;i++)
    {
        for(j = 0;j < n;j++)
        {
            scanf("%d",&a[i][j]);           //通过循环输入数组a的初值
        }
    }
    for(i = 0;i < m;i++)                    //共有m行,循环求和m次
    {
        for(j = 0;j < n;j++)
        {
            sum[i] = sum[i] + a[i][j];     //求第i+1行的和并赋值到数组sum的第i个数
        }
        printf("%d\n",sum[i]);         //输出各行的和
    }
    return 0;
}

 8、字符串逆序

#include <stdio.h>
#include <string.h>

int main()
{
    char ch[81];           //定义字符数组ch
    int i,j,lin,n;
    gets(ch);              //输入字符数组ch的初值
    n = strlen(ch);          //n等于ch的长度
    for(i = 0;i < n/2;i++)     //进行倒序
    {
        lin = ch[i];         //将数组ch的第i个数的值赋给变量lin
        ch[i] = ch[n-1-i];  //将与第i个关于中心对称的数即第n-i-1个数的值赋给第i个
        ch[n-1-i] = lin;    //将lin的值赋给第n-i-1个数
    }
    puts(ch);        //输出ch
    return 0;
}

9、字符串转换成十进制整数 

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
char a[100000];
char b[140000];
int zhuanhuan(char s,int i,int len);      //声明函数zhuanhuan
int main()
{
      int i = 0,j = 0;
      int flag = 0;
      scanf("%s",a);             //输入字符串a
      int len = strlen(a);          //定义并将a的长度赋值给变量len
      while(i < len)              //通过循环对字符串a进行逐字符转换
      {
          if(flag == 0 && j == 0 && a[i] == '-')   //当第一个字符为“-”时
          {
              flag = 1;
              i++;
          }
          if(a[i] >= '0'&&a[i] <= '9')          //当字符为数字时
          {
              b[j++] = a[i];
i++;
          }
          else if((a[i] >= 'a'&&a[i] <= 'f')||(a[i] >= 'A'&&a[i] <= 'F'))    //当字符为字母时
          {
              b[j++] = a[i];
              i++;
          }
          Else                //当字符为其他字符时
              i++;
      }
      int sum = 0;
      len = strlen(b);
      i = 0;
      int m;
      while(i < len)
      {
          m = zhuanhuan(b[i],i,len);
          sum = sum+m;
          i++;
      }
      if(flag == 1&&sum!=0)
          printf("-");
      printf("%d\n",sum);              // 输出转换完后的值
      return 0;
}
int zhuanhuan(char s,int i,int len)       //字符为不同内容时的转换
{
      if(s >= '0'&&s <= '9')
          return (s-'0')*pow(16,(len-i-1));
      if(s == 'a'||s == 'A')
          return 10*pow(16,(len-i-1));
      if(s == 'b'||s == 'B')
          return 11*pow(16,(len-i-1));
      if(s == 'c'||s == 'C')
          return 12*pow(16,(len-i-1));
      if(s == 'd'||s == 'D')
          return 13*pow(16,(len-i-1));
      if(s == 'e'||s == 'E')
          return 14*pow(16,(len-i-1));
      if(s == 'f'||s == 'F')
          return 15*pow(16,(len-i-1));
      return  0;
}

10、字符串循环左移  

#include <stdio.h>
#include <string.h>

int main()
{
      char ch[101];          //定义字符数组ch
      int a,len,temp,i,j;
      gets(ch);         //输入字符数组ch的初值
      scanf("%d",&a);         //输入变量a的初值(需要移动的位数)
      len = strlen(ch);         //变量len等于字符数组ch的长度
      for(i = 0;i < a;i++)       //循环a次使数组内容左移a次
      {
      temp = ch[0];        //把数组ch的第一个值赋给临时变量temp
          for(j = 0;j < len - 1;j++)  //利用循环使数组ch第2到第len个值左移一位
          {
              ch[j] = ch[j + 1];
          }
          ch[len - 1] = temp;        //将temp的值赋给字符数组ch的最后一个值
      }
      printf("%s",ch);            //输出移动后的结果
      return 0;
}

四、实验的分析与思考

1、求最大值及其下标

先定义一个最大值max,并将第一个数的值赋给最大值max,然后利用循环使每一个数字与max进行对比,如果大于max则将其赋值给max,并将其下标赋给变量j。

2、冒泡法排序

先定义一个临时变量lin,并将第一个数的值赋给最大值lin,然后利用循环使每一个数字与下一个数字进行对比,如果前一个数大于后一个数则进行交换。最后输出结果。

3、数组循环左移

定义一个临时变量lin,将第一个值赋给lin,然后将后面的数依次向左移动一位。循环指定次数。

4、将数组中的数逆序存放

以数组中中间的数为中心,将两端的数进行对换。

5、查找整数

定义一个变量,并赋初值为0,当数组中存在要查找的数时该变量加一,若最终该变量为0,则说明不存在该数字。

6、矩阵运算

找出矩阵除副对角线、最后一列和最后一行以外的所有元素之间的关系,然后进行求和。

7、求矩阵各行元素之和

定义一个和的数组,每个元素代表一行的和,分别对每行求和,然后输出。

8、字符串逆序

以字符数组中中间的字符为中心,将两端的字符进行对换。

9、字符串转换成十进制整数

如果在第一个十六进制字符之前存在字符“-”,则代表该数是负数,应首先对其进行判断,然后根据字符类型进行分类,最后转换成十进制数并求和,输出。

10、字符串循环左移

定义一个临时变量temp,将第一个值赋给temp,然后将后面的字符依次向左移动一位。循环指定次字符。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力敲代码呀~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值