Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用预处理器避免读/写函数中的代码重复_C_C Preprocessor - Fatal编程技术网

C 使用预处理器避免读/写函数中的代码重复

C 使用预处理器避免读/写函数中的代码重复,c,c-preprocessor,C,C Preprocessor,如果我有一对长函数: #include <stdio.h> #include <stdlib.h> void writeData() { FILE *fp; int someVar1 = 1; int someVar2 = 2; int someVar3 = 3; fp = fopen("results.dat", "a"); // open file if (fp == NULL) { printf("I could

如果我有一对长函数:

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

void writeData()
{
    FILE *fp; int someVar1 = 1; int someVar2 = 2; int someVar3 = 3;

    fp = fopen("results.dat", "a");     // open file

    if (fp == NULL) {
        printf("I couldn't open results.dat for appending.\n");
        exit(0);
    }

    fprintf(fp, "%d\n", someVar1);   // write to file
    fprintf(fp, "%d\n", someVar2);   // write to file
    fprintf(fp, "%d\n", someVar3);   // write to file
    fclose(fp);                     // and close
}

void readData()
{
    FILE *fp; int someVar1, someVar2, someVar3;

    fp = fopen("results.dat", "r");     // open file for reading
    if (fp == NULL) {
        printf("I couldn't open results.dat for reading.\n");
        exit(0);
    }

    fscanf(fp, "%d\n", &someVar1);       // read from file
    fscanf(fp, "%d\n", &someVar2);       // read from file
    fscanf(fp, "%d\n", &someVar3);       // read from file

    fclose(fp);     // and close

    printf("someVar: %d %d %d\n", someVar1, someVar2, someVar3);
}

int main(void)
{
    writeData();
    readData();

    return 0;
}
#包括
#包括
无效写入数据()
{
文件*fp;int-someVar1=1;int-someVar2=2;int-someVar3=3;
fp=fopen(“results.dat”,“a”);//打开文件
如果(fp==NULL){
printf(“我无法打开results.dat进行追加。\n”);
出口(0);
}
fprintf(fp,“%d\n”,someVar1);//写入文件
fprintf(fp,“%d\n”,someVar2);//写入文件
fprintf(fp,“%d\n”,someVar3);//写入文件
fclose(fp);//并关闭
}
void readData()
{
文件*fp;int someVar1、someVar2、someVar3;
fp=fopen(“results.dat”,“r”);//打开文件进行读取
如果(fp==NULL){
printf(“我无法打开results.dat进行读取。\n”);
出口(0);
}
fscanf(fp,“%d\n”,&someVar1);//从文件读取
fscanf(fp,“%d\n”,&someVar2);//从文件读取
fscanf(fp,“%d\n”,&someVar3);//从文件读取
fclose(fp);//并关闭
printf(“someVar:%d%d%d\n”、someVar1、someVar2、someVar3);
}
内部主(空)
{
writeData();
readData();
返回0;
}
有没有一种方法可以(ab)使用预处理器来避免重复读写代码?换句话说,在
write()
read()
函数中,是否有方法分别生成
fprintf(fp,“%d\n”,someVar)
fprintf(fp,“%d\n”,someVar)


编辑:这同样适用于分配/取消分配整个内存负载,例如。基本上,任何在两个互补但简单的函数之间有大量代码重复的任务。

看看您的代码,我认为这不值得付出努力,因为其中有太多的差异(“开放中的“a”与“r”,不同的错误消息,printf与scanf,额外的printf”)。如果一年后有人不得不阅读或调试它,那么整个事情的创建和理解都会很混乱,甚至会更混乱

但是,出于教育目的:

#define MYFUNC(NAME,VARPART1,VARPART2) \
  void NAME () { \
      int a= 0; \
      VARPART1; \
      VARPART2; \
  }

// make a print function
MYFUNC(printit, printf("%d", a), return);

// make a scan function:
MYFUNC(scanit, scanf("%d", &a), *global= a);
将使用一个宏创建两个不同的函数,例如第一个将是:

  void printit () { 
      int a= 0; \
      printf("%d", a); 
      return; 
  }

为什么是预处理器?你可以在代码中找到它,类似这样的东西

#define READ 0
#define WRITE 1

void do_some_io( int action )
{
    FILE *fp; int someVar = 1;

    fp = fopen("results.dat", (action == WRITE ? "a" : "r") );     // open file

    if (fp == NULL) {
        printf("I couldn't open results.dat for io.\n");
        exit(0);
    }

    if ( action == WRITE )
        fprintf(fp, "%d\n", someVar);   // write to file
    else
        fscanf(fp, "%d\n", &someVar);       // read from file
    fclose(fp);                     // and close
}

有一种称为X宏的技术可能适合您的需要。您可以在wikipedia()中查看其工作原理的基本信息

按照wiki的解释,您可以创建一个VAR_列表,然后将该列表扩展为read或write

#define MY_VAR_LIST(ENTRY)  \
    ENTRY(var1) \
    ENTRY(var2) \
    ENTRY(var3)

#define EXPAND_AS_DEFINITION(my_var) int my_var;
#define EXPAND_AS_WRITE(my_var) fprintf(fp, "%d\n", (my_var));
#define EXPAND_AS_READ(my_var) fscanf(fp, "%d\n", &(my_var));

int my_function_write()
{
    MY_VAR_LIST(EXPAND_AS_DEFINITION)
    FILE *fp;
    fp = fopen("results.dat", "a");     // open file

    if (fp == NULL) {
        printf("I couldn't open results.dat for appending.\n");
        exit(0);
    }

    MY_VAR_LIST(EXPAND_AS_WRITE)
    fclose(fp);
}

int my_function_read()
{
    MY_VAR_LIST(EXPAND_AS_DEFINITION)
    FILE *fp;
    fp = fopen("results.dat", "r");     // open file

    if (fp == NULL) {
        printf("I couldn't open results.dat for appending.\n");
        exit(0);
    }

    MY_VAR_LIST(EXPAND_AS_READ)
    fclose(fp);
}
因此,要附加一个新的var,您只需要更新您的var\u列表


我没有试着编译我的代码,所以可能有一些语法错误,但这是它应该工作的方式。

看,我不明白你想要什么。例如。如果我想读/写一整批变量,并保持它们的写入/读取顺序,那么添加一行代码(它会展开以提供读/写版本)比分别向读函数和写函数添加行要简单一些。另一个(更简单的)示例:read()和write()是函数的可怕名称,因为它们也是名称(unix)系统调用(stdio函数在内部使用)。如果你想保持理智,就不要使用它们。是的,这是真的,我只是匆忙地在这里拼凑了一些示例代码!谢谢你,很高兴看到原则上可以这样做。不幸的是,我会一次加载几个变量(我已经更新了我的示例代码),只想创建一对函数。答案不错,但为什么要使用预处理器呢<代码>枚举操作{READ,WRITE}。这就是预处理器和无预处理器常量之间的战争。我喜欢我自己的方式,但我认为这没关系。谢谢,这是最接近我所要求的。谢谢,很高兴看到它是如何完成的。