1

我在函数中有以下代码

char MenuOptions[7][200];
strcpy(MenuOptions[0], "Create New / Modify Existing Customer");
strcpy(MenuOptions[1], "Create New / Modify Existing Product");
strcpy(MenuOptions[2], "List All customers");
strcpy(MenuOptions[3], "List All Products");
strcpy(MenuOptions[4], "Batch Update of New Stock");
strcpy(MenuOptions[5], "Create Customer Order");
strcpy(MenuOptions[6], "View Last Order for Customer");
switch (displayMenu("Main Menu", MenuOptions, 7, TRUE)) {
etc....

char displayMenu(char *name, char *options[], int menuLength,
    enBoolean QuitEnabled) {

    int i;
    printf("%s: \n", name);
    for (i = 0; i < menuLength; i++) {
        printf("\t %d %s.\n", (i + 1), options[i]);
    }
    if (QuitEnabled == TRUE)
        printf("\t Q. Quit\n");
etc

但是,一旦输入了 displayMenu 方法,MenuOptions 数组似乎就从内存中丢失了。我尝试通过 eclipse 中的表达式窗口查看 options[i] 是什么,它说它“超出范围”作为一个值

4

4 回答 4

1

optionsin的类型displayMenu必须是char (*options)[200]. 不是char *options[]

除非它是sizeof. _Alignof,或一元运算&符,或者是用于在声明中初始化数组的字符串文字,“N-element array of”类型的表达式T将被转换(“decay”)为“pointer to T”类型的表达式。在这种情况下,MenuOptions是 200 个元素数组的 7 个元素数组char;根据上面的规则,它将衰减为“指向 200 元素数组的指针”类型的表达式char

如所写,类型optionschar **; options[i]为您提供指向数组基数之后的i第 ' 个指针,而不是' 的第200 个元素数组charichar

于 2012-12-10T19:16:25.493 回答
1

首先,在编译器中打开警告选项。您的编译器应该警告您存在类型不匹配。

MenuOptions是一个由 200 个数组组成的七个数组char。当displayMenu被调用并MenuOptions作为参数传递时,MenuOptions它会自动从数组转换为指向 200 个字符的七个数组中的第一个的指针。

displayMenu中,options参数用 声明char *options[]。这意味着这options是一个指向 的指针数组char。在函数参数中,[]是特殊的;它建议将为此参数传递一个数组,但该数组实际上是通过其第一个参数的地址传递的。因此,这个声明说这options是一个指向某个数量的指针中的第一个的指针char

因此,您正在传递一个指向 200 个字符的七个数组中的第一个的指针,但该函数希望接收一个指向char.

解决此问题的一种方法是更改​​ to 的options声明char (*options)[200]。这表示这options是一个指向 200 个字符的(第一个)数组的指针。

修复它的更好方法可能是更改 MenuOptions:

static const char *MenuOptions[] =
{
    "Create New / Modify Existing Customer",
    "Create New / Modify Existing Product",
    "List All customers",
    "List All Products",
    "Batch Update of New Stock",
    "Create Customer Order",
    "View Last Order for Customer",
};

(您不需要括号中的“7”,因为编译器会为您计算字符串。)

那么您不需要更改 的声明options,除了我添加了const

char displayMenu(char *name, const char *options[], int menuLength,
    enBoolean QuitEnabled) {…

现在:

  • MenuOptions是一个由七个指向字符串的指针组成的数组(char 数组)。它作为指向字符串指针的指针传递,并且options是指向字符串指针的指针,因此类型匹配。
  • MenuOptions不会占用比所需更多的空间。之前,它被定义为每个字符串 200 个字符。现在,每个字符串只占用它需要的空间(加上末尾的空字符和指向MenuOptions数组中字符串的指针)。
  • const添加以避免意外更改字符串。
  • MenuOptions被声明static,因此它在编译时被初始化,并且您不需要在运行时将字符串复制到其中。

最后,您可以将调用中的“7”替换displayMenusizeof MenuOptions / sizeof *MenuOptions。这将数组的大小除以数组元素的大小,得到数组中元素的数量。这比硬编码常量更可取,因为它消除了有人可能在不更改硬编码常量的情况下更改数组大小的可能性。

于 2012-12-10T19:20:16.513 回答
0

一种选择:

char displayMenu(char *name, char options[][200], int menuLength, enBoolean QuitEnabled) 
于 2012-12-10T19:17:17.800 回答
0

更改您的输入类型:

char displayMenu(char *name, char *options[], ...

反映它是一个多维数组:

char displayMenu(char *name, char options[][200], ...

其他可行的选项:

char displayMenu(char *name, char options[7][200], ...

char displayMenu(char *name, char (*options)[200], ...

要点是当传递多维数组时,第一个维度之后的所有维度也需要传递。

于 2012-12-10T19:18:36.953 回答