任何人都可以解释以下C语法吗?

时间:2014-11-30 17:28:55

标签: c syntax avr

我遇到了FAT file system的图书馆。它是嵌入式系统的库。在示例代码中,我发现了一些我不理解的有趣行。

以下是有问题的一行:

sd_protocol.spiHwInit=(void *)atmega_spi_init;

其中sd_protocol是结构SdSpiProtocol sd_protocol;

以下是类型定义

struct _SdSpiProtocol
{
    void *spiHwInterface;
    euint8 (*spiHwInit)(void* spiHwInterface);
    euint8 (*spiSendByte)(void* spiHwInterface,euint8 data);
};
typedef struct _SdSpiProtocol SdSpiProtocol;

atmega_spi_init是以下功能

euint8 atmega_spi_init(atmegaSpiInterface *iface)
{
    euint8 i;

    /* Unselect card */
    PORTB |= iface->pinSelect;

    /* Set as master, clock and chip select output */
    DDR_SPI = (1<<DD_MOSI) | (1<<DD_SCK) | 1;

    /* Enable SPI, master, set clock rate to fck/2 */
    SPCR = (1<<SPE) | (1<<MSTR); /* fsck / 4 */
    SPSR = 1; /* fsck / 2 */

    /* Send 10 spi commands with card not selected */
    for(i=0;i<10;i++)
        atmega_spi_send(iface,0xff);

    /* Select card */
    PORTB &= ~(iface->pinSelect);

    return(0);
}

sd_protocol.spiHwInit=(void *)atmega_spi_init;这不是函数调用,那是什么?

我不明白这行应该做什么,在类型定义中:

euint8 (*spiHwInit)(void* spiHwInterface);

提前致谢!

3 个答案:

答案 0 :(得分:3)

它不是函数调用而是函数指针:

How do function pointers in C work?

并且您的行从特定的函数指针转换为void指针。

答案 1 :(得分:2)

struct _SdSpiProtocol
{
  void *spiHwInterface;
  euint8 (*spiHwInit)(void* spiHwInterface);
  euint8 (*spiSendByte)(void* spiHwInterface,euint8 data);
};
typedef struct _SdSpiProtocol SdSpiProtocol;

spiHwInit成员是指向void *参数并返回euint8的函数的指针。

euint8 atmega_spi_init(atmegaSpiInterface *iface);

sd_protocol.spiHwInit=(void *)atmega_spi_init;

此行是作业。它会将atmega_spi_init(这是一个函数)转换为(void *)并将其分配给.spiHwInit

然而,由于多个原因,这是错误的。首先,任何C标准都不能将函数指针转换为具有任何明确定义结果的void *对象指针可以转换为void *并返回到具有明确定义结果的相同类型,但不能转换为函数指针。

其次,(假设atmegaSpiInterface是结构而不是void *),代码将一种类型的函数指针转换为void *,然后转换为不同函数指针的类型。如果通过错误类型的函数指针调用该函数,则行为未定义。

执行此操作的正确方法是将函数atmega_spi_init()定义为与.spiHwInterface成员具有相同类型,即使用void *参数。然后可以在没有强制转换的情况下进行赋值,并且通过.spiHwInterface的函数调用是完全明确定义的。您只需将iface参数转换为正确的类型,然后再在函数内使用它。

当然,可能还有其他标准(例如POSIX)或编译器扩展,允许所有这些转换具有明确定义的结果。

答案 2 :(得分:1)

这一行euint8 (*spiHwInit)(void* spiHwInterface);spiHwInit声明为函数的指针。 “有问题”行将指针指向具体函数sd_protocol.spiHwInit