Döngü veya koşulsuz 1 ila 1000 yazdırma


323

Görev : Sayıları 1'den 1000'e kadar herhangi bir döngü veya koşullu ifade kullanmadan yazdırın. Sadece printf()veyacout deyimini 1000 kez .

C veya C ++ kullanarak bunu nasıl yapardınız?


137
Açık cevap 500 aramayı kullanmak printfve her seferinde iki numara yazdırmak değil mi?
James McNellis

433
printf ("1'den 1000'e kadar sayılar");
jondavidjohn

7
:?koşullu değildir deyimi (bu bir deyim) ...
Chris Lutz

127
Röportaj senin parlama şansın. Onlara "Döngüler veya şartlar olmadan mı? Çocuk oyunu. Bilgisayar olmadan yapabilirim!" Sonra kalemi ve not defterini çıkarın. Size şaşkın bir görünüm verebilirler, ancak sadece yerleşik dil yapılarına güvenemezseniz, gerçekten hiçbir şey üstlenemeyeceğinizi açıklayın.
JohnFx

8
Şahsen, zekice ve ilginç çözümlere sahip birkaç cevap olduğunu düşünüyorum. Ayrıca, bu kolayca korkunç bir röportaj sorusu olabilse de, görüşmecinin gerçekten iyi biçimlendirilmiş bir çözüm için çok fazla arama yapmadığı sürece, görüşmecinin, TMP bilgisi veya yapıları alışılmadık şekillerde kullanma. Bunun saf bir 'doğru-yanlış / yanlış' sorusu olarak kullanılması kötü olurdu, ama bir tartışmanın başlangıç ​​noktası olarak kullanılmış olsaydı çok değer görebiliyordum.
Michael Burr

Yanıtlar:


785

Zaman özyineleme derleyin! : 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);
}

8
Birisi bana bunun nasıl çalıştığını açıklayabilir mi? çok etkileyici.
gath

28
@Zack: Gerçekleşelim, döngülerden kasten kaçınmak için yazılmış bir programdan 1.000 satır yazdırıyoruz. Performans sorun değil.
dreamlax

42
Bunu derleyecek kadar meraklı olanlar için: g ++ 'da -ftemplate-deep-1000 ayarlayın. Varsayılan şablon yineleme maksimum 500'dür.
Tom

6
Bu hala koşulludur: kalıp eşleştirme eğer yüceltilirse.
David K.

10
@dreamlax: Yıllar boyunca deneyimlerden öğrendiğim şeylerden sadece bir tanesi: '\n'gerçekten yıkamak istemediğiniz ++isürece kullanın, aslında eski değerine ihtiyacınız olmadığı sürece kullanın i, constiyi bir nedeniniz yoksa referans ile geçin ... Geliştiriciler bunları düşünmeyi bıraktıklarında (veya asla başlamıyorlar), er ya da geç, bunun önemli olduğu bir problemle karşılaşacaklar, sadece önemli olabilecek noktalar olduğunu bile bilmiyorlardı.
sbi

1195

Bu aslında herhangi bir şartı olmayan montaj için derlenir:

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

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


Düzenleme: Adres eklendiğinden işaretçi hatalarından kaçınmak için '&' eklendi.

Standart C'de yukarıdakilerin bu sürümü, işlev işaretçileri üzerinde aritmetiğe bağlı olmadığından:

#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);
}

17
Peki, bu cevaptaki kod ne C ne de C ++ değildir, bu yüzden sadece gereksinimi hurdaya çıkarırsak iyi olur. O zaman herhangi bir cevap kabul edilebilir, çünkü varsayımsal bir derleyici herhangi bir girdiden gerekli programı üretebilir.
eq-

321
@PP, açıklamak oldukça uzun, ama temelde, jbaşlangıçta olduğu 1aslında çünkü argchangi 1programın argümanlar olmadan çağrılırsa. Sonra j/1000ise 0dek jolur 1000öyle bundan sonra 1. (exit - main)tabii ki, adreslerinin arasındaki fark exit()ve main(). Araçlarla Yani (main + (exit - main)*(j/1000))olduğu main()kadar jolur 1000o olur, bundan sonra, exit(). Sonuç, main()program başladığında çağrılır, daha sonra art arda kendini 999 kez jçağırır, sonra çağırır exit(). Vay canına :)
Frédéric Hamidi

