想知道如何将我的代码分成单独的函数

Want to know how to divide my code into separate functions

我最近开始在大学学习 C,今天我的任务是编写一个程序来计算结构数组中产品的平均价格。有人告诉我,我的代码应该分成单独的函数。 如何将 printf for 循环和平均价格 for 循环放在一个单独的函数中,然后在 main() 中调用它?

提前感谢您的回复。

#define n 2

struct products{

    char name[30];
    char brand[30];
    double price;
    int quantity;

};
int main()
{

    struct products products_arr[n];
    int i;
    float sum,avg;

    for (i=0;i<n;i++)
    {
        printf("Enter product/s:\n\n");

        printf("Enter product name: \n");
        scanf("%s",products_arr[i].name);

        printf("Enter product brand: \n");
        scanf("%s",products_arr[i].brand);

        printf("Enter product price: \n");
        scanf("%lf",&products_arr[i].price);

        printf("Enter product quantity: \n");
        scanf("%d",&products_arr[i].quantity);
    }

    for (i=0;i<n;i++)
    {
        printf("\n%s - %s - %.2lf - %d",products_arr[i].name,
              products_arr[i].brand,
              products_arr[i].price,
              products_arr[i].quantity);
        printf("\n");
    }


    for (i = 0; i < n; i++)
    {
        sum += products_arr[i].price;
    }

    avg = sum / n;
    printf("\nAverage = %.2f", avg);



    return 0;
}

这里是如何实现 avg 函数

double avg(struct products * prod, int sz){
    double sum = 0;
    for(int i = 0 ; i < sz; i++){
       sum += prod[i].price;
    }
    return sum / sz;
 }

注意你必须传递一个指向数组开头的指针,加上数组的大小

现在在 main 中调用它

  double average = avg(products_arr, n);

如果函数体在 main 函数体之后,则需要在 main 函数之前声明 avg

   double avg(struct products * prod, int sz);

您可以将其用作执行其他功能的模型

由于您正在学习 C,因此您现有的代码有几个注意事项。您真正的问题似乎是“如何将我的代码分成单独的函数”。

有两种基本方法,

  1. 在学习时,通常更容易编写程序、对其进行调试和运行,然后将类似的功能分成单独的功能,或者随着经验的增长
  2. 您了解需要创建的功能以及它如何与现有代码交互,只需编写一个新功能即可满足您的需求。

在你的情况下,编写你的程序,然后将它放在你面前,这样你就可以将 InputComputations输出 功能将为您提供一个很好的路线图,说明您需要函数做什么。

在第一次编写程序时,您可能希望改进代码(此处和以后)的注意事项列在下面的评论中:

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

#define N        2          /* define as many as you need - UPPERCASE */
#define MAXC    30
#define BUFSZ 1024

typedef struct products {   /* add a typedef to make type use convenient */
  char name[MAXC];
  char brand[MAXC];
  double price;
  int quantity;
} products;

int main (void)
{
  char buf[BUFSZ] = "";             /* read buffer */
  int i = 0;
  double sum = 0., avg = 0.;
  products products_arr[N] = {0};   /* initialize arrays all zero */
  
  puts ("Enter products");          /* heading before loop */
  
  for (i = 0; i < N; i++)
  {
    fputs ("\n  Enter product name     : ", stdout);
    /* read user input with fgets() to consume entire line */
    if (fgets (products_arr[i].name, MAXC, stdin) == NULL) {
      puts ("(user canceled input)");
      return 0;
    }
    /* trim trailing '\n' with strcspn()
     *   strcspn (string, "\n")               // returns no. of chars to "\n"
     *   string[strcspn (string, "\n")] = 0;  // overwrites '\n' with 0
     */
    products_arr[i].name[strcspn (products_arr[i].name, "\n")] = 0;
    
    fputs ("  Enter product brand    : ", stdout);
    if (fgets (products_arr[i].brand, MAXC, stdin) == NULL) {
      puts ("(user canceled input)");
      return 0;
    }
    products_arr[i].brand[strcspn (products_arr[i].brand, "\n")] = 0;

    fputs ("  Enter product price    : ", stdout);
    if (fgets (buf, MAXC, stdin) == NULL) {   /* read all input with fgets */
      puts ("(user canceled input)");
      return 0;
    }
    /* parse needed information from read-buffer with sscanf() */
    if (sscanf (buf, "%lf", &products_arr[i].price) != 1) {
      fputs ("error: invalid double value.\n", stderr);
      return 1;
    }

    fputs ("  Enter product quantity : ", stdout);
    if (fgets (buf, MAXC, stdin) == NULL) {   /* read all input with fgets */
      puts ("(user canceled input)");
      return 0;
    }
    if (sscanf (buf, "%d", &products_arr[i].quantity) != 1) {
      fputs ("error: invalid integer value.\n", stderr);
      return 1;
    }
  }

  for (i = 0; i < N; i++)
  { /* add '\n' to end of format string, don't call printf() twice */
    printf ("\n%s - %s - %.2lf - %d\n", products_arr[i].name,
            products_arr[i].brand,
            products_arr[i].price,
            products_arr[i].quantity);
    sum += products_arr[i].price;       /* don't waste loop, sum here */
  }

  avg = sum / N;
  printf("\nAverage = %.2f\n", avg);    /* always end final output with \n */
}

