【问题标题】:Passing argument to a struct in C将参数传递给C中的结构
【发布时间】:2021-12-10 06:03:16
【问题描述】:

我想创建以下结构。

struct student
{
    char name[n+1];
    int length = n; 
};

其中 n 是一个特定的整数。是否可以将参数传递给结构或其他解决方案来实现这样的目标?也许是指针。所以我想要基于长度的不同结构。

【问题讨论】:

  • 在 C 中,数组的大小必须是固定的。那么答案是否定的。为此,您必须在堆中动态创建一个数组。
  • @CroCo "数组的大小必须是固定的。"使用灵活的数组成员和其他策略,“必须在堆中动态创建一个数组”是不正确的。

标签: arrays c pointers


【解决方案1】:

您可以使用灵活的数组成员:

struct student {
  int length;
  char name[];
};

结构被分配并初始化为长度n

struct student *s = malloc(sizeof *s + n + 1);
s->length = n;
// initialize s->name
strcpy(s->name, the_name_of_n_chars);

当不再使用时,记得在s 上拨打free

【讨论】:

  • 更多信息:malloc(sizeof *s + sizeof s->name[0] * (n + 1));。当然,在这种情况下sizeof s->name[0] == 1 所以不需要。但对于一般情况,按 FAM 元素的大小进行缩放。
【解决方案2】:

这是另一个实现,除了其他答案。

#include <string.h>
#include <stdlib.h>

struct student
{
    char *name;
    int length; 
};

struct student *
alloc_student(char *name)
{
    struct student *new;
    new = malloc(sizeof(struct student));
    if (new)
    {
        new->name = malloc(strlen(name)+1);
        if (new->name)
        {
            new->length = strlen(name);
            strcpy(new->name, name);
        }
        else
        {
            free(new);
            new=NULL;
        }
    return new;
}

void
dealloc_student(struct student *s)
{
    free(s->name);
    free(s);
}

int
main(void)
{
    struct student *s0;
    s0 = alloc_student("John");
    if (s0) dealloc_student(s0);
    return 0;
}

【讨论】:

    【解决方案3】:

    这是一种拥有参数化类型之类的方法,但我不建议您这样做!正如您在下面的示例中所见,它可能无法为您提供您想要的,也没有额外的安全性。最好使用 tstanisl 的答案。

    您可以使用 C 预处理器来获取具有不同大小的名称数组的不同类型的学生结构。但是,这些将是不同的结构类型,因此 char name[20 + 1] 的 student20 的类型与 char name[30 + 1] 的 student30 的类型相关。

    #include <string.h>
    #include <stdio.h>
    
    #define DEFSTUDENT(n) struct student##n { \
        char name[n+1]; \
        int length; \
    }
    
    #define STUDENT(n) struct student##n
    
    #define INIT_STUDENT(name) { name, strlen(name) }
    
    DEFSTUDENT(100) student1 = INIT_STUDENT("John");
    DEFSTUDENT(20) student2 = INIT_STUDENT("James");
    DEFSTUDENT(1);
    
    int main()
    {
        STUDENT(20) student3 = INIT_STUDENT("");
        printf("%d\n", student3.length);
        printf("%d\n", student2.length);
        STUDENT(1) impossibleStudent = INIT_STUDENT("Walter");
        printf("%d %s\n", impossibleStudent.length, impossibleStudent.name);
    }
    

    注意预处理器的作用(为了清楚起见,我在此处删除了#includes):

    C:\cygwin64\tmp\preproc>gcc -E student.c
    # 1 "student.c"
    # 1 "<built-in>"
    # 1 "<command-line>"
    # 1 "student.c"
    # 11 "student.c"
    struct student100 { char name[100 +1]; int length; } student1 = { "John", strlen("John") };
    struct student20 { char name[20 +1]; int length; } student2 = { "James", strlen("James") };
    struct student1 { char name[1 +1]; int length; };
    
    int main()
    {
        struct student20 student3 = { "", strlen("") };
        printf("%d\n", student3.length);
        printf("%d\n", student2.length);
        struct student1 impossibleStudent = { "Walter", strlen("Walter") };
        printf("%d %s\n", impossibleStudent.length, impossibleStudent.name);
    }
    

    这是我编译和运行它时发生的情况:

    C:\cygwin64\tmp\preproc>gcc student.c
    student.c: In function 'main':
    student.c:22:49: warning: initializer-string for array of chars is too long
         STUDENT(1) impossibleStudent = INIT_STUDENT("Walter");
                                                     ^
    student.c:11:30: note: in definition of macro 'INIT_STUDENT'
     #define INIT_STUDENT(name) { name, strlen(name) }
                                  ^~~~
    student.c:22:49: note: (near initialization for 'impossibleStudent.name')
         STUDENT(1) impossibleStudent = INIT_STUDENT("Walter");
                                                     ^
    student.c:11:30: note: in definition of macro 'INIT_STUDENT'
     #define INIT_STUDENT(name) { name, strlen(name) }
                                  ^~~~
    
    C:\cygwin64\tmp\preproc>a.exe
    0
    5
    6 Wa@
    

    【讨论】:

    • 有趣....
    猜你喜欢
    • 2018-05-29
    • 1970-01-01
    • 2013-04-12
    • 2015-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多