想知道如何将我的代码分成单独的函数
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,因此您现有的代码有几个注意事项。您真正的问题似乎是“如何将我的代码分成单独的函数”。
有两种基本方法,
- 在学习时,通常更容易编写程序、对其进行调试和运行,然后将类似的功能分成单独的功能,或者随着经验的增长
- 您了解需要创建的功能以及它如何与现有代码交互,只需编写一个新功能即可满足您的需求。
在你的情况下,编写你的程序,然后将它放在你面前,这样你就可以将 Input、Computations 和输出 功能将为您提供一个很好的路线图,说明您需要函数做什么。
在第一次编写程序时,您可能希望改进代码(此处和以后)的注意事项列在下面的评论中:
#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 */
}
将代码分成函数
通过 Input、Computations 和 Output 的路线图初步了解将您的代码分解成单独的函数,您可以相当容易地识别与输入相关的代码——以及它需要哪些变量。
您的最大数组大小为 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
检查一下,如果您有任何问题,请告诉我。
我最近开始在大学学习 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,因此您现有的代码有几个注意事项。您真正的问题似乎是“如何将我的代码分成单独的函数”。
有两种基本方法,
- 在学习时,通常更容易编写程序、对其进行调试和运行,然后将类似的功能分成单独的功能,或者随着经验的增长
- 您了解需要创建的功能以及它如何与现有代码交互,只需编写一个新功能即可满足您的需求。
在你的情况下,编写你的程序,然后将它放在你面前,这样你就可以将 Input、Computations 和输出 功能将为您提供一个很好的路线图,说明您需要函数做什么。
在第一次编写程序时,您可能希望改进代码(此处和以后)的注意事项列在下面的评论中:
#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 */
}
将代码分成函数
通过 Input、Computations 和 Output 的路线图初步了解将您的代码分解成单独的函数,您可以相当容易地识别与输入相关的代码——以及它需要哪些变量。
您的最大数组大小为 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
检查一下,如果您有任何问题,请告诉我。