关于C中指向结构体数组的指针的应用

题目描述

设有30条手机销售信息,每条手机销售信息包括:编号(ID)、型号、品牌、销售价格、销售数量,依据所定义的结构体 struct phone,完成一下功能:

  1. 编写 void input(struct phone *p) 函数,实现从键盘输入这30条手机信息;
  2. 编写 void output1(struct phone *p) 函数,按照手机销售数量从高到低将所有手机销售信息进行排序,然后分行输出排序后的手机销售的信息;
  3. 编写 void output2(struct phone *p) 函数,实现将销售价格低于平均销售价格的手机信息保存到当前文件夹下的 “low_price.dat“ 文件中。
#include <stdio.h>
#include <stdlib.h>
#define N 30
struct phone {
    
    
  char ID[10];
  char model[12];
  char brand[12];
  float price;
  int num;
}

void input(struct phone *p);
void output1(struct phone *p);
void output2(struct phone *p);
void main() {
    
    
  struct phone st[N];
  input(st);
  output1(st);
  output2(st);
}

解答

注:下方代码并没有使用 p[i] 的格式遍历访问结构体数组,而是直接操作的指针。

执行 p++ 时,p 的值的增量是结构体 struct phone 的长度。p 加一意味着 p 所增加的值为结构体数组 phones 的一个元素所占的字节数,所以 p++ 后 p 的值等于 phones+1,即 p 此时指向 phones[1]。

个人解答如下:

#include <stdio.h>
#include <stdlib.h>

#define N 3 // 数据量

typedef struct pNode{
    
    
  int ID; // 编号
  char type[10];  // 型号
  char brand[20]; // 品牌
  float price;  // 销售价格
  int salesVolume;  // 销售数量
}Phone;

void input(Phone*);
void printf_phone(Phone*);
void sortAndOutput(Phone*);
void filterAndSave(Phone*);

int main() {
    
    
  Phone phones[N]={
    
    
    // * 此数据用于调试,避免多次在终端输入数据,还需注释掉下方的 input 方法
    // {101, "A11", "AAA", 111, 2},
    // {102, "A22", "AAA", 666, 10},
    // {103, "B11", "BBB", 12000, 6},
    '\0'
  };
  input(phones);
  printf_phone(phones);
  sortAndOutput(phones);
  filterAndSave(phones);

  return 0;
}

/**
 * 从终端中录入 N 条手机数据
 **/
void input(Phone *p) {
    
    
  printf("输入「%d组」手机编号、型号、品牌、销售价格、销售数量\n", N);
  for (int i=0; i<N; i++) {
    
    
    scanf("%d %s %s %f %d", &p->ID, p->type, p->brand, &p->price, &p->salesVolume);
    p++;
  }
}

/**
 * 按照「手机销量」从高到低将所有手机销售信息排序
 * 然后分行输出排序后的手机信息
 **/
void sortAndOutput(Phone *p) {
    
    
  Phone *t;
  t = (Phone*)malloc(sizeof(Phone));
  for (int i=0; i<N-1; i++) {
    
     // 冒泡排序
    for (int j=i+1; j<N; j++) {
    
    
      if ((p+i)->salesVolume < (p+j)->salesVolume) {
    
    
        *t = *(p+i);
        *(p+i) = *(p+j);
        *(p+j) = *t;
      }
    }
  }
  free(t);
  printf_phone(p);
}

/**
 * 将「销售价格」低于平均销售价格的手机信息
 * 保存到当前文件夹下的 low_price.data 文件
 **/
void filterAndSave(Phone *p) {
    
    
  float averagePrice=0;
  Phone *s;
  s=p;
  for (int i=0; i<N; i++, s++) {
    
     // 售价求和
    averagePrice += s->price;
  }
  averagePrice /= N;  // 取平均售价

  FILE *fp;
  if ((fp=fopen("./jida/3.6/low_price.dat", "w")) == NULL) {
    
    
    printf("无法打开此文件\n");
    exit(0);
  }
  fprintf(fp, "手机编号\t型号\t品牌\t销售价格\t销售数量\n");
  for (int i=0; i<N; i++, p++) {
    
      // 低于平均售价的存入文件
    if (p->price < averagePrice) {
    
    
      fprintf(fp, "%d, %s, %s, %.2f, %d\n", p->ID, p->type, p->brand, p->price, p->salesVolume);
    }
  }
  fclose(fp);
}

/**
 * 在终端中输出数组的所有数据
 **/
void printf_phone(Phone *p) {
    
    
  printf("手机编号\t型号\t品牌\t销售价格\t销售数量\n");
  for (int i=0; i<N; i++) {
    
    
    printf("%d, %s, %s, %.2f, %d\n", p->ID, p->type, p->brand, p->price, p->salesVolume);
    p++;
  }
  printf("\n\n");
}

猜你喜欢

转载自blog.csdn.net/yotcap/article/details/114708509