7
Bu, CI'nin şimdiye kadar gördüğü en şaşırtıcı istismarlardan biridir. Ancak tüm platformlarda çalışır mı?
Qwertie

13
@ Mark: Bu ana standardın imzası değil, ana özyinelemeyi çağırmaya izin vermiyorsunuz ve işlev işaretçilerinin çıkarılmasının sonucu tanımsız.
Yakov Galka

9
Evet, evet, @ybungalobill'in verdiği nedenlerden dolayı kesinlikle yasal C ++ kodu değil, ama sırf delilik ve derleme ve birkaç platformda çalışması gerçeği için +1 gerekiyor. "Ama bu standart değil!" "Kimin umurunda!" :)
j_random_hacker

544
#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; }

Kimsenin bunu yayınlamamasına şaşırdım - bunun en açık yol olduğunu düşündüm. 1000 = 5*5*5*8.


İnsanlar bunu gönderdi. Diğer sürümler, global kullanmak yerine yazdırılacak sayıyı geçirir, ancak aslında aynı çözümdür.
Chris Lutz

1
@Chris, makrolarda veya şablonlarda ifade edilen aynı mantığı kullanıyorlar, kod boyutunu şişiriyorlar, değil mi? Bin printfs yerine çıktı dizesini de oluşturabilirsiniz.
Darius Bacon

Oh evet, Keith'in cevabının bütün ipi oluşturduğunu görüyorum, havalı. :) Onu özledim.
Darius Bacon

43
Güzel bir çaba, ama 8'i 2 * 2 * 2'ye ayırmadığınız için garip ve bu nedenle eşsiz asal çarpanlara ayırma yöntemini kullanın
David Heffernan

298

Döngüler kullanmaya gerek yok gibi görünüyor

printf("1 10 11 100 101 110 111 1000\n");

1
biri copykullanım hile olduğunu iddia edebilir
John Dibling

13
@Johannes aslında printfbir döngü olduğundan eminim : p
icecrime

1
@litb: Not Bunu "kullanarak demedi copy edilir hile"
John Dibling

2
@John: kopyalama edilir hile. bundan şüphe ediyor musun? : P
Nawaz

1
1'den 10'a kadar bir ölçekte, ikili kullanma şansım nedir?
Ürdün

270

İşte bildiğim üç çözüm. İkincisi yine de tartışılabilir.

// 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
}

[ Düzenleme: (1) ve (4) yalnızca derleme zamanı sabitleri için kullanılabilir, (2) ve (3) çalışma zamanı ifadeleri için de kullanılabilir - son düzenleme. ]


5
Ayrıca, kısa devre için koşullu olmama konusunda tartışırdım ... Bir ifade değil, doğru, ama koşullu bir ifade, derim. Koşullu ifadeyi "birleştiricide koşullu sıçramalar sağlayan bir şey" olarak tanımlamamız şartıyla.
Kos

5
Yapıcıyı okurken bana vuran soru: Standart, dizideki her öğenin sırayla oluşturulmasını zorunlu kılıyor mu? Yapıcının yan etkileri olup olmadığı önemli olacaktır. Eminim her aklı derleyici bunu 0-> 1000 döngü olarak uygular ama yine de uyumlu olup olamayacağınızı merak ediyorum ...
Joseph Garvin

6
@Joseph - Yapıcı kişi, nesnelerin hangi sırayla başlatıldığından etkilenmemelidir, ancak bu iyi bir sorudur.
Chris Lutz

12
Joseph bu 12.6 / 3 (C ++ 03) ile tanımlanır. Başlatma, abonelik sırasında yapılır.
Johannes Schaub - litb

2
@Joseph: Ve onlar da ters sırada imha edildi, bu yüzden kolayca bir yıkıcı kullanabilirsiniz :)
j_random_hacker

263

Printf bildirimini 1000 defa yazmıyorum!

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");

Rica ederim ;)


223
Umarım bu satırı oluşturmak için bir program yazmışsınızdır.
Martin York

32
open ("1000.c", 'w'). write ('printf ("% s");'% ("\ n" .join (x in xrange (1.1000)] için [str (x)]) ))
Tyler Eaves

53
Umarım bu satırı oluşturmak için yazdığınız program döngü içermez!
Jeeyoung Kim

20
Bir Vim makrosu işi çabucak yapardı.
StackedCrooked

2
Perl biraz süslü bir şekilde üretir:$r='printf("'; for (1..1000) { $r.="$_\\n" } $r.='");'; print $r;
sidyll

213
printf("%d\n", 2);
printf("%d\n", 3);

Tüm sayıları yazdırmaz , ancak "1'den 1000'e kadar sayıları yazdırın". Kazanmak için belirsiz soru! :)


77
'printf ("1'den 1000'e kadar rakamlar") "sonrası en sevdiğim - aptalca sorular aptalca cevaplar gerektirir.
6'da SEngstrom

bu harika. Sorunun belirsizliğinden yararlanmak için +1. haha
Nawaz

2
Düzenlenen; hiçbir şekilde, şekil veya form bu kodu yaptı print "Print numbers from 1 to 1000."- kazanmak için belirsiz soru, yanlış açıklamalar emmek :)
sehe

Vay be, son zamanlarda bu sorunun cevaplarında biraz vandalizm oldu. Bir şey bana bu kilidi tarihi bir kilide yükseltmemiz gerektiğini söylüyor.
BoltClock

172

Önemli bir hatayı tetikleyin! İşte countup.c dosyası:

#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);
}

Derleyin, ardından bir kabuk isteminde yürütün:

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

Bu gerçekten herhangi bir döngü veya koşul olmadan 1'den 1000'e kadar olan sayıları yazdırır!


43
fflush (stdout) 'u çağırmalısınız; her printf () işleminden sonra ... Bir program çöktüğünde, çıktı arabelleğinin ekrana yazdırılacağı garanti edilmez.
zakk

10
@zakk: Bu kesinlikle gerekli değildir - varsayılan olarak stdout satır arabelleğe alınır, bu nedenle \nçıktıyı temizlemek için yeterli olacaktır.
psmears

24
stdout, etkileşimli bir aygıt olarak belirlenebilirse satır arabelleğe alınır , aksi takdirde tamamen arabelleğe alınır. Profesör stdout'u otomatik kontrol için bir dosyaya yönlendirirse, başarısız olacaksınız :-)
paxdiablo


166

Sistem komutlarını kullanma:

system("/usr/bin/seq 1000");

15
Yüksek şans /usr/bin/seqdahili bir döngü kullanır. :)

@jokester: Yani, Solaris / BSD'nin bir seqyardımcı programı yok (varsayılan kurulumda)? <sırıtma />
sehe

Bunu söylemekten nefret ediyorum (iyi, hayır, bilmiyorum), ama çözümünüzde bir hata var. Doğru sayı kümesini yazdırmaz. :) İşte düzeltme: system("/bin/echo {1..1000}"); Önce birim testini yazmış olsaydınız ...
Don Branson

1
Parlak bir adam cevabımı değiştirmeye karar verdi, bu yüzden bu benim hatam değil.
moinudin

100

Test edilmedi, ancak vanilya standardı C olmalı:

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);
}

29
@Prasoon: Bu bir ilişki.
Yakov Galka

28
gereksinimi "koşul yok" (if, switch vb.). "koşul yok"
jon_darkstar

32
<bir şart değildir. İlişkisel bir operatör. if/ elsekoşullu bir ifadedir. ?:koşullu bir operatördür. <yalnızca bir boole değeri döndüren bir işleçtir. Muhtemelen atlamalar ya da herhangi bir şey olmadan tek bir makine talimatıdır.
Chris Lutz

