Печать от 1 до 1000 без петель или условных обозначений

308

Задача: печать чисел от 1 до 1000 без использования каких-либо циклов или условных операторов. Не просто пишите инструкцию printf() или cout 1000 раз.

Как вы это сделаете с помощью C или С++?

  • 0
    Итак .... у вас вопрос, как мне это сделать ?
  • 137
    Очевидный ответ - использовать 500 вызовов для printf и печатать два числа каждый раз, нет?
Показать ещё 33 комментария
Теги:
printf

106 ответов

827
Лучший ответ

Рекурсия времени компиляции!: P

#include <iostream>
template<int N>
struct NumberGeneration{
  static void out(std::ostream& os)
  {
    NumberGeneration<N-1>::out(os);
    os << N << std::endl;
  }
};
template<>
struct NumberGeneration<1>{
  static void out(std::ostream& os)
  {
    os << 1 << std::endl;
  }
};
int main(){
   NumberGeneration<1000>::out(std::cout);
}
  • 1
    Вы знаете, это имело бы смысл. Но это странный вопрос, спрашивать, хочет ли он знать, знает ли парень, что шаблоны Тьюринга завершены.
  • 9
    @Motti: нет, я не ideone.com/A0ZQZ
Показать ещё 31 комментарий
1140

Этот фактически компилируется в сборку, которая не имеет никаких условных выражений:

#include <stdio.h>
#include <stdlib.h>

void main(int j) {
  printf("%d\n", j);
  (&main + (&exit - &main)*(j/1000))(j+1);
}


Изменить: Добавлено '&' поэтому он будет рассматривать адрес, следовательно, избегая ошибок указателя.

Эта версия выше в стандарте C, так как она не полагается на арифметику на указатели функций:

#include <stdio.h>
#include <stdlib.h>

void f(int j)
{
    static void (*const ft[2])(int) = { f, exit };

    printf("%d\n", j);
    ft[j/1000](j + 1);
}

int main(int argc, char *argv[])
{
    f(1);
}
  • 1
    Отличное решение. Если бы он вышел с кодом состояния 0, это было бы идеально. Я все еще проголосовал, хотя ... ИДЕЯ: заменить (++ j) на (++ j * (1 - (j / 1001)), и он выйдет с кодом состояния 0: D
  • 1
    Да, я изначально реализовал это таким образом. Но краткость этого решения была слишком неотразимой.
Показать ещё 23 комментария
571
#include <stdio.h>
int i = 0;
p()    { printf("%d\n", ++i); }
a()    { p();p();p();p();p(); }
b()    { a();a();a();a();a(); }
c()    { b();b();b();b();b(); }
main() { c();c();c();c();c();c();c();c(); return 0; }

Я удивлен, что никто, кажется, не опубликовал это - я думал, что это самый очевидный способ. 1000 = 5*5*5*8.

  • 0
    Люди это опубликовали. Другие версии передают номер для печати вместо использования глобального, но по сути это то же решение.
  • 1
    @ Крис, они используют ту же логику, выраженную в макросах или шаблонах, увеличивая размер кода, верно? Вы могли бы также сгенерировать саму строку вывода вместо тысячи printfs.
Показать ещё 2 комментария
312

Похоже, что не нужно использовать циклы

printf("1 10 11 100 101 110 111 1000\n");
  • 1
    можно утверждать, что использование copy - это обман
  • 13
    @ Йоханнес на самом деле я уверен, что у printf есть цикл: p
Показать ещё 8 комментариев
285

Вот три решения, которые я знаю. Во-вторых, можно утверждать, что.

// compile time recursion
template<int N> void f1()
{ 
    f1<N-1>(); 
    cout << N << '\n'; 
}

template<> void f1<1>() 
{ 
    cout << 1 << '\n'; 
}

// short circuiting (not a conditional statement)
void f2(int N)
{ 
    N && (f2(N-1), cout << N << '\n');
}

// constructors!
struct A {
    A() {
        static int N = 1;
        cout << N++ << '\n';
    }
};

int main()
{
    f1<1000>();
    f2(1000);
    delete[] new A[1000]; // (3)
    A data[1000]; // (4) added by Martin York
}

[Изменить: (1) и (4) можно использовать только для констант времени компиляции, (2) и (3) можно использовать для выражений времени выполнения too — редактирование. ]

  • 1
    конструктор один это круто. Я упомянул, что видел java-вопрос, где у них есть массив 1000, и он выполняет arr [param] = val, который будет выдавать, когда он достигает 1000 и перехватывается в конце main ().
  • 0
    (4) может также использоваться для значений времени выполнения в современных компиляторах, которые поддерживают расширения C99 в режиме C ++. Давай, это 2010, давайте не будем бояться VLA :)
Показать ещё 7 комментариев
277

Я не пишу инструкцию printf 1000 раз!

printf("1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n34\n35\n36\n37\n38\n39\n40\n41\n42\n43\n44\n45\n46\n47\n48\n49\n50\n51\n52\n53\n54\n55\n56\n57\n58\n59\n60\n61\n62\n63\n64\n65\n66\n67\n68\n69\n70\n71\n72\n73\n74\n75\n76\n77\n78\n79\n80\n81\n82\n83\n84\n85\n86\n87\n88\n89\n90\n91\n92\n93\n94\n95\n96\n97\n98\n99\n100\n101\n102\n103\n104\n105\n106\n107\n108\n109\n110\n111\n112\n113\n114\n115\n116\n117\n118\n119\n120\n121\n122\n123\n124\n125\n126\n127\n128\n129\n130\n131\n132\n133\n134\n135\n136\n137\n138\n139\n140\n141\n142\n143\n144\n145\n146\n147\n148\n149\n150\n151\n152\n153\n154\n155\n156\n157\n158\n159\n160\n161\n162\n163\n164\n165\n166\n167\n168\n169\n170\n171\n172\n173\n174\n175\n176\n177\n178\n179\n180\n181\n182\n183\n184\n185\n186\n187\n188\n189\n190\n191\n192\n193\n194\n195\n196\n197\n198\n199\n200\n201\n202\n203\n204\n205\n206\n207\n208\n209\n210\n211\n212\n213\n214\n215\n216\n217\n218\n219\n220\n221\n222\n223\n224\n225\n226\n227\n228\n229\n230\n231\n232\n233\n234\n235\n236\n237\n238\n239\n240\n241\n242\n243\n244\n245\n246\n247\n248\n249\n250\n251\n252\n253\n254\n255\n256\n257\n258\n259\n260\n261\n262\n263\n264\n265\n266\n267\n268\n269\n270\n271\n272\n273\n274\n275\n276\n277\n278\n279\n280\n281\n282\n283\n284\n285\n286\n287\n288\n289\n290\n291\n292\n293\n294\n295\n296\n297\n298\n299\n300\n301\n302\n303\n304\n305\n306\n307\n308\n309\n310\n311\n312\n313\n314\n315\n316\n317\n318\n319\n320\n321\n322\n323\n324\n325\n326\n327\n328\n329\n330\n331\n332\n333\n334\n335\n336\n337\n338\n339\n340\n341\n342\n343\n344\n345\n346\n347\n348\n349\n350\n351\n352\n353\n354\n355\n356\n357\n358\n359\n360\n361\n362\n363\n364\n365\n366\n367\n368\n369\n370\n371\n372\n373\n374\n375\n376\n377\n378\n379\n380\n381\n382\n383\n384\n385\n386\n387\n388\n389\n390\n391\n392\n393\n394\n395\n396\n397\n398\n399\n400\n401\n402\n403\n404\n405\n406\n407\n408\n409\n410\n411\n412\n413\n414\n415\n416\n417\n418\n419\n420\n421\n422\n423\n424\n425\n426\n427\n428\n429\n430\n431\n432\n433\n434\n435\n436\n437\n438\n439\n440\n441\n442\n443\n444\n445\n446\n447\n448\n449\n450\n451\n452\n453\n454\n455\n456\n457\n458\n459\n460\n461\n462\n463\n464\n465\n466\n467\n468\n469\n470\n471\n472\n473\n474\n475\n476\n477\n478\n479\n480\n481\n482\n483\n484\n485\n486\n487\n488\n489\n490\n491\n492\n493\n494\n495\n496\n497\n498\n499\n500\n501\n502\n503\n504\n505\n506\n507\n508\n509\n510\n511\n512\n513\n514\n515\n516\n517\n518\n519\n520\n521\n522\n523\n524\n525\n526\n527\n528\n529\n530\n531\n532\n533\n534\n535\n536\n537\n538\n539\n540\n541\n542\n543\n544\n545\n546\n547\n548\n549\n550\n551\n552\n553\n554\n555\n556\n557\n558\n559\n560\n561\n562\n563\n564\n565\n566\n567\n568\n569\n570\n571\n572\n573\n574\n575\n576\n577\n578\n579\n580\n581\n582\n583\n584\n585\n586\n587\n588\n589\n590\n591\n592\n593\n594\n595\n596\n597\n598\n599\n600\n601\n602\n603\n604\n605\n606\n607\n608\n609\n610\n611\n612\n613\n614\n615\n616\n617\n618\n619\n620\n621\n622\n623\n624\n625\n626\n627\n628\n629\n630\n631\n632\n633\n634\n635\n636\n637\n638\n639\n640\n641\n642\n643\n644\n645\n646\n647\n648\n649\n650\n651\n652\n653\n654\n655\n656\n657\n658\n659\n660\n661\n662\n663\n664\n665\n666\n667\n668\n669\n670\n671\n672\n673\n674\n675\n676\n677\n678\n679\n680\n681\n682\n683\n684\n685\n686\n687\n688\n689\n690\n691\n692\n693\n694\n695\n696\n697\n698\n699\n700\n701\n702\n703\n704\n705\n706\n707\n708\n709\n710\n711\n712\n713\n714\n715\n716\n717\n718\n719\n720\n721\n722\n723\n724\n725\n726\n727\n728\n729\n730\n731\n732\n733\n734\n735\n736\n737\n738\n739\n740\n741\n742\n743\n744\n745\n746\n747\n748\n749\n750\n751\n752\n753\n754\n755\n756\n757\n758\n759\n760\n761\n762\n763\n764\n765\n766\n767\n768\n769\n770\n771\n772\n773\n774\n775\n776\n777\n778\n779\n780\n781\n782\n783\n784\n785\n786\n787\n788\n789\n790\n791\n792\n793\n794\n795\n796\n797\n798\n799\n800\n801\n802\n803\n804\n805\n806\n807\n808\n809\n810\n811\n812\n813\n814\n815\n816\n817\n818\n819\n820\n821\n822\n823\n824\n825\n826\n827\n828\n829\n830\n831\n832\n833\n834\n835\n836\n837\n838\n839\n840\n841\n842\n843\n844\n845\n846\n847\n848\n849\n850\n851\n852\n853\n854\n855\n856\n857\n858\n859\n860\n861\n862\n863\n864\n865\n866\n867\n868\n869\n870\n871\n872\n873\n874\n875\n876\n877\n878\n879\n880\n881\n882\n883\n884\n885\n886\n887\n888\n889\n890\n891\n892\n893\n894\n895\n896\n897\n898\n899\n900\n901\n902\n903\n904\n905\n906\n907\n908\n909\n910\n911\n912\n913\n914\n915\n916\n917\n918\n919\n920\n921\n922\n923\n924\n925\n926\n927\n928\n929\n930\n931\n932\n933\n934\n935\n936\n937\n938\n939\n940\n941\n942\n943\n944\n945\n946\n947\n948\n949\n950\n951\n952\n953\n954\n955\n956\n957\n958\n959\n960\n961\n962\n963\n964\n965\n966\n967\n968\n969\n970\n971\n972\n973\n974\n975\n976\n977\n978\n979\n980\n981\n982\n983\n984\n985\n986\n987\n988\n989\n990\n991\n992\n993\n994\n995\n996\n997\n998\n999\n1000\n");

