首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >指向字符数组的指针,并传递给二维字符数组函数参数

指向字符数组的指针,并传递给二维字符数组函数参数
EN

Stack Overflow用户
提问于 2021-06-10 09:04:29
回答 1查看 55关注 0票数 1

所以我在C中试验了几行代码,遇到了这个问题。我有一个具有以下定义的结构:

代码语言:javascript
复制
typedef struct menuScreen
{
    char *lines[MENU_MAX_LINES];
}menuScreen;

这样,我就有了一个2D字符数组,声明为:

代码语言:javascript
复制
static char array1[][MENU_MAX_CHAR_PER_LINE] = {
    "Line 1",
    "Line 2",
    "Line 3",
    "Line 4"
};

然后我有一个函数:

代码语言:javascript
复制
void buildMenu(menuScreen *menu, const char lines[][MENU_MAX_CHAR_PER_LINE])
{
    int i = 0;
    for(i = 0; i < MENU_MAX_LINES; i++)
    {
        menu->lines[i] = (char *) lines[i];
    }
}

最后是菜单的打印功能:

代码语言:javascript
复制
void printMenu(menuScreen *menu)
{
    int i = 0;
    for(i = 0; i < MENU_MAX_LINES; i++)
    {
        printf("%s\n", menu->lines[i]);
    }
}

在main.c中:

代码语言:javascript
复制
    menuScreen selectMenu[2];
    buildMenu(&selectMenu[0], array1);
    printMenu(&selectMenu[0]);

现在一切都正常了。打印也很好。然后我决定转换我的字符数组,如下所示:

代码语言:javascript
复制
static char *array1[MENU_MAX_CHAR_PER_LINE] = {
    "Line 1",
    "Line 2",
    "Line 3",
    "Line 4"
};

并将函数更改为:

代码语言:javascript
复制
void buildMenu(menuScreen *menu, const char **lines)
{
    int i = 0;
    for(i = 0; i < MENU_MAX_LINES; i++)
    {
        menu->lines[i] = (char *) lines[i];
    }
}

最后,在main.c中,我将函数调用为:

代码语言:javascript
复制
    menuScreen selectMenu[2];
    buildMenu(&selectMenu[0], (const char**) array1);
    printMenu(&selectMenu[0]);

再说一次,一切都很好。按要求工作。

现在,鉴于以上所有情况,我想知道如何泛化buildMenu()函数,以便可以在一个函数本身中同时传递char和char *[]。不能使用函数重载,因为我使用的是C,而不是C++。也许可以通过函数指针来完成,但只想知道是否可以通过调整函数的参数来实现。

EN

回答 1

Stack Overflow用户

发布于 2021-06-10 14:36:29

如果您的编译器支持C11,则可以使用_Generic重载函数:

代码语言:javascript
复制
#define buildMenu(a,b) _Generic((&b), \
    char (*)[][MENU_MAX_CHAR_PER_LINE] : buildMenu1(a,(const char (*)[MENU_MAX_CHAR_PER_LINE])(b)), \
    char *(*)[MENU_MAX_CHAR_PER_LINE]  : buildMenu2(a,(const char**)(b)))

(参见https://stackoverflow.com/a/43500229/6874310https://gustedt.wordpress.com/2012/05/19/type-generic-functions-taking-pointers-or-arrays/)

代码语言:javascript
复制
#include <stdio.h>

#define MENU_MAX_CHAR_PER_LINE (100)
#define MENU_MAX_LINES (4)

#define buildMenu(a,b) _Generic((&b), \
    char (*)[][MENU_MAX_CHAR_PER_LINE] : buildMenu1(a,(const char (*)[MENU_MAX_CHAR_PER_LINE])(b)), \
    char *(*)[MENU_MAX_CHAR_PER_LINE]  : buildMenu2(a,(const char**)(b)))

typedef struct menuScreen
{
    char *lines[MENU_MAX_LINES];

} menuScreen;

static char array1[][MENU_MAX_CHAR_PER_LINE] = {
    "array1_Line 1",
    "array1_Line 2",
    "array1_Line 3",
    "array1_Line 4"
};

static char *array2[MENU_MAX_CHAR_PER_LINE] = {
    "array2_Line 1",
    "array2_Line 2",
    "array2_Line 3",
    "array2_Line 4"
};

void buildMenu2(menuScreen *menu, const char **lines)
{
    int i = 0;
    for(i = 0; i < MENU_MAX_LINES; i++)
    {
        menu->lines[i] = (char *)lines[i];
    }
}

void buildMenu1(menuScreen *menu, const char lines[][MENU_MAX_CHAR_PER_LINE])
{
    int i = 0;
    for(i = 0; i < MENU_MAX_LINES; i++)
    {
        menu->lines[i] = (char *) lines[i];
    }
}

void printMenu(menuScreen *menu)
{
    int i = 0;
    for(i = 0; i < MENU_MAX_LINES; i++)
    {
        printf("%s\n", menu->lines[i]);
    }
}

int main()
{
    menuScreen selectMenu[2] = {0,};

    buildMenu(&selectMenu[0], array1);
    printMenu(&selectMenu[0]);

    printf("\n");

    buildMenu(&selectMenu[1], array2);
    printMenu(&selectMenu[1]);

    return 0;
}

这将输出以下内容:

代码语言:javascript
复制
array1_Line 1
array1_Line 2
array1_Line 3
array1_Line 4

array2_Line 1
array2_Line 2
array2_Line 3
array2_Line 4
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67913351

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档