用于数组初始化的 C 宏

Posted

技术标签:

【中文标题】用于数组初始化的 C 宏【英文标题】:C macro for array initialization 【发布时间】:2021-10-10 19:21:03 【问题描述】:

我需要一个 C 中的宏来执行此操作:

ARRINIT(10, 0) => 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

然而,据我了解,C 宏中没有常规循环。所以我尝试编写一个函数,它接受一个数字和一个 void 指针并返回一个初始化的数组。但这需要指针,我希望它与常数一起使用。此外,我想将它用于所有内容:函数、整数、浮点数、字符串等。所以我很可能需要一个宏。 我怎样才能达到这种效果?

【问题讨论】:

你看过memset吗? 有可能。命名不是很好(不一定是数组初始化,也可以是结构初始化)。这也是相当困难和不平凡的。您可以查看github.com/rofl0r/chaos-pp 以获得灵感。 cpp 不会为你这样做 [即使是在胁迫/折磨 :-)]。你想要一个“代码生成器”程序。像m4 这样的“真正的”宏处理器或perl/python/c 程序,您编写并添加到您的Makefile 以生成您想要的源代码(即元编程)。 @CraigEstey "@CraigEstey "cpp 不会为你做这件事 [即使在胁迫/折磨下:-)]" “这个”是指this ? @HWalters 哦,真是个黑客! ;-) 它也适用于 C 吗? -- 无论如何,为了使它更有用,我希望REPEAT(4, x) 扩展为x, x, x, x 而不带大括号和最后的逗号。这样,人们可以使用它的倍数来填充同一数组/结构/任何东西中的区域。但是,我永远不会使用这样的宏,只是因为它隐藏的太多。 【参考方案1】:

这是我想到的一个古怪的解决方法。为了实现这个愿望:

我想将它用于所有内容:函数、整数、浮点数、字符串等。

我无法使用指针逃脱

首先,准备一个头文件(在本例中称为“macroArray.h”),如下所示:

#ifndef MACRO_ARRAY_H
#define MACRO_ARRAY_H

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

#define ARRINIT(SIZE, INIT_VAL) initArr(SIZE, INIT_VAL)

typedef int Item;

Item **initArr(int aSize, Item *initVal)

    Item **arr = malloc(aSize * sizeof *arr);

    if (arr != NULL)
    
        for (int i = 0; i < aSize; i++) 
        
            *(arr + i) = initVal;
        
    
    else
    
        fprintf(stderr, "Failed to allocate memory!\n");
        exit(1);
    

    return arr;


#endif /* MACRO_ARRAY_H */

这是一个用法示例:

#include "macroArray.h"

int main(void) 
   
    int size = 10;
    int num = 0;
    
    int **arr = ARRINIT(size, &num);

    for (int i = 0; i < size; i++)
    
        printf("%d ", **(arr + i));
    

    printf("\n");

    free(arr);

    return 0;

所以...

ARRINIT(10, 0) =&gt; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

可以!

你怎么看?

一些缺点:

为了改变数组的类型,必须改变头文件中typedef定义的别名;这不是很“用户友好” 你一定不要忘记free()动态分配的数组 这可能无法满足您使用“常量”的愿望 这就像“有效,但不是真的”;可以改进

【讨论】:

以上是关于用于数组初始化的 C 宏的主要内容,如果未能解决你的问题,请参考以下文章

C语言数组或者枚举类型初始化时出现宏定义和包含头文件的奇怪语法

C语言数组或者枚举类型初始化时出现宏定义和包含头文件的奇怪语法

C语言数组或者枚举类型初始化时出现宏定义和包含头文件的奇怪语法

使用可变参数宏的结构初始化数组

用于初始化数组的 c++ 语法

第五次实验(数组实验)