ANSI C:声明类型为“字符串数组”的指针

时间:2018-09-06 12:14:01

标签: c arrays string pointers

我有这样的结构

struct {
  int    id;
  char   str00[10];
  char   str01[10];
  char   str03[10];
  char   str04[10];
  ...
}   myStructure;

所有strXX具有相同的大小。我想通过数组(strArray)访问它们,如下所示:

strcpy(strArray[i], strValue);

如何声明strArray?

我用了这个:

char   (*strArray)[][10] = (void *)&myStructure.str00;

它正在工作,但是我必须像这样编码strcpy

strcpy((*strArray)[i], strValue);

...而且我不喜欢这样:-)

还有另一种声明strArray的方法吗?

感谢您的想法和帮助。

2 个答案:

答案 0 :(得分:3)

您几乎拥有它,正确的指针类型就是char (*ptr)[10]

天真的,您可以使用此指针类型来遍历struct成员,但是这样做会调用未定义的行为。因为严格来说,指针只能指向单个项或数组,并且如果我们使用指针算法超出单个项/数组,则会调用未定义的行为。

为了演示数组指针算法,我将继续提供一个示例:

// BAD CODE, it relies on undefined behavior!

#include <stdio.h>
#include <string.h>

typedef struct {
  int    id;
  char   str00[10];
  char   str01[10];
  char   str02[10];
  char   str03[10];
} myStructure;


int main(void)
{
  myStructure ms = { 0 };
  char (*ptr)[10] = &ms.str00;

  for(size_t i=0; i<4; i++)
  {
    strcpy(ptr[i], "hello ");
    strcat(ptr[i], (char[]){i+'0', '\0'});
  }

  puts(ms.str00);
  puts(ms.str01);
  puts(ms.str02);
  puts(ms.str03);

  return 0;
}

正确的解决方案是改用联合,以便您可以单独或作为数组访问成员:

typedef union {
  struct              // anonymous struct, requires a standard C compiler
  {
    char str00[10];
    char str01[10];
    char str02[10];
    char str03[10];
  };
  char array[4][10];
} str_t;

typedef struct {
  int    id;
  str_t  str;
} myStructure;


strcpy(ms.str.array[i], ...); // access as array
puts(ms.str.str00); // access as individual item

答案 1 :(得分:2)

按要求定义strArray的最干净方法是使它成为指向myStructure中数组(的第一个元素)的指针数组:

char *strArray[] = { myStructure.str00, myStructure.str01, myStructure.str03, myStructure.Str04, … };

使用此定义,strArray[i]被初始化为结构的相应成员,例如myStructure.str01。请注意,myStructure.str01将自动转换为指向其第一个元素的指针,因此strArray[i]是指向其中一个数组中第一个char的指针。

然后strArray[i][j]是数组char的{​​{1}} j

(偶然地,您在示例代码中跳过了i。我不知道为什么,但在上面的代码中保留了该代码。)

另一种方法是使用联合,可以通过多种方式完成,其中之一是:

str02

那通常是一个糟糕的设计,因为它不必要地造成混淆。 (虽然由于个别定义的数组之间的填充而在技术上有失败的可能性,但是可以使用断言来确保这种情况不会发生,或者可以检测出何时发生。)

通常,我们只是将字符串定义为数组数组:

struct
{
    int    id;
    union
    {
        struct
        {
            char   str00[10];
            char   str01[10];
            char   str03[10];
            char   str04[10];
            ...
        };
        char strArray[number of arrays][10];
    };
} myStructure;

然后,将始终通过索引(例如struct { int id; char str[number of arrays][10]; } my Structure; )而不是通过单个名称(例如myStructure.str[1])来引用成员。

相关问题