有时候会看到类似如下情况声明的结构体,这个结构体中的 intro 有什么深意吗?

typedef struct{
  int age;
  const char* name;
  char intro[];
}Person;

这个例子中结构体的前两个字段平平无奇,一个是整型变量,一个指针变量。那么长度为零的数组有什么用呢?和指针有什么区别呢。

首先,数组的名字是一个地址,指向的是结构体内的一块空间,指针是可以指向任意位置的,但是数组是不可以的,这是数组和指针的区别。

之所以声明一个长度为 0 的数组,是为了可以在定义时控制其长度,以实现变长数组的效果。

比如使用如下函数初始化结构体。

Person* PersonNew(const char* name,int age,const char* intro)
{
  // 获取 intro 字符串的长度, 最后加一是 ‘\0’ 的位置   
  size_t intro_len = (intro? strlen(intro):0) + 1;
  Person* p = (Person*) malloc(sizeof(Person) + intro_len);
  p->age = age;
  p->name = name;
  if(intro)
  {
    strcpy(p->intro,intro);
  }
  else
  {
    p->intro[0] = 0;
  }
  return p;
}

在这个初始化函数中,首先计算 intro 字符串所需要的空间大小,然后动态申请 Person 结构体的空间,最后将 intro 的内容复制到结构体中。

还可以写出其他的操作此结构体的函数。

// 打印信息 
void PersonToString(const Person* const p)
{
  printf("Person{name = %s, age = %d,intro = %s}",p->name,p->age,p->intro);
}

// 释放内存 
void PersonDestroy(Person** ptr)
{
  if(ptr && *ptr)
  {
    free(*ptr);
    *ptr = NULL;
  }
}

// intro 重置
void PersonSetIntro(Person** ptr,const char* intro)
{
  if(ptr && *ptr)
  {
    Person* person = *ptr;
    Person* new_person = PersonNew(person->name,person->age,intro);
    PersonDestroy(ptr);
    *ptr = new_person;
  }
}