0

我正在编写一个必须规范化音频*.wav文件的程序。有一个任务“显示标题的数据”:ChunkId等等ChunkSize

我想创建一个名为的函数display_hdr(为了在 main.c 文件中有更少的代码,所以阅读这段代码会变得更容易)。为此,我必须将此函数头的变量(类型头的变量)作为参数传递,但它写道

functions.h|1|error: unknown type name 'header'|

主.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'|

函数.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;
}

那么,如何将您自己(非标准)类型的变量作为参数传递给函数?

4

3 回答 3

2

“可以通过仔细放置声明来限制全局变量的范围。从声明到当前源文件的结尾,它们都是可见的。”

现在这个主题没有问题(没有警告或错误)。我只是将结构(类型)的定义从 main.c 移到了 function.c(其中声明了一个header类型的变量hdr)。

函数.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;
}

附言

当然我可以传递一个指向函数的指针,但我想传递变量。没有必要这样做认为它更好(内存经济)。

问题是因为对“范围” 的误解(理解不佳/理解不佳)

PSS

也许,Andrew W在某种程度上是对的,但这并不能解决当前的问题。那完全是另一类问题。但也值得一读!

于 2013-05-18T19:12:18.457 回答
1

有理由不传递指针吗?这样做可能会提供更好的性能。除此之外,请确保在原型之前定义结构。此外,您可能希望看到将结构传递给函数

于 2013-05-18T18:50:24.590 回答
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);
}
于 2013-05-18T19:25:23.593 回答