1

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

// 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;
}
4

3 回答 3

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 地址常量是空指针、指向指定静态存储持续时间对象的左值指针或指向函数指示符的指针;它应使用一元 & 运算符或转换为指针类型的整数常量显式创建,或通过使用数组或函数类型的表达式隐式创建。数组下标 [] 和成员访问。和 -> 运算符、地址 & 和间接 * 一元运算符以及指针转换可用于创建地址常量,但不应使用这些运算符访问对象的值。

于 2017-01-19T15:17:23.467 回答
2

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

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

于 2017-01-19T15:14:01.070 回答
0

您不能基于函数初始化数组的内容。static

但是要选择另一个功能...

typedef returntype (*fxtype)(parmtypes);

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

static const Callback_t CallbackArray[] =
{
    GenConfig,
    GenInfo,
    choose,   
};
于 2017-01-19T15:14:39.750 回答