如何在c中使用malloc typedef结构?
我们的老师让我们制作一个视频俱乐部菜单,他给了我们一些结构:如何在c中使用malloc typedef结构?,c,struct,malloc,typedef,C,Struct,Malloc,Typedef,我们的老师让我们制作一个视频俱乐部菜单,他给了我们一些结构: typedef struct date { int day, month, year; }date; typedef struct directorInfo { const char* directorSurname; const char* directorName; }directorInfo; typedef struct movie { int id; const char* t
typedef struct date
{
int day, month, year;
}date;
typedef struct directorInfo
{
const char* directorSurname;
const char* directorName;
}directorInfo;
typedef struct movie
{
int id;
const char* title;
directorInfo* director;
date* releaseDate;
}movie;
我很困惑,我不知道如何处理每一个问题。
这就是我所做的:
int main()
{
int totalMovies = 50;
movie *movie_ptr = (movie*)malloc( totalMovies * sizeof(movie) );
date *date_ptr = (date*)malloc( totalMovies * sizeof(date) );
directorInfo *directorInfo_ptr = (directorInfo*)malloc( totalMovies * sizeof(directorInfo) );
movie_ptr->title = (char*)malloc( 200 * sizeof(char) );
directorInfo_ptr->directorName = (char*)malloc( 200 * sizeof(char) );
movie_ptr[0].director->directorName = "John";
printf("%s", movie_ptr[0].director->directorName);
有没有更快更专业的方法?我觉得这一切都错了,而且当我试图打印directorName时,它不会打印任何内容。
(我很抱歉这里的任何高级程序员看到这段代码,都会瞪大眼睛)结构、嵌套结构的内存分配,需要遵循最顶层结构的分配,并深入到嵌套结构(如果它们是指针),内存没有分配,在这种情况下,每个结构指针都需要显式分配内存,例如在您的情况下 以下代码将分配
类型的电影的结构的未初始化数组
// this created/allocates an array of 50 movies
movie *m = malloc( sizeof(movie) * 50);
// for each movie m[i]
for (int i = 0; i < 50; ++i)
{
m[i].title = malloc( sizeof(char) * 128 ); // say title size is 128 characters;
m[i].director = malloc( sizeof(director));
m[i].director->directorName = malloc( sizeof(char) * 128 );
m[i].director->directorSurname = malloc( sizeof(char) * 128 );
m[i].releaseDate = malloc( sizeof(date));
} // repeat for others
//这创建/分配了一个包含50部电影的数组
movie*m=malloc(sizeof(movie)*50);
//每部电影m[i]
对于(int i=0;i<50;++i)
{
m[i].title=malloc(sizeof(char)*128);//假设标题大小为128个字符;
m[i].director=malloc(sizeof(director));
m[i].director->directorName=malloc(sizeof(char)*128);
m[i].director->directorSurname=malloc(sizeof(char)*128);
m[i].releaseDate=malloc(sizeof(date));
}//为其他人重复
同样,释放遵循反向路径,首先释放所有结构元素,然后释放实际结构
// Free loop
for (int i = 0; i < 50; ++i)
{
free(m[i].releaseDate);
free(m[i].directorName->directorName);
free(m[i].directorName->directorSurname);
free(m[i],director);
free(m[i]);
} // repeat for others
free(m);
//自由循环
对于(int i=0;i<50;++i)
{
免费(m[i]。发布日期);
免费(m[i].directorName->directorName);
免费(m[i].directorName->directorSurname);
自由(m[i],董事);
自由(m[i]);
}//为其他人重复
自由(m);
< P>除非你将此代码编译为C++或使用一个古老的K&R C实现,否则你可以将“脱离代码”> MalOC/ >调用——这会节省一些混乱和维护的头痛。此外,您还可以将目标用作sizeof
操作数:
movie *movie_ptr = malloc( totalMovies * sizeof *movie_ptr );
由于表达式*movie\u ptr
的类型是movie
,sizeof*movie\u ptr==sizeof(movie)
1。当movie_ptr
的声明与实际的malloc
调用分开时,这尤其有用:
movie *movie_ptr;
// a bunch of code here
movie_ptr = malloc( totalMovies * sizeof *movie_ptr );
这样,您就不必不断重复类型名,从而使维护变得更容易
现在,关于更大的问题——如何更好地组织针对此类问题的代码——这里有一些建议:
首先,我将抽象出读取、分配数据的逻辑,并将数据分配给不同类型的函数
例如,有一个函数专门用于从标准输入流读取日期:
int getDate( int *day, int *month, int *year )
{
int success = 1;
printf( "Release year: " );
if ( scanf( "%d", year ) != 1 ) // this is the barest minimum level
success = 0; // of error handling, but it's better than nothing
...
return success;
}
然后使用另一个函数获取该数据并分配一个date
对象:
date *createDate( int day, int month, int year )
{
date *d = malloc( sizeof *d );
/**
* ALWAYS check the result of malloc, calloc, or realloc before attempting
* to use the pointer, since they will return NULL if they cannot
* satisfy the request.
*/
if ( d ) // or if ( d != NULL )
{
d->day = day;
d->month = month;
d->year = year;
}
return d;
}
然后在主代码中,您可以这样调用它们:
int day, month, year;
date *d = NULL;
if ( getDate( &day, &month, &year ) )
d = createDate( day, month, year );
或者,可以将这些操作组合到第三个功能中:
date *dateFromStdInput( void )
{
int day, month, year;
date *d = NULL;
if ( getDate( &day, &month, &year ) )
d = createDate( day, month, year );
return d;
}
然后在主代码中调用:
date *d = dateFromStdInput();
I/O和内存分配是完全独立的操作,因此通常您希望编写单独的函数来处理每一个操作,以便在不影响另一个操作的情况下更改其中一个操作。这需要一些预先考虑,但最终它使代码更易于维护和更新
对导演信息执行类似操作,然后您可以创建一个新的电影
对象,如下所示:
date *d = dateFromStdInput();
directorInfo *dir = dirFromStdInput();
char title[MAX_TITLE_LEN + 1];
/**
* Make sure we have successfully read title, director, and date info
* before we attempt to create a new movie object:
*/
if ( fgets( title, sizeof title, stdin ) && dir && d )
{
movie *m = createMovie( title, dir, d );
}
“但是,”你说,“我想创建一个电影数组。”那么,你可以创建一个指向movie
的指针数组,然后为每个元素分配一个新的movie
对象:
movie **m = malloc( totalMovies * sizeof *m ); // sizeof *m == sizeof (movie *)
if ( m )
{
for ( int i = 0; i < totalMovies; i++ )
{
date *d = dateFromStdInput();
director *dir = dirFromStdInput();
char title[MAX_TITLE_LEN+1];
if ( fgets( title, sizeof title, stdin ) && dir && d )
m[i] = createMovie( title, dir, d );
}
}
再一次,这些都是我头脑中的建议;毫无疑问,有更好的方法来构造这段代码,但无论如何,它都应该让您开始
请记住,sizeof
是一个运算符,而不是一个函数;仅当操作数是类型名(如int
或movie
)时,才需要使用参数。添加它们并没有什么坏处sizeof(*movie_ptr)
将以同样的方式工作。不过,这也节省了一些混乱。
没有typedef结构,为什么不呢?@USER 253551我用过好几次,这对于C++和C来说是一样的:核心语言将为你做的很少。你必须完成所有的工作,并编写所有的代码来完成。C和C++都没有捷径,只需要使用它就能使所有的事情发生。如果您必须malloc
几个不同的对象,并且每个对象都有指针,这些指针本身也必须依次malloc
ed,那么必须编写这样做的代码。要详细说明。。。“typedef struct”不是一个术语。这是两个连续的关键词,每一个都有自己的效果。任何一方的存在都不会影响另一方的行为。所以“typedef struct”并没有传达任何有意义的东西。通常你可以使用一个函数来为你做这件事(显然你必须编写它)次要:if(fgets(title)&&dir&d)
不如if(dir&d&&fgets(title))
如果先前的分配失败,则不尝试输入。@chux:fixedfgets
调用。我会责备睡眠不足。
void freeMovie( movie *m )
{
free( m->releaseDate );
free( m->director->name );
free( m->director->surname );
free( m->director );
free( m->title );
free( m );
}