我想创建以下结构体:
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
。
这里是另一个实现,除了其他答案。
#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;
}
这里有一种类似参数化类型的方法,但我不建议您这样做!正如你在下面的例子中看到的,它可能不会给你想要的,也没有额外的安全。最好使用tstanisl的答案。
你可以使用C预处理器来获得不同类型的学生结构体和不同大小的名称数组。然而,这将是不同的结构类型,所以具有char名[20 + 1]的student20的类型与具有char名[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("%dn", student3.length);
printf("%dn", student2.length);
STUDENT(1) impossibleStudent = INIT_STUDENT("Walter");
printf("%d %sn", impossibleStudent.length, impossibleStudent.name);
}
请注意预处理器从中得到了什么(为了清晰起见,我删除了这里的#includes):
C:cygwin64tmppreproc>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("%dn", student3.length);
printf("%dn", student2.length);
struct student1 impossibleStudent = { "Walter", strlen("Walter") };
printf("%d %sn", impossibleStudent.length, impossibleStudent.name);
}
下面是我编译并运行它时的结果:
C:cygwin64tmppreproc>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:cygwin64tmppreproc>a.exe
0
5
6 Wa@