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