Вы можете получить лучшее из обоих миров (функция и макрос) для удобочитаемости и производительности, с функцией static inline
.
Обычно вы не будете использовать это, но если вы знаете, что компилятор собираетсячтобы оптимизировать его код, тогда можно использовать его.Обычное правило, которое я использую, состоит из 3 или менее строк кода, и функция должна требовать дополнительной производительности.
При этом ваше get_state
не соответствует (моим) требованиям для функции static inline
,но если вы хотите, чтобы функция получала только fav_num, это имело бы смысл:
struct State {
int fav_num_monday;
int fav_num_not_monday;
bool is_monday;
};
static inline int get_fav_num(const struct State *state)
{
if (state->is_monday)
return state->fav_num_monday;
else
return state->fav_num_not_monday;
}
int main(void)
{
struct State state;
int fav_num;
state = (struct State){
.fav_num_monday = 12;
.fav_num_not_monday = 5;
.is_monday = 1;
};
// Print favourite number in different ways.
printf("\n");
if (state.is_monday)
fav_num = state->fav_num_monday;
else
fav_num = state->fav_num_not_monday;
printf("1) Current favourite number is %d.\n", fav_num);
fav_num = get_fav_num(&state);
printf("4) Current favourite number is %d.\n", fav_num);
return 0;
}
Отказ от ответственности: для этого кода требуется C99 или более поздняя версия.
Хотя здесь все вместе,struct State {...};
и функция static inline
будут обычно помещаться в файл заголовка .h
.
Кроме того, я бы улучшил вашу функцию get_state
следующим образом:
enum Properties {
FAV_NUM_MONDAY,
FAV_NUM_NOT_MONDAY,
IS_MONDAY,
FAV_NUM
};
int get_state(const struct State *state, int property)
{
switch (property) {
case FAV_NUM_MONDAY:
return state->fav_num_monday;
case FAV_NUM_NOT_MONDAY:
return state->fav_num_not_monday;
case IS_MONDAY:
return state->is_monday;
case FAV_NUM:
return get_fav_num(state);
default:
return -1; /* Error */
}
}
Эта функция будет обычной extern
функцией и будет помещаться в файл .c
, хотя enum Properties
должен идти в заголовочном файле, чтобы ее мог использовать пользователь функции.
Редактировать: Добавить высокопроизводительную версию с использованием массива
state.h
#include <stdint.h>
enum State_Properties {
FAV_NUM_MONDAY,
FAV_NUM_NOT_MONDAY,
IS_MONDAY,
STATE_PROPERTIES
};
static inline
uint_fast8_t get_fav_num(const uint_fast8_t *restrict (state[STATE_PROPERTIES]))
{
if ((*state)[IS_MONDAY])
return (*state)[FAV_NUM_MONDAY];
else
return (*state)[FAV_NUM_NOT_MONDAY];
}
main.c
#include <inttypes.h>
#include "state.h"
int main(void)
{
uint_fast8_t state[STATE_PROPERTIES];
uint_fast8_t fav_num;
uint_fast8_t fav_num_monday;
state = (uint_fast8_t [STATE_PROPERTIES]){
[FAV_NUM_MONDAY] = 12;
[FAV_NUM_NOT_MONDAY] = 5;
[IS_MONDAY] = true;
};
// Print favourite number in different ways.
fav_num = get_fav_num(&state);
printf("5) Current favourite number is %"PRIuFAST8".\n", fav_num);
// Example of how to retrieve any property:
fav_num_monday = state[FAV_NUM_MONDAY];
}
Конечно, вы можете изменить тип на кого угодноЯ использовал uint_fast8_t
, потому что ваши данные могут поместиться там, и это самый быстрый тип в любой системе.