我正在编写一个必须规范化音频*.wav
文件的程序。
有一项任务“显示标题数据”:ChunkId
,ChunkSize
等等。
我想创建一个名为display_hdr
的函数(为了在main.c文件中使用更少的代码,因此读取此代码将变得更加复杂)。为此,我必须将此函数头的变量(类型头的变量)作为参数传递,但它写入
functions.h|1|error: unknown type name 'header'|
的 main.c中 :
typedef struct FMT
{
char SubChunk1ID[4];
int SubChunk1Size;
short int AudioFormat;
short int NumChannels;
int SampleRate;
int ByteRate;
short int BlockAlign;
short int BitsPerSample;
} fmt;
typedef struct DATA
{
char Subchunk2ID[4];
int Subchunk2Size;
int Data[];
} data;
typedef struct HEADER
{
char ChunkID[4];
int ChunkSize;
char Format[4];
fmt S1;
data S2;
} header;
Header的变量以这种方式声明:
header hdr;
现在,当我尝试将hdr
传递给我的函数时,它会打印error
:
functions.h|1|error: unknown type name 'header'|
的 functions.h 的
void display_hdr( header hdr )
{
printf("\n*********************************\n");
printf("WAVE file's metadata:\n\n");
printf("%4.4s\n", hdr.ChunkID );
printf("%d\n", hdr.ChunkSize );
printf("%4.4s\n", hdr.Format );
printf("%4.4s\n", hdr.S1.SubChunk1ID );
printf("%d\n", hdr.S1.SubChunk1Size );
printf("%d\n", hdr.S1.AudioFormat );
printf("%d\n", hdr.S1.NumChannels );
printf("%d\n", hdr.S1.SampleRate );
printf("%d\n", hdr.S1.ByteRate );
printf("%d\n", hdr.S1.BlockAlign );
printf("%d\n", hdr.S1.BitsPerSample );
printf("%4.4s\n", hdr.S2.Subchunk2ID );
printf("%d\n", hdr.S2.Subchunk2Size ); /// SAMPLES' SIZE
printf("\n*********************************\n");
return;
}
那么,如何将自己的(非标准)类型的变量作为参数传递给函数?
答案 0 :(得分:2)
“可以通过仔细放置声明来限制全局变量的范围。从声明中可以看到它们直到当前源文件的结尾。”
此主题现在没有问题(没有警告或错误)。我刚刚将struct(type)的定义从main.c移到了function.c(其中声明了header
类型的变量hdr
。
<强> function.h 强>
typedef struct FMT
{
char SubChunk1ID[4];
int SubChunk1Size;
short int AudioFormat;
short int NumChannels;
int SampleRate;
int ByteRate;
short int BlockAlign;
short int BitsPerSample;
} fmt;
typedef struct DATA
{
char Subchunk2ID[4];
int Subchunk2Size;
int Data[];
} data;
typedef struct HEADER
{
char ChunkID[4];
int ChunkSize;
char Format[4];
fmt S1;
data S2;
} header; /* A `header` type created. */
header hdr; /* After a `header`type was created. */
void display_hdr( header hdr )
{
printf("\n*********************************\n");
printf("WAVE file's metadata:\n\n");
printf("%4.4s\n", hdr.ChunkID );
printf("%d\n", hdr.ChunkSize );
printf("%4.4s\n", hdr.Format );
printf("%4.4s\n", hdr.S1.SubChunk1ID );
printf("%d\n", hdr.S1.SubChunk1Size );
printf("%d\n", hdr.S1.AudioFormat );
printf("%d\n", hdr.S1.NumChannels );
printf("%d\n", hdr.S1.SampleRate );
printf("%d\n", hdr.S1.ByteRate );
printf("%d\n", hdr.S1.BlockAlign );
printf("%d\n", hdr.S1.BitsPerSample );
printf("%4.4s\n", hdr.S2.Subchunk2ID );
printf("%d\n", hdr.S2.Subchunk2Size ); /// SAMPLES' SIZE
printf("\n*********************************\n");
return;
}
<强> PS 强>
当然我可以传递指向函数的指针,但我想传递变量。没有必要这样认为它更好(记忆的经济性)。
问题是由于 'scope' 的误解(差评/不理解)。
<强> PSS 强>
也许, Andrew W 在某种程度上是正确的,但这并不能解决当前的问题。这是另一种类型的问题。但是也值得一读!
答案 1 :(得分:1)
有没有理由不通过指针?这样做可能会提供更好的性能。除此之外,确保在原型之前定义结构。另外,您可能希望看到Passing struct to function
答案 2 :(得分:0)
在主源代码模块中简化的代码行为符合预期......
/* your typedef's go here */
/* definition of display_hdr() goes here */
int main( void )
{
header hdr = {0}; /* near initialization: DO NOT RELY ON THAT */
display_hdr( hdr );
exit(0);
}
*请注意,近似初始化仅仅是为了简洁起见,在实际代码中不要依赖它。
这给出了以下输出......
*********************************
WAVE file's metadata:
0
0
0
0
0
0
0
0
0
*********************************
请检查您的代码是否以适当的顺序使用了。
在旁注中,出于性能原因,您可能需要重新编写display_hdr()
来定义它以接受指向标题的指针,如此...
void display_hdr( const header *hdr )
{
/* sanity check */
if ( NULL == hdr ) {
fprintf( stderr, "*** NULL pointer argument caught when calling: %s()\n", __func__ );
return;
}
printf("\n*********************************\n");
printf("WAVE file's metadata:\n\n");
printf("%4.4s\n", hdr->ChunkID );
printf("%d\n", hdr->ChunkSize );
printf("%4.4s\n", hdr->Format );
printf("%4.4s\n", hdr->S1.SubChunk1ID );
printf("%d\n", hdr->S1.SubChunk1Size );
printf("%d\n", hdr->S1.AudioFormat );
printf("%d\n", hdr->S1.NumChannels );
printf("%d\n", hdr->S1.SampleRate );
printf("%d\n", hdr->S1.ByteRate );
printf("%d\n", hdr->S1.BlockAlign );
printf("%d\n", hdr->S1.BitsPerSample );
printf("%4.4s\n", hdr->S2.Subchunk2ID );
printf("%d\n", hdr->S2.Subchunk2Size ); /// SAMPLES' SIZE
printf("\n*********************************\n");
return;
}
完整性检查确保在使用NULL参数调用函数时函数不会崩溃,尽管__func__
是C99的补充。如果您使用的是较旧的标准,则可以作为扩展名使用(或者只是对该功能的名称进行硬编码;)
您的main()
函数现在应该将指向标题对象的指针传递到display_hdr()
,或者在此示例中将其简单地保持为hdr
的地址,就像那样......
int main( void )
{
header hdr = {0}; /* near initialization: DO NOT RELY ON THAT */
display_hdr( &hdr );
exit(0);
}