繁体   English   中英

将参数传递给 C 中的结构

[英]Passing argument to a struct in C

我想创建以下结构。

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

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

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

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

这是一种具有参数化类型之类的方法,但我不建议您这样做! 正如您在下面的示例中看到的那样,它可能无法满足您的需求,也没有额外的安全性。 最好使用 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@

除了其他答案之外,这是另一种实现。

#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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM