Существует ли эквивалентная функция, которая может принимать операторы в качестве аргументов?

У меня есть следующий раздел кода, который мне нужно использовать примерно 5 раз во всей программе, но с разными строками кода вместо комментария.

while (loop_day < (day+1)) {
    while (loop_size < (size+1)) {

        //new lines here

        size = size + 1;
    }
    loop_day = loop_day + 1;
}

Я мог бы скопировать и вставить это несколько раз, но правда не хотел бы этого по эстетическим соображениям. Я попытался найти «функции, которые могли бы принимать операторы в качестве аргументов», но ничего подходящего не нашел.

Изменить: я хочу "встроить" в код различные операторы.

Пример:

while (loop_day < (day+1)) {
    while (loop_size < (size+1)) {

        // code that stores various values into an array

        size = size + 1;
    }
    loop_day = loop_day + 1;
}


while (loop_day < (day+1)) {
    while (loop_size < (size+1)) {

        // code that reads values stored in that array

        size = size + 1;
    }
    loop_day = loop_day + 1;
}

Но я хочу что-то подобное этому:

custom_loop {
// code that stores various values into an array
}

custom_loop {
// code that reads values stored in that array
}

person pulpbag    schedule 08.05.2018    source источник
comment
возможно, inline функции могут помочь.   -  person Ali Yılmaz    schedule 08.05.2018
comment
Две вещи для Google: макросы и указатели функций.   -  person Antti Haapala    schedule 08.05.2018
comment
От каких переменных зависит new lines here?   -  person Bathsheba    schedule 08.05.2018
comment
Пожалуйста, заполните код, чтобы показать пример.   -  person Antti Haapala    schedule 08.05.2018
comment
@Bathsheba Не переменные, утверждения. Но операторы используют члены структуры.   -  person pulpbag    schedule 08.05.2018
comment
Просто напишите функцию.   -  person Lundin    schedule 08.05.2018
comment
@Lundin Как заставить функцию принимать операторы в качестве аргументов?   -  person pulpbag    schedule 08.05.2018
comment
Передайте параметры, сообщающие функции, что делать. Общего ответа нет, в каждом конкретном случае он разный.   -  person Lundin    schedule 08.05.2018
comment
@Lundin Могу ли я передать что-то вроде [loop_day][loop_size].forget = 0;?   -  person pulpbag    schedule 08.05.2018
comment
@pulpbag Не уверен, что это должно означать, функция с 3 параметрами?   -  person Lundin    schedule 08.05.2018
comment
пример с макросом приведен в: Можно ли использовать блок кода в качестве аргумента макроса C?   -  person Lanting    schedule 08.05.2018
comment
@Lundin Я имею в виду несколько утверждений, например a = 0;, b = c, a = a + 1 одновременно.   -  person pulpbag    schedule 08.05.2018
comment
Все это одна большая XY-проблема. Передача нескольких операторов, скорее всего, является неправильным решением реальной проблемы.   -  person Lundin    schedule 08.05.2018
comment
@Lundin Я прекрасно понимаю, что нельзя передавать утверждения в качестве аргументов, я просто просил эквивалент передачи утверждений. (Кстати, не могли бы вы описать свое отношение к проблеме?)   -  person pulpbag    schedule 08.05.2018
comment
Нет эквивалента, потому что это не имеет смысла с самого начала. Либо вы передаете различные числовые переменные и что-то с ними делаете, либо вы передаете переменную состояния, такую ​​как перечисление, и делаете разные вещи на основе этого, либо вы можете передать указатель функции, выполняющий определенное поведение и т.д., и т.д. Или вы можете вызывать разные функции в во-первых, сортируя различия в вызывающей стороне, а не внутри функции. Попробуйте описать и решить настоящую проблему вместо того, чтобы пытаться понять, как делать действительно странные вещи.   -  person Lundin    schedule 08.05.2018
comment
@Lundin Я никогда не пытался передавать операторы в функцию, я знаю, что это работает не так. Все, что я хотел, это способ избежать дублирования кода, поместив мой пользовательский цикл внутри чего-то вроде функции, чтобы я мог вызывать его всякий раз, когда это необходимо, с оговоркой: вам нужно делать разные вещи в середине цикла каждый раз, когда вы вызываете цикл: что вы бы поняли, если бы прочитали примеры, которые я включил. (Я также не понимаю, как я мог бы описать ... реальную проблему лучше, чем то, что у меня уже есть.)   -  person pulpbag    schedule 08.05.2018


