是否可以在初始化程序中使用三元运算符初始化静态数组?

时间:2017-01-19 15:08:39

标签: c arrays initialization ternary-operator constant-expression

是否可以在初始化程序中使用三元运算符初始化静态数组? 例如:

// Array of functions 
static const Callback_t CallbackArray[] =
{
    GenConfig,
    GenInfo,
    /* here is the ternary operator to chose a callback */
    Test() ? Config : NULLConfig,   
};

其中Test()是一个返回0或1

的函数
// somewhere else in the code
int gVar = 0;

int TEST(void)
{
    return gVar;
}

3 个答案:

答案 0 :(得分:3)

如果数组没有静态存储持续时间,则可以将运算符用作初始化表达式。

从C标准(6.7.9初始化)

  

4具有静态的对象的初始值设定项中的所有表达式   或线程存储持续时间应为常量表达式或字符串   文字。

考虑到你可能没有声明一个函数数组,但你可以声明一个函数指针数组。

这是一个示范程序

#include <stdio.h>

void f( void ) { puts( "f"); }
void g( void ) { puts( "g"); }

int main(void) 
{
    int x = 1, y = 2;

    void ( *fp[] )( void ) = { x < y ? f : g };

    fp[0]();

    return 0;
}

程序输出

f

如果函数类型太复杂,可以为它引入typedef。例如

#include <stdio.h>

void f( void ) { puts( "f"); }
void g( void ) { puts( "g"); }

int main(void) 
{
    int x = 1, y = 2;

    typedef void F( void );

    F * fp[] = { x < y ? f : g };

    fp[0]();

    return 0;
}

您可以使用条件运算符初始化具有静态存储持续时间的数组。问题是条件必须是一个并不总是合适的常量表达式。例如

#include <stdio.h>

void f( void ) { puts( "f"); }
void g( void ) { puts( "g"); }

typedef void F( void );

F * fp[] = { 1 ? &f : &g };

int main(void) 
{
    fp[0]();

    return 0;
}

来自C标准(6.6常量表达式)

  

9地址常量是空指针,是指向左值的指针   指定静态存储持续时间的对象,或指向 a的指针   功能指示符; 应使用。明确创建   一元&amp;运算符或转换为指针类型的整数常量,或   通过使用数组或函数类型的表达式隐式地。该   array-subscript []和成员访问。和 - &gt;运营商,地址&amp;   和间接*一元运算符,以及指针强制转换可以用于   创建一个地址常量,但对象的值应该是   不能通过使用这些操作符来访问。

答案 1 :(得分:2)

CallbackArray数组具有静态存储持续时间(即由于static关键字,或者它可能已放置在任何函数之外),这意味着它必须使用常量表达式进行初始化。

这里,条件运算符?:不会产生常量表达式(因为它包含函数调用),因此代码无效。

答案 2 :(得分:0)

您无法根据功能初始化 static数组的内容。

但要选择其他功能......

typedef returntype (*fxtype)(parmtypes);

fxtype choose(void) {
    return Test() ? Config : NULLConfig;
}

static const Callback_t CallbackArray[] =
{
    GenConfig,
    GenInfo,
    choose,   
};