12
@Chris Lutz: x86 üzerinde, 3 talimatlar aşağıda verilmiştir: cmpl, setle, ve movzbl. x86-64 bu artı a cltq. PowerPC 2 talimattır: cmpwive crnot.
Adam Rosenfield

4
1 - i / 1000. Karşılaştırma yok!
Tayland

96

Buradaki diğerlerine kıyasla biraz sıkıcı, ama muhtemelen aradıkları.

#include <stdio.h>

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

void main(void) {
    f(1000);
}

Daha kısa yaptım. i = 1'i ana dışında ve sonra ana içinde ayarlayın: printf ("% d \ n", 11 - i) && --i && main (i);
jftuga

3
@Jens Schauder: &&İlk satırında tembel değerlendirmeden yararlanarak f().
Rafał Dowgird

10
Bu sıkıcı değil, basit. Şablon sihir büyük bir karmaşa ile yapabildiğiniz gibi kısa bir işlevle aynı şeyi yapabilirseniz, o zaman işlevi ile
yapmalısınız

21
&& bir şarttır. Matematiksel bir AND her iki tarafı da değerlendirecektir (Java ve Ada "AND" gibi). && sadece 2 operatörünü değerlendirecek eğer ilk doğrudur (işte burada). Veya başka bir örnek: Ada'da koşullu yönü belirtmek için THEN kullanarak kısa devreler operatörüne "VEYA SONRA" denir. Üzgünüm, bu kadar iyi kullanılmış olabilir? : Şebeke.
Martin

Özre gerek yok. && bir karşılaştırma operatörüdür. Üçlü operatör bir şarttır.
Aaron

71

Görev, programın 1000'den sonra sonlanması gerektiğini hiçbir zaman belirtmedi.

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

int main(){
   f(1);
}

( Ek parametreler olmadan ./a.out komutunu çalıştırırsanız buna kısaltılabilir )

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

Yine de 1000'de durmuyor. Sadece devam ediyor.
Remy Lebeau

Yalnızca C veya C ++ gereksinimini kaldırırsanız kısaltılabilir. O zaman herhangi bir "program" bunu yapar, çünkü teorik bir derleyici istediğiniz programı (herhangi bir girdiden) oluşturabilir.
eq-

@eq Tekrar, bu iyi derler ve iyi çalışır ...
Mark McDonald

72
Sonradan düşünüldüğünde: görünen matematikten bile kurtulabiliriz . Biz istihdam durumunda rand(), biz 1'den 1000'e kadar onları bütün numaraları yazdırmak zorundadır Sonunda =: P

5
@pooh: Rand () belirli bir diziden sonra tekrar etme şansına sahip olduğundan ve bu dizinin bu sorun için ayarlanan
çözümde düşmeyebileceğinden, mutlaka

71

Pasta kadar kolay! : P

#include <iostream>

static int current = 1;

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

int main()
{
    print numbers [1000];
}

"statik int akımı = 0" yapmak isteyebilirsiniz, aksi takdirde 2 ile 1001 arasında yazdırılır.
Shinnok

++ akımını mevcut ++ olarak değiştirdim
Zelix

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. Makrolar. Akşam yemeği için ne var.
EvilTeach

42

Herbiri numaralardan birini basan 1000 iş parçacığı başlatabiliriz. OpenMPI'yi yükleyin , kullanarak derleyin mpicxx -o 1000 1000.cppve kullanarak çalıştırın mpirun -np 1000 ./1000. Muhtemelen limitveya kullanarak tanımlayıcı sınırınızı artırmanız gerekecektir ulimit. Çok fazla çekirdek yoksa, bunun oldukça yavaş olacağını unutmayın!

#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();
}

Tabii ki, numaralar sırayla yazdırılmayacaktır, ancak soru sipariş edilmelerini gerektirmez.


1
Kütüphanede kapalı döngü var mı? Ama yeni bir yaklaşım için yine de +1.
Chris Lutz

11
@Chris Çoğu çözümün bir yerde gizli bir döngüsü yok mu?
moinudin