Ответы (2)


Вы можете думать о функциях обратного вызова. Например,

typedef void (*t_func)(int, int);

void doLoopOverDaysAndSize(t_func callback)
{
    while (loop_day < (day+1)) {
        while (loop_size < (size+1)) {
            callback(loop_day, loop_size)
            size = size + 1;
        }
        loop_day = loop_day + 1;
    }
 }

Затем вы можете передать некоторую функцию, подобную этой

void myDaySizeHandler(int day, int size)
{
    // do something
}
person rhaport    schedule 08.05.2018
comment
Не могли бы вы уточнить, как я могу применить это к моей ситуации? - person pulpbag; 08.05.2018
comment
в основном, вы реализуете один раз функцию doLoopOverDaysAndSize(), как указано выше. Разумеется, переменные loop_day и loop_size должны быть правильно определены локальными переменными. Кроме того, вы должны заботиться о том, как день и размер предоставляются функции. Это должно быть понятно из контекста вашего приложения. Затем вы реализуете различные функции, такие как myDaySizeHandler, которые должны содержать тело цикла. Он соответствует вашему комментарию // коду, который считывает значения, хранящиеся в этом массиве. Затем вы можете вызвать doLoopOverDaysAndSize(myDaySizeHandler); - person rhaport; 08.05.2018
comment
@pulpbag Вы сказали, что у вас есть повторяющийся фрагмент кода, которым вы хотите обернуть другой код. Обратные вызовы (указатели функций) — это то, как это сделать: вы передаете функцию и выполняете ее в коде, который обертывает операторы, которые вы хотите передать, которые находятся в функции, которую вы передаете в цикл. Просто погуглите функции обратного вызова, я имею в виду, что код в ответе в значительной степени является дословной реализацией: ваши утверждения идут в myDaySizeHandler. - person Dave Newton; 08.05.2018

Люди склонны забывать, что включения можно использовать в любом месте вашего кода, а не только для заголовков ( other">Включение одного исходного файла C в другой?). Однако некоторые осуждают их.

Пример:

Common.inc:

x = x + 1;

main.c

int main()
{
    {
        int x = 3;
#include "common.inc"
        printf("x = %d\n", x);
    }
    {
        double x = 1.234;
#include "common.inc"
        printf("x = %f\n", x);
    }
    return 0;
}

-Edit- Для вашего кода это приведет к:

commonStart.inc

while (loop_day < (day+1))
{
    while (loop_size < (size+1))
    {

commonEnd.inc

        size = size + 1;
    }
    loop_day = loop_day + 1;
}

main.c

#include "commonStart.inc"
//new lines here
#include "commonEnd.inc"
person Lanting    schedule 08.05.2018
comment
Я не понимаю, как я могу встроить несколько операторов в свой вышеупомянутый фрагмент кода (собственный цикл, если хотите), используя это. - person pulpbag; 08.05.2018
comment
Это сработает, но это кажется странным, когда у вас есть указатели на функции. И ИМО, это немного сложнее читать или рассуждать. - person Dave Newton; 08.05.2018
comment
Это было бы ответом на вопрос: как я могу написать код, который еще хуже, чем изобретать какой-то неясный, похожий на функцию язык макросов. Никогда не злоупотребляйте подобным образом, это не что иное, как запутывание и действительно плохой совет. - person Lundin; 08.05.2018
comment
Однако некоторые осуждают их. Здесь под некоторыми ты подразумеваешь практически всех? Я изо всех сил пытаюсь придумать правильный вариант использования, который лучше не обрабатывается указателями или макросами. Можете ли вы привести пример, когда это было бы хорошей идеей? - person Dave Newton; 08.05.2018