Я хочу написать функцию C, которая будет печатать от 1 до N по одной на каждую строку на stdout, где N является параметром int для функции. Функция не должна использоваться во время циклов do-while, инструкции goto, рекурсии и оператора switch. Является ли это возможным?C: Looping без использования инструкций цикла или рекурсии
ответ
С блокировкой чтения, сигналов и сигнализации. Я думал, что мне придется использовать sigaction и SA_RESTART, но, похоже, он работал достаточно хорошо.
Обратите внимание, что setitimer/alarm, вероятно, имеет значение unix/-like.
#include <signal.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
volatile sig_atomic_t counter;
volatile sig_atomic_t stop;
void alarm_handler(int signal)
{
printf("%d\n", counter++);
if (counter > stop)
{
exit(0);
}
}
int main(int argc, char **argv)
{
struct itimerval v;
v.it_value.tv_sec = 0;
v.it_value.tv_usec = 5000;
v.it_interval.tv_sec = 0;
v.it_interval.tv_usec = 5000;
int pipefds[2];
char b;
stop = 10;
counter = 1;
pipe(pipefds);
signal(SIGALRM, alarm_handler);
setitimer(ITIMER_REAL, &v, NULL);
read(pipefds[0], &b, 1);
}
Не стандарт C, но я не буду проголосовать за вас, так как любой причудливый достаточно, чтобы придумать это решение, вероятно, достаточно психотичен, чтобы отследить меня и нанести серьезный вред :-) – paxdiablo
@paxdiablo: да, боюсь, тело моего ботаника! Кроме того, добавление оскорбления к травме, C99 заявляет, что вызов, т. Е. Printf внутри обработчика сигналов, может быть не полностью определен. :) –
записать все возможные выходные данные в строку сначала, а null прекратить ее, где выход должен остановиться.
Это довольно грязное решение, но с учетом ограничений, все, что я могу придумать,
за исключением использования ассемблера, конечно.
char a[]="1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n"/*...*/;
main(n,v)char**v;{n=atoi(v[1]);
#define c(x)(n>x?n-x:0)
a[n+c(1)+c(9)+c(99)+c(999)+c(9999)+c(99999)+c(999999)+c(9999999)/*+...*/]=0;
puts(a);}
Учитывая, что MAX_INT==2147483647
на популярных архитектур, нам нужно только подойти к +c(999999999)
. Вывод этой начальной строки может занять некоторое время, хотя ...
N не фиксирован, поэтому вы не можете развернуть петлю. Насколько я знаю, у C нет итераторов.
Вы должны найти что-то, что имитирует цикл.
Или думать вне коробки:
(например, N ограничено до 1000, но это легко адаптироваться)
int f(int N) {
if (N >= 900) f100(100);
if (N >= 800) f100(100);
if (N >= 700) f100(100);
...
f100(n % 100);
}
int f100(int N) {
if (N >= 90) f10(10);
if (N >= 80) f10(10);
if (N >= 70) f10(10);
...
f(n % 10);
}
int f10(int N) {
if (N >= 9) func();
if (N >= 8) func();
if (N >= 7) func();
...
}
Yhis кажется лучшим решением на сегодняшний день, каждый новый уровень функции дает вам десятикратное увеличение пространства. Это должно привести вас к 2^63-1 довольно быстро. – paxdiablo
Можно обернуть его в макросы – vava
+1. Все остальные решения используют что-то в стандартных библиотеках, которые в некотором роде похожи на ходоподобные или похожие на петли (longjmp, очередь сигналов, стек atexit, цикл в qsort). Это даже не доходит до библиотек (за исключением фактического кода ввода-вывода, который необходимо добавить для завершения кода), так как решение устойчиво к простым изменениям требований. –
Если вы знаете, верхний предел N, вы можете попробовать что-то вроде это;)
void func(int N)
{
char *data = " 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9\n10\n11\n12\n";
if (N > 0 && N < 12)
printf("%.*s", N*3, data);
else
printf("Not enough data. Need to reticulate some more splines\n");
}
Шутка в сторону, я действительно не понимаю, как вы можете сделать это без рекурсии или все инструкции вы упомянули там. Это заставляет меня больше интересоваться решением.
Редактировать: Просто заметил, что я предложил такое же решение, как grombeestje :)
Это делает:
int main()
{
printf ("1 to N one per each line\n");
return 0;
}
Вот еще один:
#include <stdlib.h>
#include <stdio.h>
int main (int c, char ** v) {
char b[100];
sprintf (b, "perl -e 'map {print \"$_\\n\"} (1..%s)'", v[1]);
system (b);
return 0;
}
Я уже разместил это как комментарий перед вами. Cheers .. - :) – Vadakkumpadath
О, извините, но я этого не заметил. – 2009-10-14 08:58:05
Я обнаружил функцию переполнения буфера. – spoulson
Вы можете используйте функции setjmp и logjmp для этого, как показано на рисунке in this C FAQ
Для тех, кому интересно, почему у кого-то есть такой вопрос, это один из часто задаваемых вопросов в Индии для найма свежих сортов.
Итак, стандартный вопрос вербовки: «Как вы делаете что-то мирское, не используя какие-либо методы, которые вы должны использовать, а вместо этого делаете это излишне византийским и сложным образом, без всякой причины?» Дай, как это применимо. – phoebus
Да, это своего рода «стандартный» вопрос вербовки здесь. Но большинство компаний, которые задают такие вопросы, даже не набирают их на работу программиста C, и в большинстве случаев человек, задающий такой вопрос, не имеет реального опыта программирования. – Technowise
Является ли setjmp/longjmp просто синтаксическим сахаром для goto? Кажется, как рекрутер, я бы запретил использовать это тоже. – mrduclaw
Вы можете сделать это, вложив макросы.
int i = 1;
#define PRINT_1(N) if(i < N) printf("%d\n", i++);
#define PRINT_2(N) PRINT_1(N) PRINT_1(N)
#define PRINT_3(N) PRINT_2(N) PRINT_2(N)
#define PRINT_4(N) PRINT_3(N) PRINT_3(N)
:
:
#define PRINT_32(N) PRINT_31(N) PRINT_31(N)
Всего будет 32 макроса. Предполагая размер int
как 4 байта. Теперь вызовите PRINT_32(N)
из любой функции.
Редактировать: Добавить пример для наглядности.
void Foo(int n)
{
i = 1;
PRINT_32(n);
}
void main()
{
Foo(5);
Foo(55);
Foo(555);
Foo(5555);
}
Просто удалите N из параметров макроса, и вы хорошо пойдете. Я уверен, что полученный 4GB исходный файл убьет компилятор, но теоретически он должен работать. – itsadok
Это будет больше 4 ГБ, нет? 2^32 * (28 байтов) = 120 ГБ. –
Спасибо всем; Я знаю, что эта идея непрактична, но это логично ... Я не думаю, что есть компилятор, у которого достаточно кучи для компиляции этого кода. Это может быть код, который должен быть сделан к 2050 году. :) – Vadakkumpadath
Я бы для использования longjmp()
#include <stdio.h>
#include <setjmp.h>
void do_loop(int n) {
int val;
jmp_buf env;
val = 0;
setjmp(env);
printf("%d\n", ++val);
if (val != n)
longjmp(env, 0);
}
int main() {
do_loop(7);
return 0;
}
#include <stdlib.h>
int callback(const void *a, const void *b) {
static int n = 1;
if (n <= N)
printf("%d\n", n++);
return 0;
}
int main(int argc, char *argv) {
char *buf;
/* get N value here */
buf = malloc(N); // could be less than N, but N is definitely sufficient
qsort(buf, N, 1, callback);
}
Я думаю, что это не считается рекурсии.
ничего себе. что взорвало мой разум. sneaky: использовать чей-то петлю ... –
qsort использовать «для» или «пока» внутри, поэтому ваша идея нарушает правило. – Test
@Effo, по вашим рассуждениям, любое решение, использующее printf(), также недействительно, поскольку оно, без сомнения, использовало какой-либо цикл для обработки строки формата. Это очень упростит печать строки. – paxdiablo
Я очень разочарован тем, что это не работает. Для меня фраза «функция вызывается после того, как какие-либо ранее зарегистрированные функции, которые уже были вызваны в момент ее регистрации», предполагает, что после того, как они начали вызываться, можно зарегистрировать обработчики atexit. То есть, обработчик может зарегистрировать другой обработчик. В противном случае, как вообще возможно существование функции, которая была вызвана во время регистрации другой функции? Но для меня вызов atexit возвращает 0 успеха, но фактически не приводит к другому вызову. Кто-нибудь знает, почему я сделал какую-то глупую ошибку?
#include "stdio.h"
#include "stdlib.h"
int count = 0;
int limit = 10;
void handler() {
printf("%d of %d\n", ++count, limit);
if (count < limit) atexit(handler);
}
int main(int argc, char **argv) {
if (argc > 1) limit = atoi(argv[1]);
atexit(handler);
}
Кстати, не рекурсию, потому что atexit не вызывает его параметр, то в очередь он будет называться позже. Очевидно, что среда выполнения C содержит цикл для вызова обработчиков atexit, но этот цикл существует независимо от того, зарегистрируете ли вы какие-либо обработчики atexit или нет. Таким образом, если эта программа содержит цикл, так что делает каждую С программой ;-)
см. «Современный дизайн C++: общие шаблоны программирования и дизайна». 6.6.1 Проблемы с atexit. – Test
Кстати, мое предложение atexit получило голос -2, перестаньте его пытаться – Test
Спасибо за это. Резюме: стандарт был неадекватным и не указывал, что должно произойти. Стандарт был скорректирован. Мой компилятор не включает исправление, но если бы это произошло, этот код работал бы. –
Это принимает целое число N из командной строки и печатает от 1 до N
#include <stdio.h>
#include <stdlib.h>
int total;
int N;
int print16(int n)
{
printf("%d\n",n+0x01); total++; if (total >= N) exit(0);
printf("%d\n",n+0x02); total++; if (total >= N) exit(0);
printf("%d\n",n+0x03); total++; if (total >= N) exit(0);
printf("%d\n",n+0x04); total++; if (total >= N) exit(0);
printf("%d\n",n+0x05); total++; if (total >= N) exit(0);
printf("%d\n",n+0x06); total++; if (total >= N) exit(0);
printf("%d\n",n+0x07); total++; if (total >= N) exit(0);
printf("%d\n",n+0x08); total++; if (total >= N) exit(0);
printf("%d\n",n+0x09); total++; if (total >= N) exit(0);
printf("%d\n",n+0x0A); total++; if (total >= N) exit(0);
printf("%d\n",n+0x0B); total++; if (total >= N) exit(0);
printf("%d\n",n+0x0C); total++; if (total >= N) exit(0);
printf("%d\n",n+0x0D); total++; if (total >= N) exit(0);
printf("%d\n",n+0x0E); total++; if (total >= N) exit(0);
printf("%d\n",n+0x0F); total++; if (total >= N) exit(0);
printf("%d\n",n+0x10); total++; if (total >= N) exit(0);
}
int print256(int n)
{
print16(n);
print16(n+0x10);
print16(n+0x20);
print16(n+0x30);
print16(n+0x40);
print16(n+0x50);
print16(n+0x60);
print16(n+0x70);
print16(n+0x80);
print16(n+0x90);
print16(n+0xA0);
print16(n+0xB0);
print16(n+0xC0);
print16(n+0xD0);
print16(n+0xE0);
print16(n+0xF0);
}
int print4096(int n)
{
print256(n);
print256(n+0x100);
print256(n+0x200);
print256(n+0x300);
print256(n+0x400);
print256(n+0x500);
print256(n+0x600);
print256(n+0x700);
print256(n+0x800);
print256(n+0x900);
print256(n+0xA00);
print256(n+0xB00);
print256(n+0xC00);
print256(n+0xD00);
print256(n+0xE00);
print256(n+0xF00);
}
int print65536(int n)
{
print4096(n);
print4096(n+0x1000);
print4096(n+0x2000);
print4096(n+0x3000);
print4096(n+0x4000);
print4096(n+0x5000);
print4096(n+0x6000);
print4096(n+0x7000);
print4096(n+0x8000);
print4096(n+0x9000);
print4096(n+0xA000);
print4096(n+0xB000);
print4096(n+0xC000);
print4096(n+0xD000);
print4096(n+0xE000);
print4096(n+0xF000);
}
int print1048576(int n)
{
print65536(n);
print65536(n+0x10000);
print65536(n+0x20000);
print65536(n+0x30000);
print65536(n+0x40000);
print65536(n+0x50000);
print65536(n+0x60000);
print65536(n+0x70000);
print65536(n+0x80000);
print65536(n+0x90000);
print65536(n+0xA0000);
print65536(n+0xB0000);
print65536(n+0xC0000);
print65536(n+0xD0000);
print65536(n+0xE0000);
print65536(n+0xF0000);
}
int print16777216(int n)
{
print1048576(n);
print1048576(n+0x100000);
print1048576(n+0x200000);
print1048576(n+0x300000);
print1048576(n+0x400000);
print1048576(n+0x500000);
print1048576(n+0x600000);
print1048576(n+0x700000);
print1048576(n+0x800000);
print1048576(n+0x900000);
print1048576(n+0xA00000);
print1048576(n+0xB00000);
print1048576(n+0xC00000);
print1048576(n+0xD00000);
print1048576(n+0xE00000);
print1048576(n+0xF00000);
}
int print268435456(int n)
{
print16777216(n);
print16777216(n+0x1000000);
print16777216(n+0x2000000);
print16777216(n+0x3000000);
print16777216(n+0x4000000);
print16777216(n+0x5000000);
print16777216(n+0x6000000);
print16777216(n+0x7000000);
print16777216(n+0x8000000);
print16777216(n+0x9000000);
print16777216(n+0xA000000);
print16777216(n+0xB000000);
print16777216(n+0xC000000);
print16777216(n+0xD000000);
print16777216(n+0xE000000);
print16777216(n+0xF000000);
}
int print2147483648(int n)
{
/*
* Only goes up to n+0x70000000 since we
* deal only with postive 32 bit integers
*/
print268435456(n);
print268435456(n+0x10000000);
print268435456(n+0x20000000);
print268435456(n+0x30000000);
print268435456(n+0x40000000);
print268435456(n+0x50000000);
print268435456(n+0x60000000);
print268435456(n+0x70000000);
}
int main(int argc, char *argv[])
{
int i;
if (argc > 1) {
N = strtol(argv[1], NULL, 0);
}
if (N >=1) {
printf("listing 1 to %d\n",N);
print2147483648(0);
}
else {
printf("Must enter a postive integer N\n");
}
}
другой штуковины (на Linux) будет будет делать, как показано ниже, где 7 Н
int main() {
return system("seq 7");
}
/// <summary>
/// Print one to Hundred without using any loop/condition.
/// </summary>
int count = 100;
public void PrintOneToHundred()
{
try
{
int[] hey = new int[count];
Console.WriteLine(hey.Length);
count--;
PrintOneToHundred();
}
catch
{
Console.WriteLine("Done Printing");
}
}
int x=1;
void PRINT_2(int);
void PRINT_1(int n)
{ if(x>n)
return;
printf("%d\n",x++);
PRINT_2(n);
}
void PRINT_2(int n)
{ if(x>n)
return;
printf("%d\n",x++);
PRINT_1(n);
}
int main()
{ int n;
scanf("%d",&n);
if(n>0)
PRINT_1(n);
system("pause");
}
#include "stdio.h"
#include "stdlib.h"
#include "signal.h"
int g_num;
int iterator;
void signal_print()
{
if(iterator>g_num-1)
exit(0);
printf("%d\n",++iterator);
}
void myprintf(int n)
{
g_num=n;
int *p=NULL;
int x= *(p); // the instruction is reexecuted after handling the signal
}
int main()
{
signal(SIGSEGV,signal_print);
int n;
scanf("%d",&n);
myprintf(n);
return 0;
}
- 1. GCD без использования рекурсии
- 2. Как печатать массив без использования цикла и рекурсии В java
- 3. Создание функции без использования рекурсии
- 4. Перемещение каталогов без использования рекурсии?
- 5. Отображение от 1 до 100 без цикла или рекурсии
- 6. Создание определенного вектора без цикла или рекурсии в R
- 7. Двоичный обход дерева без использования рекурсии
- 8. LINQ без использования цикла
- 9. Looping против рекурсии с F #
- 10. обратная строка без использования strrev и любого типа цикла или рекурсии
- 11. Элементы массива Multiply без использования цикла
- 12. PostOrder Traversal дерева без использования рекурсии или стека
- 13. Итерации через файловую систему без использования двоичного дерева или рекурсии
- 14. Время запуска инструкций цикла for
- 15. Как отсортировать без использования цикла
- 16. Looping через массив без использования свойства
- 17. Как создать флаг в excel без использования нескольких инструкций OR?
- 18. C# Иерархия пересечения без рекурсии
- 19. BNF-грамматика с использованием инструкций цикла
- 20. Функция сна в javascript - без использования рекурсии
- 21. Переписывание рекурсивной функции без использования рекурсии
- 22. проверить существование ряда или более без использования для цикла
- 23. C++ Looping Да или нет
- 24. Vectorize это без использования цикла
- 25. Код анаграммы без использования цикла
- 26. попарно evlaluation без использования цикла
- 27. Прослеживание рекурсии внутри цикла
- 28. Ошибка рекурсии Python без рекурсии?
- 29. печати дерево без рекурсии
- 30. Пользовательская наложение инструкций с выделенным представлением (без использования ShowcaseViewLibrary)
из curiosi Почему? – phoebus
Если это сложный вопрос, и мы даем вам ответ, проблема будет испорчена. –
разрешено использовать инструкции сборки в c-коде? –