如何正确初始化另一个结构中的结构数组并从函数 return 中初始化它?

How to properly initialize array of structures inside another structure and return it from function?

我有一个这样的结构数组:

typedef struct month {
    char cName[20];
    char cAbbr[20];
    int iDays;
    int iNumber;
} MONTH;

嵌套在另一个结构中:

typedef struct input{
    MONTH * pMonths;
    DATE sDate;
    CALCS sCalcs;
} INPUT;

我这样在堆栈中初始化这个结构数组:

MONTH * init_months(bool bLeap) {

    MONTH months[NUM_MONTHS] = {
        { .cName = "January", .cAbbr = "Jan", .iDays = 31, .iNumber = 1 },
        { "February", "Feb", 28, 2 },
        { "March", "Mar", 31, 3 },
        { "April", "Apr", 30, 4 },
        { "May", "May", 31, 5 },
        { "June", "Jun", 30, 6 },
        { "July", "Jul", 31, 7 },
        { "August", "Aug", 31, 8 },
        { "September", "Sep", 30, 9 },
        { "October", "Oct", 31, 10 },
        { "November", "Nov", 30, 11 },
        { "December", "Dec", 31, 12 }
    };

    if(bLeap){
        months[1].iDays++;
    }

    return months;
}

问题是,如果我在某个函数中形成一个 INPUT 结构:

INPUT GetUserInput(void){

    // init months
    MONTH * pMonths;
    pMonths = init_months(isLeap(sDate.iYear));

    // some code here
    ...
    INPUT sInput = { pMonths, sDate, sCalcs };

    // return
    return sInput;
}

然后如何正确初始化 MONTH 数组 and/or 如何正确初始化 INPUT 以便它在以下情况下包含有效数据从 GetUserInput() 返回?

您有 3 个选项:

  1. 使其成为静态的(但所有 returned 引用将引用同一个数组)。
    static MONTH months[NUM_MONTHS] = {
  1. 使用 malloc 和复合文字
    MONTH *months = malloc(sizeof(*months) * NUM_MONTHS);
    
    /* check if memory was allocated */
    
    memcpy(months, (MONTH[]){
        { .cName = "January", .cAbbr = "Jan", .iDays = 31, .iNumber = 1 },
        { "February", "Feb", 28, 2 },
        { "March", "Mar", 31, 3 },
        { "April", "Apr", 30, 4 },
        { "May", "May", 31, 5 },
        { "June", "Jun", 30, 6 },
        { "July", "Jul", 31, 7 },
        { "August", "Aug", 31, 8 },
        { "September", "Sep", 30, 9 },
        { "October", "Oct", 31, 10 },
        { "November", "Nov", 30, 11 },
        { "December", "Dec", 31, 12 }}, sizeof(*months) * NUM_MONTHS);
  1. 将table包装到另一个结构中并return按值
typedef struct
{
    MONTH months[NUM_MONTHS];
}YEAR;

YEAR init_months(bool bLeap) {

    YEAR year = {{
        { .cName = "January", .cAbbr = "Jan", .iDays = 31, .iNumber = 1 },
        { "February", "Feb", 28, 2 },
        { "March", "Mar", 31, 3 },
        { "April", "Apr", 30, 4 },
        { "May", "May", 31, 5 },
        { "June", "Jun", 30, 6 },
        { "July", "Jul", 31, 7 },
        { "August", "Aug", 31, 8 },
        { "September", "Sep", 30, 9 },
        { "October", "Oct", 31, 10 },
        { "November", "Nov", 30, 11 },
        { "December", "Dec", 31, 12 }}};

    if(bLeap){
        year.months[1].iDays++;
    }

    return year;
}