Добро пожаловать;)

  • 223
    Я надеюсь, что вы написали программу для генерации этой строки.
  • 538
    @ Martin И надеюсь, что программа не printf ("printf (1 \\ n2 \\ ....
Показать ещё 8 комментариев
213
printf("%d\n", 2);
printf("%d\n", 3);

Он не печатает все числа, но он "печатает номера от 1 до 1000". Неоднозначный вопрос для победы!:)

  • 77
    мой любимый после 'printf ("числа от 1 до 1000") - глупые вопросы требуют глупых ответов.
  • 0
    это круто. +1 за использование неясности в вопросе. ха-ха
Показать ещё 2 комментария
166

Использование системных команд:

system("/usr/bin/seq 1000");
  • 6
    ну это менее портативное решение ..
  • 15
    Высокий шанс /usr/bin/seq использует цикл внутри. :)
Показать ещё 3 комментария
164

Запустить фатальную ошибку! Здесь файл, countup.c:

#include <stdio.h>
#define MAX 1000
int boom;
int foo(n) {
    boom = 1 / (MAX-n+1);
    printf("%d\n", n);
    foo(n+1);
}
int main() {
    foo(1);
}

Скомпилируйте, затем выполните в командной строке:

$ ./countup
1
2
3
...
996
997
998
999
1000
Floating point exception
$

Это действительно печатает числа от 1 до 1000 без каких-либо циклов или условных обозначений!

  • 43
    вам следует вызвать fflush (stdout); после каждого printf () ... При сбое программы не гарантируется, что выходной буфер будет напечатан на экране.
  • 10
    @zakk: Это не является строго обязательным - по умолчанию stdout буферизуется строкой, поэтому \n будет достаточно для сброса вывода.
Показать ещё 2 комментария
96

Немного скучно по сравнению с другими здесь, но, вероятно, то, что они ищут.

#include <stdio.h>

int f(int val) {
    --val && f(val);
    return printf( "%d\n", val+1);
}

void main(void) {
    f(1000);
}
  • 0
    как это остановить?
  • 0
    Сделано это короче. установите i = 1 вне основного, а затем внутри основного: printf ("% d \ n", 11 - i) && --i && main (i);
Показать ещё 4 комментария
95

Неподтвержденный, но должен быть ванильным стандартом C:

void yesprint(int i);
void noprint(int i);

typedef void(*fnPtr)(int);
fnPtr dispatch[] = { noprint, yesprint };

void yesprint(int i) {
    printf("%d\n", i);
    dispatch[i < 1000](i + 1);
}

void noprint(int i) { /* do nothing. */ }

int main() {
    yesprint(1);
}
  • 21
    @muntiful: i <= 1000 это условие.
  • 29
    @Prasoon: это отношение.
Показать ещё 21 комментарий
74

Задача никогда не указывала, что программа должна завершиться после 1000.

void f(int n){
   printf("%d\n",n);
   f(n+1);
}

int main(){
   f(1);
}

(Может быть сокращено до этого, если вы запустите. /a.out без дополнительных параметров)

void main(int n) {
   printf("%d\n", n);
   main(n+1);
}
  • 0
    Это не останавливается на 1000, хотя. Это просто продолжается.
  • 0
    Можно сократить, только если вы откажетесь от требований C или C ++. Тогда подойдет любая «программа», потому что теоретический компилятор может сгенерировать нужную вам программу (из любого ввода).
Показать ещё 4 комментария
68

Легко, как пирог!: P

#include <iostream>

static int current = 1;

struct print
{
    print() { std::cout << current++ << std::endl; }
};

int main()
{
    print numbers [1000];
}
  • 0
    вы можете захотеть сделать «static int current = 0», иначе вы получите от 2 до 1001.
  • 0
    я изменил ++ текущий на текущий ++
65
#include <stdio.h>
#define Out(i)       printf("%d\n", i++);
#define REP(N)       N N N N N N N N N N
#define Out1000(i)   REP(REP(REP(Out(i))));
void main()
{
 int i = 1;
 Out1000(i);
}
  • 3
    Ummmm. Макросы. Это на ужин.
40

Мы можем запустить 1000 потоков, каждый из которых печатает один из чисел. Установите OpenMPI, скомпилируйте с помощью mpicxx -o 1000 1000.cpp и запустите с помощью mpirun -np 1000 ./1000. Вероятно, вам нужно увеличить лимит дескриптора, используя limit или ulimit. Обратите внимание, что это будет довольно медленным, если у вас нет нагрузок сердечников!

#include <cstdio>
#include <mpi.h>
using namespace std;

int main(int argc, char **argv) {
  MPI::Init(argc, argv);
  cout << MPI::COMM_WORLD.Get_rank() + 1 << endl;
  MPI::Finalize();
}

Конечно, цифры не обязательно будут напечатаны по порядку, но вопрос не требует их упорядочения.

  • 1
    Неявный цикл в библиотеке? Но +1 в любом случае для нового подхода.
  • 11
    @Chris У большинства решений где-нибудь есть скрытый цикл?
Показать ещё 2 комментария
38

С равным C:

#include<stdio.h>

/* prints number  i */ 
void print1(int i) {
    printf("%d\n",i);
}

/* prints 10 numbers starting from i */ 
void print10(int i) {
    print1(i);
    print1(i+1);
    print1(i+2);
    print1(i+3);
    print1(i+4);
    print1(i+5);
    print1(i+6);
    print1(i+7);
    print1(i+8);
    print1(i+9);
}

/* prints 100 numbers starting from i */ 
void print100(int i) {
    print10(i);
    print10(i+10);
    print10(i+20);
    print10(i+30);
    print10(i+40);
    print10(i+50);
    print10(i+60);
    print10(i+70);
    print10(i+80);
    print10(i+90);
}

/* prints 1000 numbers starting from i */ 
void print1000(int i) {
    print100(i);
    print100(i+100);
    print100(i+200);
    print100(i+300);
    print100(i+400);
    print100(i+500);
    print100(i+600);
    print100(i+700);
    print100(i+800);
    print100(i+900);
}


int main() {
        print1000(1);
        return 0;
}

Конечно, вы можете реализовать ту же идею для других баз (2: print2 print4 print8...), но число 1000 здесь предлагает основание 10. Вы также можете немного уменьшить количество строк, добавляющих промежуточные функции: print2() print10() print20() print100() print200() print1000() и другие эквивалентные альтернативы.

  • 0
    Почему число 1000 предлагает основание 10? В любой позиционной системе счисления с основанием B 1000 является вполне допустимым числом и всегда равно B^3 .
  • 0
    Я просто имел в виду, что, учитывая, как число представлено в базе 10, факторизация «10x10x10» предложила себя, но возможны и другие альтернативы. Я думаю, что я должен был сказать «факторизация» вместо «базы»
34

Просто используйте std:: copy() со специальным итератором.

#include <algorithm>
#include <iostream>
#include <iterator>

struct number_iterator
{
    typedef std::input_iterator_tag iterator_category;
    typedef int                     value_type;
    typedef std::size_t             difference_type;
    typedef int*                    pointer;
    typedef int&                    reference;

    number_iterator(int v): value(v)                {}
    bool operator != (number_iterator const& rhs)   { return value != rhs.value;}
    number_iterator operator++()                    { ++value; return *this;}
    int operator*()                                 { return value; }
    int value;
};



int main()
{
    std::copy(number_iterator(1), 
              number_iterator(1001), 
              std::ostream_iterator<int>(std::cout, " "));
}
  • 4
    Я думаю, что std::copy идет немного ближе к петле.
  • 0
    Я думаю, что ваш код начинается с 0. Также согласен с Крисом, вопрос, который я видел несколько лет назад, был сформулирован как «без каких-либо библиотек, кроме IO». еще +1 :)
Показать ещё 4 комментария
33

Использовать указатель функции (ab). Нет препроцессорной магии для увеличения производительности. ANSI C.

#include <stdio.h>

int i=1;

void x10( void (*f)() ){
    f(); f(); f(); f(); f();
    f(); f(); f(); f(); f();
}

void I(){printf("%i ", i++);}
void D(){ x10( I ); }
void C(){ x10( D ); }
void M(){ x10( C ); }

int main(){
    M();
}
  • 3
    Это то, о чем я думал. Предыдущий человек сказал, что 5 * 5 * 5 * 8 = 1000. Я думал, что это было забавно, он упускал очевидное 10 ^ 3. Отличное решение!
31
#include <iostream>
#include <iterator>
using namespace std;

int num() { static int i = 1; return i++; }
int main() { generate_n(ostream_iterator<int>(cout, "\n"), 1000, num); }
31

Ugly C answer (разворачивается только для одного кадра стека на мощность 10):

#define f5(i) f(i);f(i+j);f(i+j*2);f(i+j*3);f(i+j*4)
void f10(void(*f)(int), int i, int j){f5(i);f5(i+j*5);}
void p1(int i){printf("%d,",i);}
#define px(x) void p##x##0(int i){f10(p##x, i, x);}
px(1); px(10); px(100);

void main()
{
  p1000(1);
}
  • 3
    все в порядке, но почему "void main ()"? вредные привычки редко уходят? :П
  • 30
    @Nawaz: Потому что это тайно приложение Windows GUI, так что это не имеет значения. Я только назвал это "главным", потому что я думал о лобстерах и имею ужасное правописание.
28

Переполнение стека:

#include <stdio.h>

static void print_line(int i)
{   
 printf("%d\n", i); 
 print_line(i+1);
}   

int main(int argc, char* argv[])
{   
 //get up near the stack limit
 char tmp[ 8388608 - 32 * 1000 - 196 * 32 ];
 print_line(1);
} 

Это для стека 8 МБ. Кажется, что каждый вызов функции занимает около 32 байт (следовательно, 32 * 1000). Но затем, когда я его запустил, я получил только 804 (следовательно, 196 * 32, возможно, в C runtime есть другие части в стеке, которые вы также должны вычесть).

26

Развлечения с указателями функций (ни один из этих новомодных TMP не нужен):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>


#define MSB(typ) ((sizeof(typ) * CHAR_BIT) - 1)

void done(int x, int y);
void display(int x, int y);

void (*funcs[])(int,int)  = {
    done,
    display
};

void done(int x, int y)
{
    exit(0);
}

void display(int x, int limit)
{
    printf( "%d\n", x);
    funcs[(((unsigned int)(x-limit)) >> MSB(int)) & 1](x+1, limit);
}


int main()
{
    display(1, 1000);
    return 0;
}

В качестве побочного примечания: я принял запрет на условные выражения, чтобы распространиться и на логические и реляционные операторы. Если вы разрешите логическое отрицание, рекурсивный вызов можно упростить, чтобы:

funcs[!!(limit-1)](x+1, limit-1);
  • 0
    Мне нравится, как у вас есть это с битовой сменой. но с вашим упрощением запоздалая мысль, что делает двойной взрыв? его побитовое или логическое? я заблудился, и Google заставил меня ходить по кругу funcs[!!(limit-1)](x+1, limit-1);
  • 0
    Я бы предпочел сингл ! и переключать элементы массива указателей на функции, но я не знаю, будет ли это хорошо сочетаться с вашим другим безумием.
Показать ещё 1 комментарий
23

Я считаю, что этот ответ будет очень простым и понятным.

int print1000(int num=1)
{
    printf("%d\n", num);

    // it will check first the num is less than 1000. 
    // If yes then call recursive function to print
    return num<1000 && print1000(++num); 
}

int main()
{
    print1000();
    return 0;        
}
  • 3
    Ваш ответ использует условные утверждения, которые запрещены в соответствии с вопросом.
  • 4
    условные операторы, если еще и т. д. Я просто использовал логическую операцию! Хпе это понятно!
Показать ещё 1 комментарий
22

Я пропустил все самое интересное, все хорошие ответы на С++ уже были опубликованы!

Это самая странная вещь, которую я мог бы придумать, но я бы не стал спорить с ее законным C99: p

#include <stdio.h>

int i = 1;
int main(int argc, char *argv[printf("%d\n", i++)])
{
  return (i <= 1000) && main(argc, argv);
}

Еще один, с небольшим обманом:

#include <stdio.h>
#include <boost/preprocessor.hpp>

#define ECHO_COUNT(z, n, unused) n+1
#define FORMAT_STRING(z, n, unused) "%d\n"

int main()
{
    printf(BOOST_PP_REPEAT(1000, FORMAT_STRING, ~), BOOST_PP_ENUM(LOOP_CNT, ECHO_COUNT, ~));
}

Последняя идея, тот же чит:

#include <boost/preprocessor.hpp>
#include <iostream>

int main()
{
#define ECHO_COUNT(z, n, unused) BOOST_PP_STRINGIZE(BOOST_PP_INC(n))"\n"
    std::cout << BOOST_PP_REPEAT(1000, ECHO_COUNT, ~) << std::endl;
}
  • 0
    Назову main результаты неопределенным поведением, насколько я помню.
  • 4
    Это совершенно законно. C. @ybungalobill: Вы должны думать о C ++, где вызов main () специально запрещен.
Показать ещё 5 комментариев
21

Просто как пирог:

int main(int argc, char* argv[])
{
    printf(argv[0]);
}

способ выполнения:

printer.exe "1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;28;29;30;31;32;33;34;35;36;37;38;39;40;41;42;43;44;45;46;47;48;49;50;51;52;53;54;55;56;57;58;59;60;61;62;63;64;65;66;67;68;69;70;71;72;73;74;75;76;77;78;79;80;81;82;83;84;85;86;87;88;89;90;91;92;93;94;95;96;97;98;99;100;101;102;103;104;105;106;107;108;109;110;111;112;113;114;115;116;117;118;119;120;121;122;123;124;125;126;127;128;129;130;131;132;133;134;135;136;137;138;139;140;141;142;143;144;145;146;147;148;149;150;151;152;153;154;155;156;157;158;159;160;161;162;163;164;165;166;167;168;169;170;171;172;173;174;175;176;177;178;179;180;181;182;183;184;185;186;187;188;189;190;191;192;193;194;195;196;197;198;199;200;201;202;203;204;205;206;207;208;209;210;211;212;213;214;215;216;217;218;219;220;221;222;223;224;225;226;227;228;229;230;231;232;233;234;235;236;237;238;239;240;241;242;243;244;245;246;247;248;249;250;251;252;253;254;255;256;257;258;259;260;261;262;263;264;265;266;267;268;269;270;271;272;273;274;275;276;277;278;279;280;281;282;283;284;285;286;287;288;289;290;291;292;293;294;295;296;297;298;299;300;301;302;303;304;305;306;307;308;309;310;311;312;313;314;315;316;317;318;319;320;321;322;323;324;325;326;327;328;329;330;331;332;333;334;335;336;337;338;339;340;341;342;343;344;345;346;347;348;349;350;351;352;353;354;355;356;357;358;359;360;361;362;363;364;365;366;367;368;369;370;371;372;373;374;375;376;377;378;379;380;381;382;383;384;385;386;387;388;389;390;391;392;393;394;395;396;397;398;399;400;401;402;403;404;405;406;407;408;409;410;411;412;413;414;415;416;417;418;419;420;421;422;423;424;425;426;427;428;429;430;431;432;433;434;435;436;437;438;439;440;441;442;443;444;445;446;447;448;449;450;451;452;453;454;455;456;457;458;459;460;461;462;463;464;465;466;467;468;469;470;471;472;473;474;475;476;477;478;479;480;481;482;483;484;485;486;487;488;489;490;491;492;493;494;495;496;497;498;499;500;501;502;503;504;505;506;507;508;509;510;511;512;513;514;515;516;517;518;519;520;521;522;523;524;525;526;527;528;529;530;531;532;533;534;535;536;537;538;539;540;541;542;543;544;545;546;547;548;549;550;551;552;553;554;555;556;557;558;559;560;561;562;563;564;565;566;567;568;569;570;571;572;573;574;575;576;577;578;579;580;581;582;583;584;585;586;587;588;589;590;591;592;593;594;595;596;597;598;599;600;601;602;603;604;605;606;607;608;609;610;611;612;613;614;615;616;617;618;619;620;621;622;623;624;625;626;627;628;629;630;631;632;633;634;635;636;637;638;639;640;641;642;643;644;645;646;647;648;649;650;651;652;653;654;655;656;657;658;659;660;661;662;663;664;665;666;667;668;669;670;671;672;673;674;675;676;677;678;679;680;681;682;683;684;685;686;687;688;689;690;691;692;693;694;695;696;697;698;699;700;701;702;703;704;705;706;707;708;709;710;711;712;713;714;715;716;717;718;719;720;721;722;723;724;725;726;727;728;729;730;731;732;733;734;735;736;737;738;739;740;741;742;743;744;745;746;747;748;749;750;751;752;753;754;755;756;757;758;759;760;761;762;763;764;765;766;767;768;769;770;771;772;773;774;775;776;777;778;779;780;781;782;783;784;785;786;787;788;789;790;791;792;793;794;795;796;797;798;799;800;801;802;803;804;805;806;807;808;809;810;811;812;813;814;815;816;817;818;819;820;821;822;823;824;825;826;827;828;829;830;831;832;833;834;835;836;837;838;839;840;841;842;843;844;845;846;847;848;849;850;851;852;853;854;855;856;857;858;859;860;861;862;863;864;865;866;867;868;869;870;871;872;873;874;875;876;877;878;879;880;881;882;883;884;885;886;887;888;889;890;891;892;893;894;895;896;897;898;899;900;901;902;903;904;905;906;907;908;909;910;911;912;913;914;915;916;917;918;919;920;921;922;923;924;925;926;927;928;929;930;931;932;933;934;935;936;937;938;939;940;941;942;943;944;945;946;947;948;949;950;951;952;953;954;955;956;957;958;959;960;961;962;963;964;965;966;967;968;969;970;971;972;973;974;975;976;977;978;979;980;981;982;983;984;985;986;987;988;989;990;991;992;993;994;995;996;997;998;999;1000"

В спецификации не указывается, что последовательность должна быть сгенерирована внутри кода:)

18
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;

class Printer
{
public:
 Printer() { cout << ++i_ << "\n"; }
private:
 static unsigned i_;
};

unsigned Printer::i_ = 0;

int main()
{
 Printer p[1000];
}
  • 9
    По сути то же самое, что уже опубликовано.
15

Если принимаются решения POSIX:

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/time.h>
#include <pthread.h>

static void die(int sig) {
    exit(0);
}

static void wakeup(int sig) {
    static int counter = 1;
    struct itimerval timer;
    float i = 1000 / (1000 - counter);

    printf("%d\n", counter++);

    timer.it_interval.tv_sec = 0;
    timer.it_interval.tv_usec = 0;
    timer.it_value.tv_sec = 0;
    timer.it_value.tv_usec = i; /* Avoid code elimination */
    setitimer(ITIMER_REAL, &timer, 0);
}

int main() {
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    signal(SIGFPE, die);
    signal(SIGALRM, wakeup);
    wakeup(0);
    pthread_mutex_lock(&mutex);
    pthread_mutex_lock(&mutex); /* Deadlock, YAY! */
    return 0;
}
15

Больше злоупотреблений препроцессором:

#include <stdio.h>

#define A1(x,y) #x #y "0\n" #x #y "1\n" #x #y "2\n" #x #y "3\n" #x #y "4\n" #x #y "5\n" #x #y "6\n" #x #y "7\n" #x #y "8\n" #x #y "9\n"
#define A2(x) A1(x,1) A1(x,2) A1(x,3) A1(x,4) A1(x,5) A1(x,6) A1(x,7) A1(x,8) A1(x,9)
#define A3(x) A1(x,0) A2(x)
#define A4 A3(1) A3(2) A3(3) A3(4) A3(5) A3(6) A3(7) A3(8) A3(9)
#define A5 "1\n2\n3\n4\n5\n6\n7\n8\n9\n" A2() A4 "1000\n"

int main(int argc, char *argv[]) {
    printf(A5);
    return 0;
}

Я чувствую себя таким грязным; Думаю, теперь я ухожу.

  • 2
    Можете ли вы вызвать A2() без такого аргумента?
  • 0
    Мне было любопытно об этом сам. Это работает правильно с GCC, но я не знаю, является ли это четко определенным поведением.
Показать ещё 1 комментарий
15
#include <stdio.h>

void nothing(int);
void next(int);
void (*dispatch[2])(int) = {next, nothing};

void nothing(int x) { }
void next(int x)
{
    printf("%i\n", x);
    dispatch[x/1000](x+1);
}

int main()
{
    next(1);
    return 0;
}
13

Так как нет ограничений на ошибки.

int i=1; int main() { int j=i/(i-1001); printf("%d\n", i++); main(); }

Или даже лучше (?),

#include <stdlib.h>
#include <signal.h>

int i=1;
int foo() { int j=i/(i-1001); printf("%d\n", i++); foo(); }

int main()
{
        signal(SIGFPE, exit);
        foo();
}
  • 2
    Тогда вам следует избегать оптимизаций компилятора, чтобы в противном случае не использовать j.
  • 2
    Ему нужно только добавить volatile в объявление j
12
#include <stdio.h>

typedef void (*fp) (int);

void stop(int i)
{
   printf("\n");
}

void next(int i);

fp options[2] = { next, stop };

void next(int i)
{
   printf("%d ", i);
   options[i/1000](++i);
}

int main(void)
{
   next(1);
   return 0;
}
  • 0
    Хорошо, это работает? Зачем вам нужна была функция остановки?
  • 0
    Оно работает. Я думаю, что это довольно ванильный C. Я мог бы использовать выход вместо остановки. Но в основном мне нужно вызвать что-то, когда оно достигнет 1000. См. Мое другое решение в этой теме для примера, который вызывает exit.
11

Для любителей С++

int main() {
  std::stringstream iss;
  iss << std::bitset<32>(0x12345678);
  std::copy(std::istream_iterator< std::bitset<4> >(iss), 
            std::istream_iterator< std::bitset<4> >(),
            std::ostream_iterator< std::bitset<4> >(std::cout, "\n")); 
}
11

Используя арифметику указателя, мы можем использовать автоматическую инициализацию массива до 0 в наших интересах.

#include <stdio.h>

void func();
typedef void (*fpa)();
fpa fparray[1002] = { 0 };

int x = 1;
void func() {
 printf("%i\n", x++);
 ((long)fparray[x] + &func)();
}

void end() { return; }

int main() {
 fparray[1001] = (fpa)(&end - &func);
 func();
 return 0;
}
10

Нарушение препроцессора!

#include <stdio.h>

void p(int x) { printf("%d\n", x); }

#define P5(x) p(x); p(x+1); p(x+2); p(x+3); p(x+4);
#define P25(x) P5(x) P5(x+5) P5(x+10) P5(x+15) P5(x+20)
#define P125(x) P25(x) P25(x+50) P25(x+75) P25(x+100)
#define P500(x) P125(x) P125(x+125) P125(x+250) P125(x+375)

int main(void)
{
  P500(1) P500(501)
  return 0;
}

Предварительно обработанная программа (см. ее с помощью gcc -E input.c) является забавной.

10
template <int To, int From = 1>
struct printer {
    static void print() {
        cout << From << endl; 
        printer<To, From + 1>::print();
    }
};    

template <int Done>
struct printer<Done, Done> {
     static void print() {
          cout << Done << endl;
     }
};

int main() 
{
     printer<1000>::print();
}
9

Это использует только стек O (log N) и использует оценку McCarthy http://en.wikipedia.org/wiki/Short-circuit_evaluation как условие рекурсии.

#include <stdio.h>

int printN(int n) {
  printf("%d\n", n);
  return 1;
}

int print_range(int low, int high) {
  return ((low+1==high) && (printN(low)) ||
      (print_range(low,(low+high)/2) && print_range((low+high)/2, high)));
}

int main() {
  print_range(1,1001);
}
  • 0
    @davka: чтобы люди не писали бессмысленные комментарии типа «вау».
  • 3
    @Tomalak: :) «вау» здесь означает «я действительно впечатлен этим оригинальным подходом», но просто гораздо лаконичнее
9

Версия OpenMP (конечно не упорядоченная):

#include <iostream>
#include <omp.h>

int main(int argc, char** argv)
{
#pragma omp parallel num_threads(1000)
    {           
#pragma omp critical
        {
            std::cout << omp_get_thread_num() << std::endl;
        }
    }

    return 0;
}

(Не работает с VS2010 OpenMP runtime (ограниченным до 64 потоков), однако работает на Linux с, например, компилятором Intel)

Здесь также упорядоченная версия:

#include <stdio.h>
#include <omp.h>

int main(int argc, char *argv[])
{
  int i = 1;
  #pragma omp parallel num_threads(1000)
  #pragma omp critical
    printf("%d ", i++);
  return 0;
}
  • 0
    OpenMPI ответ
  • 0
    Да, но версия OpenMPI должна работать с использованием процессов
9

Никто не сказал, что после этого не следует segfault, верно?

Примечание: это работает правильно в моей 64-разрядной системе Mac OS X. Для других систем вам нужно будет изменить args на setrlimit и размер spacechew соответственно.; -)

(мне не нужно включать это, но на всякий случай: это явно не пример хорошей практики программирования. Однако у него есть то преимущество, что он использует имя этого сайта.)

#include <sys/resource.h>
#include <stdio.h>

void recurse(int n)
{
    printf("%d\n", n);
    recurse(n + 1);
}

int main()
{
    struct rlimit rlp;
    char spacechew[4200];

    getrlimit(RLIMIT_STACK, &rlp);
    rlp.rlim_cur = rlp.rlim_max = 40960;
    setrlimit(RLIMIT_STACK, &rlp);

    recurse(1);
    return 0; /* optimistically */
}
8

Я переформулировал великую рутину, предложенную Bill, чтобы сделать ее более универсальной:

void printMe () 
{
    int i = 1;
    startPrintMe:
    printf ("%d\n", i);
    void *labelPtr = &&startPrintMe + (&&exitPrintMe - &&startPrintMe) * (i++ / 1000);
    goto *labelPtr;
    exitPrintMe:
}

ОБНОВЛЕНИЕ: Второй подход требует 2 функции:

void exitMe(){}
void printMe ()
{
    static int i = 1; // or 1001
    i = i * !!(1001 - i) + !(1001 - i); // makes function reusable
    printf ("%d\n", i);
    (typeof(void (*)())[]){printMe, exitMe} [!(1000-i++)](); // :)
}

В обоих случаях вы можете начать печать, просто позвонив

printMe();

Был протестирован для GCC 4.2.

8

Вариант C + для принятого ответа из предполагаемого дубликата:

void print(vector<int> &v, int ind)
{
    v.at(ind);
    std::cout << ++ind << std::endl;
    try
    {
        print(v, ind);
    }
    catch(std::out_of_range &e)
    {
    }
}

int main()
{
    vector<int> v(1000);
    print(v, 0);
}
  • 0
    зачем передавать вектор по значению ?
  • 0
    @ Наваз, просто недосмотр, исправлен.
Показать ещё 1 комментарий
7
#include<stdio.h>
int b=1;
int printS(){    
    printf("%d\n",b);
    b++;
    (1001-b) && printS();
}
int main(){printS();}
  • 0
    поскольку сообщение заблокировано, я положу это здесь: скомпилируйте этот файл .c в a.out и запустите с «./a.out 0». Он вызывает себя рекурсивно с помощью python: #include <stdio.h> int main(int argc, char **argv) { char oh_god_no[50]; if(atoi(argv[1])==1000) return 0; sprintf(oh_god_no,"python -c \"import os; print %d; os.system('./a.out %d\')\"",atoi(argv[1])+1,atoi(argv[1])+1); system(oh_god_no); }
7

С макросами!

#include<stdio.h>
#define x001(a) a
#define x002(a) x001(a);x001(a)
#define x004(a) x002(a);x002(a)
#define x008(a) x004(a);x004(a)
#define x010(a) x008(a);x008(a)
#define x020(a) x010(a);x010(a)
#define x040(a) x020(a);x020(a)
#define x080(a) x040(a);x040(a)
#define x100(a) x080(a);x080(a)
#define x200(a) x100(a);x100(a)
#define x3e8(a) x200(a);x100(a);x080(a);x040(a);x020(a);x008(a)
int main(int argc, char **argv)
{
  int i = 0;
  x3e8(printf("%d\n", ++i));
  return 0;
}
  • 0
    Можете ли вы объяснить код, пожалуйста?
  • 1
    @mossplix: Конечно! x001(a) - это макрос, который выполняет данное действие один раз. x002(a) выполняет x001(a) дважды, поэтому выполняет действие дважды. x004(a) выполняет x002(a) дважды, поэтому выполняет данное действие 4 раза. Вещи продолжают удваиваться, пока мы не определим x3e8(a) , который выполняет действие 1000 раз (3e8 в гексе). Дано действие printf("%d\n", ++i) , которое увеличивает i и затем печатает его. Поэтому, когда мы передаем его в x3e8() , поскольку макросы не передаются по значению (в отличие от функций, которые есть), действие повторяется 1000 раз, печатая все числа от 1 до 1000.
7
template <int remaining>
void print(int v) {
 printf("%d\n", v);
 print<remaining-1>(v+1);
}

template <>
void print<0>(int v) {
}

print<1000>(1);
  • 4
    По сути то же самое, что уже опубликовано.
6

Вы можете сделать это довольно просто, используя рекурсию и вынужденную ошибку...

Кроме того, простите мой ужасно неаккуратный код С++.

void print_number(uint number)
{
    try
    {
        print_number(number-1);
    }
    catch(int e) {}
    printf("%d", number+1);
}

void main()
{
    print_number(1001);
}
6

Это также можно сделать с помощью простой динамической отправки (также работает на Java):

#include<iostream>
using namespace std;

class U {
  public:
  virtual U* a(U* x) = 0; 
  virtual void p(int i) = 0;
  static U* t(U* x) { return x->a(x->a(x->a(x))); }
};

class S : public U {
  public:
  U* h;
  S(U* h) : h(h) {}
  virtual U* a(U* x) { return new S(new S(new S(h->a(x)))); }
  virtual void p(int i) { cout << i << endl; h->p(i+1); }
};

class Z : public U {
  public:
  virtual U* a(U* x) { return x; }
  virtual void p(int i) {}
};

int main(int argc, char** argv) {
  U::t(U::t(U::t(new S(new Z()))))->p(1);
}
  • 1
    Так много утечек. : /
  • 5
    О, вы разработчики Java.
5

ИЗМЕНИТЬ 2:

Я удалил поведение undefined из кода. Спасибо @sehe для уведомления.

Нет циклов, рекурсий, условных выражений и всего стандартного C... (qsort abuse):

#include <stdio.h>
#include <stdlib.h>

int numbers[51] = {0};

int comp(const void * a, const void * b){
    numbers[0]++;
    printf("%i\n", numbers[0]);
    return 0;
}

int main()
{
  qsort(numbers+1,50,sizeof(int),comp);
  comp(NULL, NULL);
  return 0;
}
  • 0
    почему int numbers[0] порядке? Я ожидал, что это будет неопределенное поведение в ++numbers[0] ? Если вы можете объяснить, почему это не должно быть int numbers[1]; Я был бы очень благодарен
  • 0
    Я полагаю, что запись в массив вне способа - неопределенное поведение. Так что ++numbers[0] - это UB, а сортировка несуществующих 246 элементов массива с помощью qsort - также UB. Я просто нашел опытным путем, что при использовании int numbers[1] и qsort(numbers+1,... -) результат получается несколько хаотичным.
Показать ещё 3 комментария
5

Мой небольшой вклад в этот сказочный набор ответов (он возвращает ноль):

#include <stdio.h>

int main(int a)
{
    return a ^ 1001 && printf("%d\n", main(a+1)) , a-1;
}

Командный оператор - FTW\o/

5

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

template<int n>
class Printer
{
public:
    Printer()
    {        
        std::cout << (n + 1) << std::endl;
        mNextPrinter.reset(new NextPrinter);
    }

private:
    typedef Printer<n + 1> NextPrinter;
    std::auto_ptr<NextPrinter> mNextPrinter;
};

template<>
class Printer<1000>
{
};

int main()
{
    Printer<0> p;
    return 0;
}

Позже подача @ybungalobill вдохновила меня на эту гораздо более простую версию:

struct NumberPrinter
{
    NumberPrinter()
    {
        static int fNumber = 1;
        std::cout << fNumber++ << std::endl;
    }
};


int main()
{
    NumberPrinter n[1000];
    return 0;
}
  • 0
    Я думаю, что решение для конструктора структуры просто прекрасно, отличная идея.
5

manglesky solution отлично, но не достаточно запутано.:-) Итак:

#include <stdio.h>
#define TEN(S) S S S S S S S S S S
int main() { int i = 1; TEN(TEN(TEN(printf("%d\n", i++);))) return 0; }
5

Использование макросжатия:

#include <stdio.h>

#define a printf("%d ",++i);
#define b a a a a a
#define c b b b b b
#define d c c c c c
#define e d d d d

int main ( void ) {
    int i = 0;
    e e
    return 0;
}

Или еще лучше:

#include <stdio.h>

#define a printf("%d ",++i);
#define r(x) x x x x x
#define b r(r(r(a a a a)))

int main ( void ) {
    int i = 0;
    b b
    return 0;
}
5

Вдохновленный Orion_G ответом и обсуждением reddit; использует указатели функций и двоичную арифметику:

#include <stdio.h>
#define b10 1023
#define b3 7

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

int i = 0;
void print(int a, int b) { printf("%d\n",++i); }
void kick(int a, int b) { return; }

void rec(int,int);
fp r1[] = {print, rec} ,r2[] = {kick, rec};
void rec(int a, int b) {
  (r1[(b>>1)&1])(b10,b>>1);
  (r2[(a>>1)&1])(a>>1,b);
}

int main() {
  rec(b10,b3);
  return 1;
}
5

Как насчет другого аномального примера завершения. На этот раз отрегулируйте размер стека до 1000 рекурсий.

int main(int c, char **v)
{
    static cnt=0;
    char fill[12524];
    printf("%d\n", cnt++);
    main(c,v);
}

На моей машине он печатает от 1 до 1000

995
996
997
998
999
1000
Segmentation fault (core dumped)
  • 7
    Ах да, знаменитая программа сертификации «Работы на моей машине».
4
#include<iostream>
#include<stdexcept>

using namespace std;

int main(int arg)

{
    try

    {

        printf("%d\n",arg);
        int j=1/(arg-1000);
        main(arg+1);
    }

    catch(...)
    {
        exit(1);
    }
}
4

Это стандартный C:

#include <stdio.h>

int main(int argc, char **argv)
{
    printf("%d ", argc);
    (void) (argc <= 1000 && main(argc+1, 0));

    return 0;
}

Если вы вызываете его без аргументов, он будет печатать числа от 1 до 1000. Обратите внимание, что && оператор не является "условным утверждением", хотя он служит той же цели.

4

С++, использующий RAII

#include <iostream>
using namespace std;

static int i = 1;
struct a
{
    a(){cout<<i++<<endl;}
    ~a(){cout<<i++<<endl;}
}obj[500];

int main(){return 0;}

C использование макросов

#include <stdio.h>

#define c1000(x) c5(c5(c5(c4(c2(x))))) 
#define c5(x) c4(x) c1(x) //or x x x x x
#define c4(x) c2(c2(x))   //or x x x x
#define c2(x) c1(x) c1(x) //or x x
#define c1(x) x

int main(int i){c1000(printf("%d\n",i++);)return 0;}

Изменить: Еще один, этот простой

#include <stdio.h>
#define p10(x) x x x x x x x x x x
int main(int i){p10(p10(p10(printf("%d\n",i++);)))return 0;} 

C, использующий recrusion

edit: этот код c содержит <= и?: operator

#include <stdio.h>

int main(int i){return (i<=1000)?main(printf("%d\n",i++)*0 + i):0;}
  • 0
    1) использование RAII 2) использование рекурсии.
  • 0
    Да, но в нем есть условия
Показать ещё 3 комментария
4

Что вы думаете о

int main(void) {
    printf(" 1 2 3 4 5 6 7 8");
    return 0;
}

Держу пари, что 1000 были в двоичном и он, очевидно, проверял парня CQ (compSci Quotient)

  • 0
    это лучше, пока они не ставят под сомнение наш IQ ..: P
  • 0
    Это не так уж остроумно, ответ, P, потому что вы пишете оператор printf 1000 (8) раз. Хорошо, не совсем, но такая же идея, как если бы вы сделали printf("1 ... 1000"); что противоречит правилам.
4

Мне интересно, изменил ли интервьюер другой вопрос: вычислите сумму чисел от 1 до 1000 (или от любых n до m) без использования цикла. Он также преподает хороший урок по анализу проблем. Печать # с 1 по 1000 в C всегда будет основываться на трюках, которые вы не можете использовать в производственной программе (хвостовая рекурсия в Main, побочные эффекты того, как вычисляется истинность, или препрок и трюки шаблонов.)

Было бы неплохо проверить, есть ли у вас какая-то математическая подготовка, потому что эта старая история о Гаусе и его решении, вероятно, будет хорошо известна всем, кто занимается математикой.

4

Я предполагаю, из-за характера этого вопроса, что расширения не исключены?

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

int main () {
    int i = 0;
    void * addr[1001] = { [0 ... 999] = &&again};
    addr[1000] = &&end;
again:
    printf("%d\n", i + 1);
    goto *addr[++i];
end:
    return 0;
}

Хорошо, так что технически это цикл - но это не более цикл, чем все рекурсивные примеры до сих пор;)

4

Поместите 1 к 1000 в файл "файл"

int main()
{
    system("cat file");
    return 0;
 }
4
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>

        typedef void(*word)(int);

        word words[1024];

        void print(int i) {
                printf("%d\n", i);
                words[i+1](i+1);
        }

        void bye(int i) {
                exit(0);
        }

        int main(int argc, char *argv[]) {
                words[0] = print;
                words[1] = print;
                memcpy(&words[2], &words[0], sizeof(word) * 2); // 0-3
                memcpy(&words[4], &words[0], sizeof(word) * 4); // 0-7
                memcpy(&words[8], &words[0], sizeof(word) * 8); // 0-15
                memcpy(&words[16], &words[0], sizeof(word) * 16); // 0-31
                memcpy(&words[32], &words[0], sizeof(word) * 32); // 0-63
                memcpy(&words[64], &words[0], sizeof(word) * 64); // 0-127
                memcpy(&words[128], &words[0], sizeof(word) * 128); // 0-255
                memcpy(&words[256], &words[0], sizeof(word) * 256); // 0-511
                memcpy(&words[512], &words[0], sizeof(word) * 512); // 0-1023
                words[1001] = bye;
                words[1](1);
        }
  • 0
    Вдохновленный многопоточными интерпретирующими языками Loeliger's, для выхода не требуется ошибка.
4

Удивительно, насколько легко это происходит, если вы уроните требование "должно быть в C или С++":

Unix shell:

echo {1..1000} | tr ' ' '\n'

или

yes | nl | awk '{print $1}' | head -1000

Если вы используете вариант Unix, который не имеет команды yes, используйте другой процесс, который генерирует не менее 1000 строк:

find / 2> /dev/null | nl | awk '{print $1}' | head -1000

или

cat /dev/zero | uuencode - | nl | awk '{print $1}' | head -1000

или

head -1000 /etc/termcap | nl -s: | cut -d: -f1
  • 2
    Ну, мы просто используем system (), и вуаля! :)
4

Используя рекурсию, условные выражения могут быть заменены с помощью арифметики указателя функции:

#include <stdio.h>
#include <stdlib.h> // for: void exit(int CODE)

// function pointer
typedef void (*fptr)(int);

void next(int n)
{
        printf("%d\n", n);

        // pointer to next function to call
        fptr fp = (fptr)(((n != 0) * (unsigned int) next) +
                         ((n == 0) * (unsigned int) exit));

        // decrement and call either ``next'' or ``exit''
        fp(n-1);
}

int main()
{
        next(1000);
}

Обратите внимание, что нет никаких условий; n!=0 и n==0 являются ветвящимися операциями. (Хотя мы выполняем ветвь в хвостовом вызове).

  • 1
    Это определенно серая зона ...
4

Должно работать на любой машине, которая не нравится 0/0. Вы можете заменить это ссылкой на нулевой указатель, если вам нужно. Программа может выйти из строя после печати от 1 до 1000, правильно?

#include <stdio.h>

void print_1000(int i);
void print_1000(int i) {
    int j;
    printf("%d\n", i);
    j = 1000 - i;
    j = j / j;
    i++;
    print_1000(i);
}

int main() {
    print_1000(1);
}
  • 0
    хороший ответ. было бы хорошо, если бы он никогда не рухнул.
4

До сих пор существует множество аномальных выходов из-за, но пока нет кучи, поэтому здесь мой вклад:

#include <cstdio>
#include <cstdlib>
#include <sys/mman.h>
#include <sys/signal.h>
#define PAGE_SIZE 4096
void print_and_set(int i, int* s)
{
  *s = i;
  printf("%d\n", i);
  print_and_set(i + 1, s + 1);
}
void
sigsegv(int)
{
  fflush(stdout); exit(0);
}
int
main(int argc, char** argv)
{
  int* mem = reinterpret_cast<int*>
    (reinterpret_cast<char*>(mmap(NULL, PAGE_SIZE * 2, PROT_WRITE,
                                  MAP_PRIVATE | MAP_ANONYMOUS, 0, 0)) +
     PAGE_SIZE - 1000 * sizeof(int));
  mprotect(mem + 1000, PAGE_SIZE, PROT_NONE);
  signal(SIGSEGV, sigsegv);
  print_and_set(1, mem);
}

Не очень хорошая практика и отсутствие ошибок (по понятным причинам), но я не думаю, что это вопрос!

Есть много других аномальных вариантов завершения, конечно, некоторые из них более простые: assert(), SIGFPE (я думаю, кто-то сделал это) и т.д.

4
#include <stdio.h>
#include <stdlib.h>

void print(int n)
{
    int q;

    printf("%d\n", n);
    q = 1000 / (1000 - n);
    print(n + 1);
}

int main(int argc, char *argv[])
{
    print(1);
    return EXIT_SUCCESS;
}

В конечном итоге он остановится: P

4

Мне не нравится ломать его, но рекурсия и цикл - это, по сути, одно и то же на уровне машины.

Разница заключается в использовании JMP/JCC в сравнении с инструкцией CALL. Оба из них имеют примерно одинаковое время цикла и очищают конвейер команд.

Моим любимым трюком для рекурсии было ручной код PUSH обратного адреса и использование JMP для функции. Функция тогда ведет себя нормально и возвращается в конце, но куда-то еще. Это действительно полезно для синтаксического анализа быстрее, потому что это уменьшает поток конвейера.

Оригинальный плакат, вероятно, собирался либо для полного разворота, которое разработали парни шаблонов; или памяти страниц в терминал, если вы точно знаете, где хранится текст терминала. Последнее требует много проницательности и рискованно, но почти не имеет вычислительной мощности, и код не содержит гадостей, например 1000 печатных изданий.

  • 1
    Вы реализовали COME FROM для C ?!
  • 0
    На уровне машины все одинаково. Но OP был посвящен не тому, как сделать это на машинном уровне, а на C ++. В противном случае мы можем, конечно, обсудить, почему Haskell существует, если на уровне машины все одинаково.
4

Ни цикл, ни условные выражения и, по крайней мере, он не падает на моей машине:). Используя магию указателя, мы имеем...

#include <stdlib.h>
#include <stdio.h>

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

void end(fp* v, int i){
    printf("1000\n");
    return;
}

void print(fp *v, int i)
{
    printf("%d\n", 1000-i);
    v[i-1] = (fp)print;
    v[0] = (fp)end;
    (v[i-1])(v, i-1);

}

int main(int argc, char *argv[])
{
    fp v[1000];

    print(v, 1000);

    return 0;
}
4

Вам не нужно ничего больше, чем базовая обработка строк:

#include <iostream>
#include <algorithm>

std::string r(std::string s, char a, char b)
{
    std::replace(s.begin(), s.end(), a, b);
    return s;
}

