我想創建以下結構。
struct student
{
char name[n 1];
int length = n;
};
其中 n 是特定整數。是否可以將引數傳遞給結構或其他解決方案來實作這樣的目標?也許指標。所以我想要基于長度的不同結構。
uj5u.com熱心網友回復:
您可以使用靈活的陣列成員:
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);
記得撥打free上s時,它不再使用。
uj5u.com熱心網友回復:
這是一種具有引數化型別之類的方法,但我不建議您這樣做!正如您在下面的示例中看到的那樣,它可能無法滿足您的需求,也沒有額外的安全性。最好使用 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@
uj5u.com熱心網友回復:
除了其他答案之外,這是另一種實作。
#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;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/334845.html