Sanırım "derleyicideki döngüler" yaklaşımını kullanırsanız. ( MPI::Init()İçinde argümanlar üzerinde olası bir döngü dışında ) 1000.cpp programınızın gerçek ikili dosyasında herhangi bir döngü hayal edemediğim için, yürüttüğünüzde kesinlikle çalışan döngüler olmasına rağmen size +1 verdim.
Chris Lutz

40

Düz C ile:

#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;
}

Tabii ki, aynı fikri diğer üsler için de uygulayabilirsiniz (2: print2 print4 print8 ...) ancak burada 1000 sayısı, taban 10'u önerdi. Ara işlevler print2() print10() print20() print100() print200() print1000()ve diğer eşdeğer alternatifler ekleyerek satır sayısını da azaltabilirsiniz .


1000 sayısı neden 10'u öneriyor? Tabanı olan herhangi bir konumsal gösterimde B, 1000 tamamen geçerli bir sayıdır ve her zaman eşittir B^3.
Philip

Demek istediğim, sayının baz 10'da nasıl temsil edildiği göz önüne alındığında, "10x10x10" çarpanlarına ayırma işlemi kendini önerdi, ama başka alternatiflerin de mümkün olduğunu söyledim. Sanırım "temel" yerine "çarpanlara ayırma"
demeliydim

34

Özel bir yineleyici ile std :: copy () kullanın.

#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, " "));
}

Bence kodunuz 0'dan başlıyor. Chris ile de aynı fikirdeyim, yıllar önce gördüğüm soru "IO dışında herhangi bir kütüphane olmadan" olarak ifade edildi. henüz +1 :)
Yakov Galka

3
@Chris Lutz: Kopyanın uygulanması tanımsız. Hatta yukarıdaki gibi şablon kodu kullanabilirsiniz (sadece bilmiyorum; bilmiyorum). Yani bir döngü kullandığını söyleyemezsiniz çünkü bilmiyoruz.
Martin York

7
Aslında, benim nit seçimim std::copyörtük koşullu olarak örtülü döngü olmazdı operator !=(). Ne olursa olsun, bir aralığı işlemek için akıllıca bir yaklaşım ve bu gibi sorulara yanıt olarak aradığım akıllı yaklaşımlar.
Michael Burr

özel uygulama tanımsız
selvaiyyamperumal

@selvaiyyamperumal: Ne hakkında konuştuğunuzdan emin değilim. Ancak davranış hakkında konuşuyorsanız, standart sizinle aynı fikirde değildir. "Uygulama Tanımlı davranış", bunun iyi tanımlandığı, ancak uygulama tarafından açıkça belgelendirilmesi gerektiği anlamına gelir. "Tanımsız Davranış" her şeyin olabileceği anlamına gelir.
Martin York

33

İşlev işaretçisi (ab) kullanımı. Çıkışı artırmak için önişlemci sihri yok. 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
Ben de öyle düşünüyordum. Önceki bir kişi 5 * 5 * 5 * 8 = 1000 olduğunu söyledi. Bariz 10 ^ 3 eksik komik olduğunu düşündüm. Güzel çözüm!
Evan Moran

32
#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); }

30

Çirkin C yanıtı (10 güç başına sadece bir yığın çerçeve için kaydedilmemiş):

#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
her şey yolunda, ama neden "void main ()"? kötü alışkanlıklar nadiren gider? : P
Nawaz

30
@Nawaz: Bu gizlice bir Windows GUI uygulaması olduğu için önemli değil. Ben sadece "ana" olarak adlandırdım çünkü ıstakoz hakkında düşünüyordum ve yazım korkunç.
Martin

29

Yığın taşması:

#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);
} 

Bu 8MB'lık bir yığın içindir. Her işlev çağırma işlemi yaklaşık 32 bayt sürer (bu nedenle 32 * 1000). Ama sonra koştuğumda sadece 804'e ulaştım (bu nedenle 196 * 32; belki de C çalışma zamanının yığınta da çıkarmanız gereken başka parçaları var).


25

İşlev işaretçileriyle eğlenceli (yeni kanatlı TMP'ye gerek yok):

#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;
}