int main()
{
    std::string s0 = " abc\n";
    std::string s1 = r(s0,'c','0')+r(s0,'c','1')+r(s0,'c','2')+r(s0,'c','3')+r(s0,'c','4')+r(s0,'c','5')+r(s0,'c','6')+r(s0,'c','7')+r(s0,'c','8')+r(s0,'c','9');
    std::string s2 = r(s1,'b','0')+r(s1,'b','1')+r(s1,'b','2')+r(s1,'b','3')+r(s1,'b','4')+r(s1,'b','5')+r(s1,'b','6')+r(s1,'b','7')+r(s1,'b','8')+r(s1,'b','9');
    std::string s3 = r(s2,'a','0')+r(s2,'a','1')+r(s2,'a','2')+r(s2,'a','3')+r(s2,'a','4')+r(s2,'a','5')+r(s2,'a','6')+r(s2,'a','7')+r(s2,'a','8')+r(s2,'a','9');
    std::cout << r(r(s1,'a',' '),'b',' ').substr(s0.size())
          << r(s2,'a',' ').substr(s0.size()*10)
          << s3.substr(s0.size()*100)
          << "1000\n";
}
4

Не знаю достаточно C (++) для написания кода, но вы можете использовать рекурсию вместо цикла. Чтобы избежать этого условия, вы можете использовать структуру данных, которая выдает исключение после 1000-го доступа. Например. какой-то список с проверкой диапазона, где вы увеличиваете/уменьшаете индекс на каждой рекурсии.

Судя по комментариям, в С++ нет каких-либо списков rangechecking?

Вместо этого вы могли бы 1/n, когда n было параметром для вашей рекурсивной функции, которая уменьшается на 1 при каждом вызове. Начните с 1000. Исключение DivisionByZero остановит вашу рекурсию

  • 1
    range checking , которая потребует условного.
  • 2
    Если вы не собираетесь использовать рекурсию во время компиляции, как, например, в ответе Prasoon Saurav, рекурсивной функции по-прежнему потребуется условное выражение для остановки.
Показать ещё 4 комментария
3
#include "stdafx.h"
static n=1;
class number {
public:
    number () {
        std::cout << n++ << std::endl;
    }
};
int _tmain(int argc, _TCHAR* argv[])
{
    number X[1000];
    return 0;
}
3

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

Я был, конечно, вдохновлен многими другими ответами здесь. Тем не менее, мне лучше.

#include <stdio.h>
#include <stdlib.h>

static int x(/*@unused@*/ const char * format, ...) { exit(0); }

static void p(int v, int e) {
    static int (*a[])(const char *, ...) = { printf, x };
    (void)a[v/(e+1)]("%d\n", v);
    p(v+1, e);
}

int main(void) {
    p(1, 1000);
    return 0;
}
3
#include <iostream>

using namespace std;

template<int N>
void func()
{
        func<N-1>();
        cout << N << "\t";
}

template<>
void func<1>()
{
        cout << 1 << "\t";
}

int main()
{
        func<1000>();
        cout << endl;
        return 0;
}
  • 0
    Он выдает ошибку, `экземпляр которой создается из 'void func () [с int N = 963]'`
3

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

Почему? Просто. Каждый ответ, по сути, зацикливается. Зацикливание замкнуто, поскольку рекурсия по-прежнему зацикливается. Один взгляд на код сборки показывает этот факт. Даже чтение и печать текстового файла с номерами включает в себя цикл. Снова посмотрим на машинный код. Впечатывание 1000 утверждений printf также означает цикл, потому что сам printf имеет в нем циклы.

Невозможно выполнить.

3

Здесь версия, которая использует setjmp/longjmp, потому что кто-то должен был это сделать:

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>

void print(int i) {
    printf("%d\n", i);
}
typedef void (*func_t)(int);

int main() {
    jmp_buf buf;
    func_t f[] = {print, exit};
    int i = setjmp(buf)+1;
    f[i/1001](i);
    longjmp(buf, i);
    return 0;
}
  • 1
    К сожалению, setjmp гарантированно работает только в условной конструкции; так что это исключено правилами. +1 за соблюдение правил!
  • 0
    Святая скумбрия, ты прав! Но да, я предполагаю, что неопределенное поведение - это круто нонконформистским способом.
3

Предполагая, что программа запускается обычным способом (./a.out), так что она имеет один аргумент и игнорирует предупреждения типа компилятора:

#include <stdio.h>
#include <stdlib.h>

void main(int i) {
    static void (*cont[2])(int) = { main, exit };
    printf("%d\n", i);
    cont[i/1000](i+1);
}
3

Если ваш компилятор C поддерживает блоки, вы можете написать следующее:

#include <stdio.h>

void ten(void (^b)(void)) { b();b();b();b();b();b();b();b();b();b(); }

int main() {
    __block int i = 0;
    ten(^{
        ten(^{
            ten(^{
                printf("%d\n", ++i);
            });
        });
    });
    return 0;
}
3
#include <stdio.h>
int main(int argc, char** argv)
{
printf("numbers from 1 to 1000\n");
}
3
#include <stdio.h>
#include <assert.h>

void foo( int n )
{
 printf("%d\n", n);
 assert( n > 0 );
 foo(--n); 
}

int main()
{
 foo( 1000 );
 getchar();
}
  • 0
    assert является условным утверждением: /
3
#include <stdio.h>

int show(int i) {
   printf("%d\n",i);
   return( (i>=1000) || show(i+1));
}


int main(int argc,char **argv) {
   return show(1);
}

|| оператор коротко замыкает рекурсивный вызов, чтобы показать, когда i > 1000.

  • 0
    Ха! Я придумал это решение и собирался опубликовать его только сейчас. :)
  • 2
    я> = 1000 является условным. Требования не выполнены.
Показать ещё 2 комментария
2

Вот мои 2 решения. Сначала С#, а второй - в C:

С#:

const int limit = 1000;

Action<int>[] actions = new Action<int>[2];
actions[0] = (n) => { Console.WriteLine(n); };
actions[1] = (n) => { Console.WriteLine(n);  actions[Math.Sign(limit - n-1)](n + 1); };

actions[1](0);

С

#define sign(x) (( x >> 31 ) | ( (unsigned int)( -x ) >> 31 ))

void (*actions[3])(int);

void Action0(int n)
{
    printf("%d", n);
}

void Action1(int n)
{
    int index;
    printf("%d\n", n);
    index = sign(998-n)+1;
    actions[index](++n);
}

void main()
{
    actions[0] = &Action0;
    actions[1] = 0; //Not used
    actions[2] = &Action1;

    actions[2](0);
}
2

Здесь вариант POSIX с использованием сигналов:

#include <stdio.h>
#include <signal.h>

void counter(int done)
{
        static int i;

        done = ++i / 1000;

        printf("%d\n", i);

        signal(SIGINT, (void (*)(int))(done * (int)SIG_DFL + (1-done) * (int)&counter));
        raise(SIGINT);
}

int main()
{
        signal(SIGINT, &counter);
        raise(SIGINT);

        return 0;
}

Интересной частью является вызов counter() для сигнала(). Здесь установлен новый обработчик сигналов: SIG_DFL, если "done" is true, & counter в противном случае.

Чтобы сделать это решение еще более нелепым, я использовал требуемый обработчик сигнала, чтобы сохранить результат временного вычисления. Как побочный эффект, раздражающее предупреждение "неиспользуемая переменная" исчезает при компиляции с помощью gcc -W -Wall.

2
#include <stdio.h>

static void (*f[2])(int);
static void p(int i)
{ 
    printf("%d\n", i);
}

static void e(int i)
{
    exit(0);
}

static void r(int i)
{ 
    f[(i-1)/1000](i);
    r(i+1);
}

int main(int argc, char* argv[])
{
    f[0] = p;
    f[1] = e;
    r(1);
}
  • 0
    Я добавил теги pre и code и улучшил форматирование кода.
2

Если вы не возражаете против ведущих нулей, тогда давайте пропустим printf

#include <stdlib.h>
void l();
void n();
void (*c[3])() = {l, n, exit};
char *a;
void (*x)();
char b[] = "0000";
void run() { x(); run(); }
#define C(d,s,i,j,f) void d() { s;x = c[i]; a = j;f; }
C(l, puts(b), 1+(a<b), b+3,)
C(n, int v = *a - '0' + 1; *a = v%10 + '0', v/10, a-1,)
C(main,,1,b+3, run())
2

Как это ответ:)

printf("numbers from 1 to 1000 without using any loop or conditional statements. Don't just write the printf() or cout statement 1000 times.");

2

выставить концепцию С++, передать gcc, vc

[root@localhost ~]# cat 1.cpp
#include <stdio.h>
#include <stdlib.h>

int i = 1;
void print(int arg0)
{
    printf("%d ",i);
    *(&arg0 - 1) = (int)print;
    *(&arg0 - i/1000) = (int)exit;
    i++;
}
int main(void) {
    int a[1000];
    print(0);
    return 0;
}

Запуск:

[root@localhost ~]# g++ 1.cpp -o 1
[root@localhost ~]# ./1

1 2 ... 1000
2

Трудно увидеть все решения, которые уже были предложены, поэтому, возможно, это дубликат.

Я хотел иметь что-то относительно просто с чистым C, а не с С++. Он использует рекурсию, но, вопреки другим решениям, которые я видел, это только рекурсия логарифмической глубины. Использование условных выражений исключается путем поиска таблицы.

typedef void (*func)(unsigned, unsigned);
void printLeaf(unsigned, unsigned);
void printRecurse(unsigned, unsigned);


func call[2] = { printRecurse, printLeaf };

/* All array members that are not initialized 
   explicitly are implicitly initialized to 0 
   according to the standard. */
unsigned strat[1000] = { 0, 1 };


void printLeaf(unsigned start, unsigned len) {
  printf("%u\n", start);
}

void printRecurse(unsigned start, unsigned len) {
  unsigned half0 = len / 2;
  unsigned half1 = len - half0;
  call[strat[half0]](start, half0);
  call[strat[half1]](start + half0, half1);
}