将代码分成函数

通过 InputComputationsOutput 的路线图初步了解将您的代码分解成单独的函数,您可以相当容易地识别与输入相关的代码——以及它需要哪些变量。

您的最大数组大小为 N,您需要将产品数组作为参数传递给您的输入函数。然后输入函数可以 return 读取的产品数量(可以小于 N)。出错时,您可以 return 一个负值,或者简单地 return 发生错误时成功读取的产品数量,保留您当时收集的数据。

对于你的输入函数,你可以这样做:

/** read up to a max of N products from stdin
 *  return number of elements read on success (can be less than N),
 *  otherwise returns -1 if user cancels input with manual EOF
 */
int read_products (products *products_arr)
{
  char buf[BUFSZ] = "";             /* read buffer */
  int i = 0;
  
  puts ("Enter products");          /* heading before loop */
  
  for (i = 0; i < N; i++)
  {
    fputs ("\n  Enter product name     : ", stdout);
    /* read user input with fgets() to consume entire line */
    if (fgets (products_arr[i].name, MAXC, stdin) == NULL) {
      puts ("(user canceled input)");
      return 0;
    }
    /* trim trailing '\n' with strcspn()      // How?
     *   strcspn (string, "\n")               // returns no. of chars to "\n"
     *   string[strcspn (string, "\n")] = 0;  // overwrites '\n' with 0
     */
    products_arr[i].name[strcspn (products_arr[i].name, "\n")] = 0;
    
    fputs ("  Enter product brand    : ", stdout);
    if (fgets (products_arr[i].brand, MAXC, stdin) == NULL) {
      puts ("(user canceled input)");
      return -1;
    }
    products_arr[i].brand[strcspn (products_arr[i].brand, "\n")] = 0;

    fputs ("  Enter product price    : ", stdout);
    if (fgets (buf, MAXC, stdin) == NULL) {   /* read all input with fgets */
      puts ("(user canceled input)");
      return -1;
    }
    /* parse needed information from read-buffer with sscanf() */
    if (sscanf (buf, "%lf", &products_arr[i].price) != 1) {
      fputs ("error: invalid double value.\n", stderr);
      return i;
    }

    fputs ("  Enter product quantity : ", stdout);
    if (fgets (buf, MAXC, stdin) == NULL) {   /* read all input with fgets */
      puts ("(user canceled input)");
      return i;
    }
    if (sscanf (buf, "%d", &products_arr[i].quantity) != 1) {
      fputs ("error: invalid integer value.\n", stderr);
      return 1;
    }
  }
  
  return i;
}

对于平均函数,除了产品数组外,您还需要传递数组中包含的产品数量(因为它可以小于 N)。您始终将函数的 return 类型与被 return 编辑的值的类型相匹配。在这里你可以做:

/** computes the average of nelem product price
 *  returns average
 */
double products_avg (products *products_arr, int nelem)
{
  int i = 0;                /* initialize variables */
  double sum = 0;
  
  for (; i < nelem; i++)    /* loop nelem times */
  {
    sum += products_arr[i].price;   /* sum price */
  }
  
  return sum / nelem;       /* return average */
}

最后,您的输出函数可以只打印单个产品。同样,除了数组之外,您还需要传递数组中的产品数量。由于输出函数不需要 return 值,它可以是 void 类型,因为不需要指示 success/failure 并且您不依赖任何计算值 returned,例如

/** prints individual product's name, brand, price & quantity */
void products_print (products *products_arr, int nelem)
{
  int i = 0;                /* initialize variables */
  
  for (; i < nelem; i++)    /* loop nelem times */
  { /* add '\n' to end of format string, don't call printf() twice */
    printf ("\n%s - %s - %.2lf - %d\n", products_arr[i].name,
            products_arr[i].brand,
            products_arr[i].price,
            products_arr[i].quantity);
  }
}

