Как напечатать от 1 до N без точки с запятой? Объясните этот код

// A recursive C program to print all numbers from 1
// to N without semicoolon 
#include<stdio.h>
#define N 10

int main(int num)
{
    if (num <= N && printf("%d ", num) && main(num + 1))
    {
    }     
}

Как работает эта программа? Пожалуйста, объясните это

2 ответа

Код в этом ужасном примере опирается на некоторые хрупкие предположения:

main вызывается с двумя аргументами: int представляющий количество аргументов, включая имя программы и массив char* содержащий строку аргумента, оканчивающуюся на NULL,

В примере предполагается, что определение main() с одним int Аргумент создаст код, совместимый с этим соглашением о вызовах, который может быть или не быть действительным и явно описан как имеющий неопределенное поведение в Стандарте C (J.2).

Если он действителен или работает случайно, int аргумент, полученный main будет 1 если программа вызывается из командной строки без аргументов.

main() проверяет, является ли этот аргумент <= N, другими словами, если значение должно быть напечатано. Если это так, это вызывает printf("%d ", num), который выводит десятичное представление num в stdout и возвращает количество произведенных символов, 2 для первого числа, которое не равно нулю, поэтому код продолжается и вызывает main рекурсивно, передавая ему следующий более высокий номер.

Идет, пока все числа до N были напечатаны, и первый тест в последнем рекурсивном вызове не прошел.

main затем возвращается 0 (если компилятор соответствует C99 или более позднему стандарту). Каждый рекурсивный вызов возвращается 0 пока первоначальный вызов не вернется 0 в систему.

Код хрупок, потому что main вызывается нестандартным способом. Было бы немного менее уродливо написать:

#include <stdio.h>

#define N 10

int main(int argc, char *argv[]) {
    if (num <= N && printf("%d ", num) && main(num + 1, argv)) {}
}

Обратите внимание, однако, что вызов main() рекурсивно, как правило, считается плохой практикой.

Пока функция внутри возвращает значение, конвертируемое в bool, оно также будет принято вызываться.

В случае успеха возвращается общее количество написанных символов. При неудаче возвращается отрицательное число.

Выше возвращаемое значение функции printf(). Так что да printf("%d ", num) в этом случае всегда будет возвращать true и печатать на каждой итерации.

Другие вопросы по тегам