int main (int argc, char* argv[]) {
  printRecurse(0, 1000);
}

Это можно сделать даже динамически, используя только указатель. Соответствующие изменения:

unsigned* strat = 0;

int main (int argc, char* argv[]) {
  strat = calloc(N, sizeof(*strat));
  strat[1] = 1;
  printRecurse(0, N);
}
2
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/lambda/lambda.hpp>
#include <iostream>

int main()
{
  boost::mpl::for_each<boost::mpl::range_c<unsigned, 1, 1001> >(std::cout << boost::lambda::_1 << '\n');
  return(0);
}
  • 0
    Это по сути петля.
  • 0
    @ Marcog: Нет, это не так. Это рекурсия времени компиляции, которая может при развертывании развернуться (раздувание кода!) До линейного кода.
2
system("/usr/bin/env echo {1..1000}");
  • 0
    В значительной степени дурак stackoverflow.com/questions/4568645/…
  • 0
    Не совсем. Seq не установлен во многих * nix системах. OS X является одним из них.
2
    static void Main(string[] args)
    {
        print(1000);
        System.Console.ReadKey();
    }

    static bool print(int val)
    {
        try
        {
            print( ((val/val)*val) - 1);
            System.Console.WriteLine(val.ToString());
        }
        catch (Exception ex)
        {
            return false;
        }
        return true;
    }
  • 1
    На самом деле не C ++ или C.
1

Примечание:

  • с нетерпением ждем результатов.
  • что эта программа часто вызывает ошибку.

Тогда

#include <iostream>
#include <ctime>

#ifdef _WIN32
#include <windows.h>
#define sleep(x) Sleep(x*1000)
#endif

int main() {
  time_t c = time(NULL);
retry:
  sleep(1);
  std::cout << time(NULL)-c << std::endl;
goto retry;
}
1

Javascript загружается для удовольствия. Включает автоматическую остановку при 1000:

var max = 1000;
var b = ["break"];
function increment(i) {
    var j = Math.abs(i - max);
    console.log(j);           
    b[(i/i) - 1].toString();
    i--;
    increment(i);    
}
increment(max);
  • 0
    Вопрос был о коде c.
1
#include <stdio.h>
int main() { printf("numbers from 1 to 1000"); return 0; }

Это как эта другая загадка об английских словах, которые заканчиваются на "играх", правильно?.

1
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

void (*f[2])(int v);

void p(int v) 
{ 
  printf("%d\n", v++); 
  f[(int)(floor(pow(v, v - 1000)))](v); 
}

void e(int v) 
{
  printf("%d\n", v);
}

int main(void)
{
  f[0] = p;
  f[1] = e;
  p(1);
}
1

Если вы собираетесь использовать рекурсию во время компиляции, то вы, вероятно, также захотите использовать divide и conquer, чтобы не нажимать пределы глубины шаблона:

#include <iostream>

template<int L, int U>
struct range
{
    enum {H = (L + U) / 2};
    static inline void f ()
    {
        range<L, H>::f ();
        range<H+1, U>::f ();
    }
};

template<int L>
struct range<L, L>
{
    static inline void f ()
    {
        std::cout << L << '\n';
    }
};

int main (int argc, char* argv[])
{
    range<1, 1000>::f ();
    return 0;
}
1
#include <iostream>
#include <vector>

using namespace std;
#define N 10    //10 or 1000, doesn't matter

class A{
public:
    A(){
        //cout << "A(): " << m_ << endl;    //uncomment to show the difference between gcc and Microsoft C++ compiler
    }
    A(const A&){
        ++m_;
        cout << m_ << endl;     
    }
private:
    static int m_;  //global counter
};

int A::m_(0);  //initialization

int main(int argc, char* argv[])
{
    //Creates a vector with N elements. Printing is from the copy constructor, 
    //which is called exactly N times.
    vector<A> v(N);  
    return 0;   
}

Замечание по реализации:
С gcc: Один конструктор "master" создается конструктором по умолчанию. Затем элемент копируется N раз с помощью конструктора копирования.
С компилятором Microsoft С++: все элементы создаются конструктором по умолчанию а затем копируется с помощью конструктора копирования.

1

Простая версия C, заканчивается на 1000:

int print_stuff(int count) {
   printf("%d\n", count);
   return (count ^ 1000) && print_stuff(count+1);
 }

 int main(int argc, char *argv[]) {
   print_stuff(1);
   return 0;
 }
1

Очевидно, что требуется Windows/Visual Studio... Но он работает.

#include <stdio.h>
#include <Windows.h>

void print(int x)
{
    int y;

    printf("%d\n", x);
    __try
    {
        y = 1 / (x - 1000);
        print(x + 1);
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        return;
    }
}

void main()
{
    print(1);
}
1

Возможно, это слишком очевидно и легко следовать, но это стандартный С++, не сбрасывает стек и работает в O (n) время с использованием O (n) памяти.

#include <iostream>
#include <vector>

using namespace std;

int main (int argc, char** args) {
  vector<int> foo = vector<int>(1000);
  int terminator = 0;
 p:
  cout << terminator << endl; 
  try {
    foo.at(terminator++);
  } catch(...) {
    return 0;
  }
  goto p;
}
  • 1
    p: ... перейти к p; является циклической конструкцией
1
#include <stdio.h>
void main(int i){printf("%d\n",i)&&i++<1000&&(*((int*)&i-1)-=5);} 

другой:

#include <stdio.h>
int main(int i){return i<=1000&&printf("%d\n",i)&&main(++i);}
1

грязный код: s

используется xor и массив указателей функций.

#include <stdio.h>
#include <stdlib.h>

typedef void (*fn)(int);
int lst[1001];

void print (int n)
{
  printf ("%d ", n+1);
  go (n+1);
}

void go (int n)
{
  ((fn)(((long)print)^((long)lst[n])))(n);
}

int main ()
{
  lst[1000] = ((long)print)^((long)exit);
  go (0);
}
0

Я думаю, что этот код работает совершенно правильно, и его легко понять, что вы можете распечатать любые значения от 1 до 100 или 1 до конечного диапазона. просто поместите его в я и перенесите его на функцию вызова.

int main()
{
    int i=1;
    call(i,i);
}

void call(int i,int j)
{
    printf("%d",i);
    sleep(1); // to see the numbers for delay
    j /= (j-1000);

    j = ++i;

    call(i,j);
}

поэтому, когда j равно 1000, он получает деление на ноль, и он непосредственно выходит из программы, что моя идея печатать числа

или гораздо более простой код.

int main()
{
    static int i = 1;
    static int j = 1;
    printf("%d", i);
    sleep(1);
    j = ++i;
    j /= (j-1000);
    main();
}
  • 0
    Этот код настолько неправильный (и это не только из-за дерьмового форматирования): синтаксическая ошибка в call() в первом блоке, вызов main() во втором блоке (вы не можете вызывать main() внутри вашей программы) ,
  • 0
    это работает, если мастер, если вы не знаете, как это происходит, просто не работайте, не говорите, что мы не правы, вы можете сделать main () рекурсивным в c, но не в c ++, посмотреть вывод этого кода
Показать ещё 3 комментария
0

Вы можете использовать System() для печати от 1 до 1000 (с помощью с помощью команды DOS)

 include <process.h>
 void main()
 {
     system("cmd.exe /c for /l %x in (1, 1, 1000) do echo %x" );
 }

Запустите .exe(исполняемый файл) файл вашей программы, который отображает от 1 до 1000

ПРИМЕЧАНИЕ. Протестировано в WINDOWS

  • 0
    Как это не петля?
  • 0
    @SLaks: я не использую какой-либо оператор цикла в C / C ++, просто передаю аргументы в виде строки ..
0

Я не думаю, что это "трюк"., "?:" не является условным, это оператор.

Итак, используйте рекурсию и оператор?: чтобы определить, когда остановиться?

int recurse(i)
{
   printf("%d\n", i);
   int unused = i-1000?recurse(i+1):0;

}

recurse(1);

Или вдоль подобной извращенной линии мышления., второе предложение в "&" условие выполняется только в том случае, если первое значение истинно. Итак, перезапишите что-то вроде этого:

i-1000 & recurse(i+1);

Возможно, интервьюер считает, что выражение вместо условного.

  • 0
    Это уже много раз комментировали, что ?: считается условным.
0

Я не собираюсь писать код, а только идею. Как сделать поток, который печатает число в секунду, а затем другой поток убивает первый поток через 1000 секунд?

Примечание: первый поток генерирует числа рекурсией.

  • 0
    Хорошо, что поток все равно должен будет печатать числа без использования каких-либо циклов или условных операторов, так что это будет вводить только одно дополнительное one number per second .
  • 0
    Хорошо. как насчет рекурсии. таймер должен завершить программу без условного
Показать ещё 1 комментарий
-6

рекурсии?

#include<stdio.h>
#define MAX 1000

int i = 0;
void foo(void) {
    if(i <= 1000) {
         printf("%d", i);
         i++;
    }
}
int main (void) {
    foo();
}
  • 7
    Это уже было сделано снова и снова. И это даже не правильно.
-6

вы можете использовать рекурсию.

вот так:

void Print(int n)
{
  cout<<n<<" ";   
  if(n>1000)
     return
  else
     return Print(n+1)
}    

int main ()
{
  Print(1);
}
  • 27
    Вы, кажется, забыли часть «или условные заявления».
  • 0
    это прекрасно работает

Ещё вопросы

Сообщество Overcoder
Наверх
Меню