总而言之,您的程序分成函数可能如下所示:

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

#define N        2          /* define as many as you need - UPPERCASE */
#define MAXC    30
#define BUFSZ 1024

typedef struct products {   /* add a typedef to make type use convenient */
  char name[MAXC];
  char brand[MAXC];
  double price;
  int quantity;
} products;

/* function prototypes (will go in header file later) */
int read_products (products *products_arr);
double products_avg (products *products_arr, int nelem);
void products_print (products *products_arr, int nelem);

int main (void)
{
  int nelem = 0;
  double avg = 0.;
  products products_arr[N] = {0};         /* initialize arrays all zero */
  
  nelem = read_products (products_arr);   /* read products assign return */
  
  if (nelem < 1) {      /* validate read_products return */
    return 1;
  }
  
  avg = products_avg (products_arr, nelem);   /* compute average */
  
  products_print (products_arr, nelem);   /* output products */
  
  printf("\nAverage = %.2f\n", avg);      /* always end final output with \n */
}

/** read up to a max of N products from stdin
 *  return number of elements read on success (can be less than N),
 *  otherwise returns -1 if user cancels input with manual EOF
 */
int read_products (products *products_arr)
{
  char buf[BUFSZ] = "";             /* read buffer */
  int i = 0;
  
  puts ("Enter products");          /* heading before loop */
  
  for (i = 0; i < N; i++)
  {
    fputs ("\n  Enter product name     : ", stdout);
    /* read user input with fgets() to consume entire line */
    if (fgets (products_arr[i].name, MAXC, stdin) == NULL) {
      puts ("(user canceled input)");
      return 0;
    }
    /* trim trailing '\n' with strcspn()      // How?
     *   strcspn (string, "\n")               // returns no. of chars to "\n"
     *   string[strcspn (string, "\n")] = 0;  // overwrites '\n' with 0
     */
    products_arr[i].name[strcspn (products_arr[i].name, "\n")] = 0;
    
    fputs ("  Enter product brand    : ", stdout);
    if (fgets (products_arr[i].brand, MAXC, stdin) == NULL) {
      puts ("(user canceled input)");
      return -1;
    }
    products_arr[i].brand[strcspn (products_arr[i].brand, "\n")] = 0;

    fputs ("  Enter product price    : ", stdout);
    if (fgets (buf, MAXC, stdin) == NULL) {   /* read all input with fgets */
      puts ("(user canceled input)");
      return -1;
    }
    /* parse needed information from read-buffer with sscanf() */
    if (sscanf (buf, "%lf", &products_arr[i].price) != 1) {
      fputs ("error: invalid double value.\n", stderr);
      return i;
    }

    fputs ("  Enter product quantity : ", stdout);
    if (fgets (buf, MAXC, stdin) == NULL) {   /* read all input with fgets */
      puts ("(user canceled input)");
      return i;
    }
    if (sscanf (buf, "%d", &products_arr[i].quantity) != 1) {
      fputs ("error: invalid integer value.\n", stderr);
      return 1;
    }
  }
  
  return i;
}

/** computes the average of nelem product price
 *  returns average
 */
double products_avg (products *products_arr, int nelem)
{
  int i = 0;                /* initialize variables */
  double sum = 0;
  
  for (; i < nelem; i++)    /* loop nelem times */
  {
    sum += products_arr[i].price;   /* sum price */
  }
  
  return sum / nelem;       /* return average */
}

/** prints individual product's name, brand, price & quantity */
void products_print (products *products_arr, int nelem)
{
  int i = 0;                /* initialize variables */
  
  for (; i < nelem; i++)    /* loop nelem times */
  { /* add '\n' to end of format string, don't call printf() twice */
    printf ("\n%s - %s - %.2lf - %d\n", products_arr[i].name,
            products_arr[i].brand,
            products_arr[i].price,
            products_arr[i].quantity);
  }
}

例子Use/Output

两个示例的工作原理完全相同,并且会产生相同的输出,例如:

$ ./bin/structavg
Enter products

  Enter product name     : foo
  Enter product brand    : fink
  Enter product price    : 23.44
  Enter product quantity : 10

  Enter product name     : bar
  Enter product brand    : blink
  Enter product price    : 26.66
  Enter product quantity : 10

foo - fink - 23.44 - 10

bar - blink - 26.66 - 10

Average = 25.05

检查一下,如果您有任何问题,请告诉我。