Bir yan not olarak: Mantıksal ve ilişkisel operatörlere de uzanmak için koşullara karşı yasağı aldım. Mantıksal olumsuzlamaya izin verirseniz, özyinelemeli çağrı şu şekilde basitleştirilebilir:

funcs[!!(limit-1)](x+1, limit-1);

biraz vardiya ile elde etme şeklini seviyorum. ama daha sonra düşündüğünüz sadeleşme ile, çift patlama ne yapar? bitsel mi mantıklı mı? im kayıp ve google beni çevrelerinde dolaşıyor varfuncs[!!(limit-1)](x+1, limit-1);
jon_darkstar

Ben bir tek var !ve fonksiyon işaretçi dizi elemanları geçmek istiyorum , ama bunun diğer delilik ile iyi oynayacak bilmiyorum.
Chris Lutz

@Chris: Tamamen katılıyorum - ancak gönderdikten sonra mantıksal / ilişki operatörleri kullanmayı düşünmedim ve tek satırlık bir yamanın daha uygun olacağını düşündüm. Ayrıca, sorunun tüm gizlenmiş hissi ile biraz daha iyi uyuyor.
Michael Burr

24

Bu cevabın çok basit ve anlaşılması kolay olacağını düşünüyorum.

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
Cevabınız, soruya göre yasaklanmış koşullu ifadeler kullanıyor.
stevelove

4
koşullu ifadeler başka vb ise. Ben sadece mantıklı bir işlem kullandım !! Hpe açıktır!
Ocak'ta Pappu

2
Yorumlarınızda bile "Evet ise, yazdırmak için özyinelemeli işlevi çağırın" yazdınız. Açık bir şekilde yazılmış bir koşullu koşul, yine de koşulludur. Num varsayılanı da bir koşulludur.
Gerry

23

Tüm eğlenceyi kaçırdım, tüm iyi C ++ cevapları zaten gönderildi!

Bu, karşılaşabileceğim en tuhaf şey, yasal C99 olsa da bahse girmezdim: p

#include <stdio.h>

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

Bir diğeri, biraz hile ile:

#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, ~));
}

Son fikir, aynı hile:

#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;
}

Arama main, hatırladığım gibi tanımsız davranışlarla sonuçlanır.
Yakov Galka

4
Tamamen yasal C. @ybungalobill: main () çağrısının özellikle izin verilmediği C ++ düşünüyor olmalısınız.
Michael Foukarakis

@Michael: Belki, C'yi çok iyi tanımıyorum
Yakov Galka

Bence Boost kullanmak C ++ anlamına geliyor. Ne olursa olsun, Boost.PP çözümü için kudos.
me22

6
Mantıksal operatörler &&ve ||kısa devre (olduğu gibi ?:) nedeniyle muhtemelen "şartlı" altında kalır .
mühimmat

22

Pasta kadar kolay:

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

yürütme yöntemi:

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"

Şartname dizinin kodun içinde oluşturulması gerektiğini söylemez :)


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];
}

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;
}

15

Daha fazla önişlemci kötüye kullanımı:

#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;
}

Kendimi çok kirli hissediyorum; Sanırım şimdi duş alacağım.


2
A2()Böyle bir argüman olmadan arayabilir misin ?
Chris Lutz

Bunu kendim merak ettim. GCC ile düzgün çalışıyor, ancak iyi tanımlanmış bir davranış olup olmadığını bilmiyorum.
keithmo

C99'da iyi tanımlanmış, C89'un ne dediğini hatırlamıyorum, bellek hizmet veriyorsa en azından bazı MSVC sürümlerinde sorun yaratır.
Ocak'ta zwol

15

POSIX çözümleri kabul edilirse:

#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;
}

13

Böcek üzerinde herhangi bir kısıtlama olmadığı için ..

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

Ya da daha iyisi (?),

#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
Aksi halde kullanılmayan j'yi tutmak için derleyici optimizasyonundan kaçınmalısınız.
bandi

2
Sadece volatilebeyanına eklemesi gerekiyorj
Patrick Schlüter
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.