ループや条件なしで1から1000を印刷する


323

タスク:ループや条件ステートメントを使用せずに、1から1000までの数値を出力します。printf()or coutステートメントを1000回だけ書くのではありません。

CまたはC ++を使用してそれをどのように行いますか?


137
明白な答えは、500回の呼び出しを使用しprintf、毎回2つの番号を出力することです。
James McNellis、2010

433
printf( "1から1000までの数値");
jondavidjohn 2010

7
:?は条件付きのステートメントではありません(式です)...
Chris Lutz

127
輝きのチャンスをインタビュー。「ループや条件文がなくても、子供の遊び。コンピュータがなくてもできる!」と伝えます。次に、ペンとメモ帳を引き出します。彼らはあなたに混乱した見た目を与えるかもしれませんが、組み込みの言語構造に頼ることができないなら、あなたは本当に何も仮定できないことを説明してください。
JohnFx 2010

8
個人的には、巧妙で興味深い解決策があった答えがいくつかあったと思います。これはひどいインタビューの質問になりがちですが、インタビュアーが完全に整形式のソリューションを実際に探しているのではなく、インタビュー対象者が示すアプローチを検討したかどうかを探している限り、それは良い価値があると私は思います。 TMPに関する知識、または通常とは異なる方法で構成を使用する。これを純粋な「正解/間違った」質問として使用した場合は悪いことだと思いますが、議論の出発点として使用した場合、多くの価値が見られました。
Michael Burr

回答:


785

時間再帰をコンパイルしてください!: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
これがどのように機能するか誰かが誰かに説明できますか?かなり印象的です。
ガテ

28
@ザック:現実に戻りましょう。ループを意図的に回避するために書かれたプログラムから1,000行を出力しています。パフォーマンスは問題ではありません。
dreamlax

42
これをコンパイルするのに十分興味がある人のために:g ++では、-ftemplate-depth-1000を設定します。デフォルトのテンプレートの再帰最大値は500です
トム・

6
これはまだ条件文を使用します。パターンマッチングは栄光があります。
David K.

10
@dreamlax:これは、長年の経験から学んだことの1つにすぎ'\n'ません。本当にフラッシュしたく++iない場合を除き、実際に以前の値が必要でない場合を使用し、正当な理由がない限りiconst参照渡しします...開発者がこれらについて考えるのをやめる(または開始することすらしない)と、遅かれ早かれ、これが問題となる問題に遭遇します。問題になる可能性のある場所があることさえ知らなかっただけです。
sbi 2011年

1195

これは実際には、条件を持たないアセンブリにコンパイルされます。

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

17
さて、この回答のコードは明らかにCでもC ++でもないため、要件を破棄した場合にのみ問題ありません。次に、架空のコンパイラが必要なプログラムを任意の入力から生成する可能性があるため、すべての回答が適格となる場合があります。
EQ-2011年

321
@PP、それは説明するのにかなり長いですが、基本的にjは、最初は1それが実際にargcであるからです。これは1、プログラムが引数なしで呼び出された場合です。その後、j/1000ある0までjとなり1000、それはだた後、1(exit - main)もちろん、アドレスの違いはexit()main()。意味することに(main + (exit - main)*(j/1000))あるmain()までjとなり1000、それがなった後、exit()。最終結果はmain()、プログラムの起動時に呼び出され、インクリメント中に999回再帰的にj呼び出され、次にが呼び出されますexit()。Whew :)
フレデリックハミディ2011年

7
これは、CIのこれまでにない最も驚くべき乱用の1つです。しかし、それはすべてのプラットフォームで機能しますか?
Qwertie、2011年

13
@Mark:これはmainの非標準のシグネチャであり、mainを再帰的に呼び出すことはできません。また、関数ポインターを減算した結果は未定義です。
Yakov Galka 2011年

9
ええ、ええ、@ ybungalobillが与える理由から、それは厳密に合法のC ++コードではありませんが、純粋な狂気と、いくつかのプラットフォームでコンパイルおよび動作するという事実のために+1する必要があります。「しかし、それは標準ではありません!」に対する正しい応答があります。「誰が気にする!」:)
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; }

誰もこれを投稿したように見えないことに驚いています-最も明白な方法だと思いました。 1000 = 5*5*5*8.


人々はこれを投稿しました。他のバージョンでは、グローバルを使用する代わりに番号を出力して渡しますが、基本的には同じソリューションです。
Chris Lutz

1
@Chris、彼らはマクロまたはテンプレートで表現された同じロジックを使用して、コードサイズを爆破しますよね?1000個のprintfsではなく、出力文字列自体を生成することもできます。
ダリウスベーコン

ええ、私はキースの答えがクールな文字列全体を生成するのを見ます。:) 私は逃しました。
ダリウスベーコン

43
さて、すばらしい努力ですが、8を2 * 2 * 2に分解せず、独自の素因数分解を使用しなかったというかなり奇妙なこと
David Heffernan

298

ループを使用する必要がないようです

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

1
使用copyは不正行為だと主張する人もいるでしょう
John Dibling 2010

13
@ヨハネスは実際にはprintfループがあると確信しています:p
icecrime

1
@litb:「使用することcopy 不正行為です」とは言わなかったことに注意してください
John Dibling 2010

2
@John:コピー不正行為です。疑いますか :P
Nawaz

1
1から10までのスケールで、私がバイナリを使用している可能性は何ですか?
ジョーダン

270

ここに私が知っている3つの解決策があります。2番目は議論されるかもしれません。

// 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)はランタイム式にも使用できます— 編集を終了します。]


5
また、短絡は条件付きではないと主張します...ステートメントではなく、真ですが、条件式だと思います。条件式を「アセンブラで条件付きジャンプを生成するもの」と定義した場合。
Kos、

5
コンストラクター1を読んだときに当たった質問:標準では、配列内の各項目を順番に作成するように要求されていますか?コンストラクタに副作用があるかどうかは重要です。すべての正気なコンパイラーがそれを0-> 1000ループとして実装すると確信していますが、準拠していて逆方向にループできるかどうか疑問に思います...
Joseph Garvin

6
@ジョセフ-コンストラクターは、個々のオブジェクトが開始される順序によって影響されるべきではありませんが、良い質問です。
Chris Lutz、2011年

12
@Josephこれは12.6 / 3(C ++ 03)で定義されています。初期化はサブスクリプション順に行われます。
ヨハネスシャウブ-litb

2
@ジョセフ:そして、それらも逆の順序で破壊されるため、デストラクタを同じくらい簡単に使用できます:)
j_random_hacker

263

私は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
その行を生成するプログラムを書いていただければ幸いです。
マーティンヨーク

32
open( "1000.c"、 'w')。write( 'printf( "%s");'%( "\ n" .join([str(x)for x in xrange(1,1000)]) ))
タイラー・イーブス2011年

53
その行を生成するために作成したプログラムにループが含まれていないことを願っています!
Jeeyoung Kim

20
Vimマクロはその仕事を素早く行います。
StackedCrooked 2011年

2
Perlの少しはそれを空想的な方法で生成します:$r='printf("'; for (1..1000) { $r.="$_\\n" } $r.='");'; print $r;
sidyll

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

すべての数字を印刷するわけではありませんが、「1から1000までの数字を印刷」します。勝利のためのあいまいな質問!:)


77
'printf( "numbers from 1 to 1000")'の後の私のお気に入り-愚かな質問には愚かな答えが必要です。
SEngstrom、2011年

これは素晴らしいです。質問のあいまいさを利用するための+1。笑
Nawaz、

2
編集済み; 決して、形も形もこのコードを実行しませんでしたprint "Print numbers from 1 to 1000."-勝利へのあいまいな質問、不正確な説明は
うんざりです

うわー、最近この質問の答えに少し荒らしがありました。そのロックを履歴ロックにアップグレードする必要があるとのことです。
BoltClock

172

致命的なエラーを引き起こします!これがファイル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()の後...プログラムがクラッシュしても、出力バッファーが画面に出力されるとは限りません。
zakk

10
@zakk:厳密には必要ありません。デフォルトではstdoutは行バッファリング\nされるため、出力をフラッシュするのに十分です。
psmears

24
stdoutは、インタラクティブデバイスあると判断できる場合はラインバッファリングされ、それ以外の場合は完全にバッファリングされます。教授が自動チェックのためにstdoutをファイルにリダイレクトすると、失敗します:-)
paxdiablo '28 / 01/01

(埋め込み的環境における例えば)stackoverflowの危険
エルナンEche

166

システムコマンドの使用:

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

15
高確率 /usr/bin/seq内部でループを使用するがです。:)

@jokester:つまり、Solaris / BSDにはseqユーティリティ(デフォルトのセットアップ)がないためですか?<grin />
sehe

私はこれを言うのが嫌いです(まあ、私はしません)が、あなたの解決策にはバグがあります。正しい数字のセットを出力しません。:)ここに修正があります:system("/bin/echo {1..1000}"); これあなただけが最初にユニットテストを書いたなら...
Don Branson '26

1
一部の明るい男は私の答えを変更することを決めたので、それは私の間違いではありません。
モイヌディン

100

テストされていませんが、標準的な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);
}

29
@Prasoon:それは関係です。
Yakov Galka 2010

28
要件は「条件なし」(if、switchなど)です。「条件なし」ではない
jon_darkstar

32
<状態ではありません。これは関係演算子です。if/ elseは条件付きステートメントです。?:条件付き演算子です。<ブール値を返す単なる演算子です。それはおそらくジャンプや何もない単一の機械命令です。
Chris Lutz

12
@クリスルッツは::x86では、それは3つの指示だcmplsetlemovzbl。x86-64はそのプラスcltqです。PowerPCは2つの命令ですcmpwicrnot
Adam Rosenfield、2011年

4
1 - i / 1000。比較なし!
タイの

96

ここの他のものに比べて少し退屈ですが、おそらく彼らが探しているものです。

#include <stdio.h>

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

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

短くしました。メインの外側、次にメインの内側にi = 1を設定:printf( "%d \ n"、11-i)&& --i && main(i);
jftuga

3
@Jens Schauder:&&の最初の行で遅延評価を利用するf()
ラファウDowgird

10
これは退屈ではなく、簡単です。テンプレートマジックの巨大な混乱と同じように、短い関数でも同じことができる場合は、次の関数でそれを行う必要があります:)
amertune

21
&&は条件付きです。数学的なANDは、両側を評価します(Java&およびAdaの「AND」のように)。&&は、2番目の演算子を(ここでは)最初の演算子が真の場合にのみ評価します。または他の例:Adaでは、短絡演算子は「OR THEN」と呼ばれ、THENを使用して条件付きの側面を示します。申し訳ありませんが、?:演算子。
マーティン

謝罪する必要はありません。&&は比較演算子です。三項演算子は条件付きです。
アーロン

71

タスクは、プログラムが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);
}

ただし、1000で止まるわけではありません。それはただ進み続ける。
レミールボー、2011年

CまたはC ++の要件を廃止した場合にのみ短縮できます。その後、理論上のコンパイラが(任意の入力から)必要なプログラムを生成できるため、任意の「プログラム」が実行されます。
eq- 2011年

@eq再び、これは正常にコンパイルおよび実行されます…
Mark McDonald

72
後付けとして:明らかな数学を回避することさえできます。を使用する場合はrand()、1から1000までのすべての数値を出力します。最終的に =:P

5
@pooh:必ずしもそうではありません。rand()は特定のシーケンスの後に繰り返す可能性があり、そのシーケンスはこの問題のソリューションセットに含まれない可能性があるためです。
dchhetri

71

やさしい!:P

#include <iostream>

static int current = 1;

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

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

あなたはそれ以外の場合は2から1001に印刷されます「= 0静的int型電流」をしたいかもしれません
Shinnok

++ currentをcurrent ++に変更しました
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
うーん。マクロ。夕食はどうですか。
EvilTeach 2011年

42

1000のスレッドを起動でき、それぞれが数値の1つを出力します。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。
Chris Lutz

11
@クリスほとんどのソリューションはどこかに隠されたループを持っていますか?
モイヌディン2011年

「コンパイラーのループ」アプローチを採用していると思います。(の引数に対する可能なループ以外ではMPI::Init())1000.cppプログラムの実際のバイナリにループがあるとは想像できないため、実行すると確実にループが実行されているにもかかわらず、+ 1を与えました。
Chris Lutz、2011年

40

プレーン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()ます。


数値1000が10進法を示唆しているのはなぜですか?baseを使用した位置表記法でBは、1000は完全に有効な数値であり、常に等しくなりB^3ます。
フィリップ

数値が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, " "));
}

あなたのコードは0から始まると思います。Chrisにも同意します。数年前に私が見たときの質問は、「IO以外のライブラリなし」と述べられていました。まだ+1 :)
Yakov Galka 2010

3
@Chris Lutz:コピーの実装は未定義です。上記のテンプレートコードを使用することもできます(わからないだけです)。したがって、ループが使用されているとは言えません。
マーティンヨーク

7
実際、私のnitピックはstd::copy、の暗黙の条件付きほどの暗黙のループにはなりませんoperator !=()。とにかく、それは範囲を処理する上での賢い選択であり、賢いアプローチは、このような質問への回答として私が探しているものです。
Michael Burr

実装固有は未定義
selvaiyyamperumal 2011

@selvaiyyamperumal:何を話しているのか正確にはわかりません。しかし、行動について話している場合、標準はあなたに同意しません。「実装定義の動作」とは、明確に定義されているが、実装によって明示的に文書化されている必要があることを意味します。「未定義の動作」とは、発生する可能性があることを意味します。
マーティンヨーク

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を逃していたのはおかしいと思いました。素敵な解決策!
エヴァンモラン

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

醜いCの答え(10の累乗あたり1つのスタックフレームのみアンロール):

#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()」ですか?悪い習慣はめったに行かない?:P
Nawaz、2011年

30
@Nawaz:これは密かにWindows GUIアプリであるため、問題ではありません。ロブスターについて考えていて、スペルがひどいので、私はそれを「メイン」とだけ呼びました。
マーティン

29

スタックオーバーフロー:

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

これは8MBスタック用です。各関数の呼び出しには、約32バイト(つまり、32 * 1000)がかかるようです。しかし、実行すると804になりました(したがって196 *32。Cランタイムには、スタック内に他にも差し引かなければならない部分があります)。


25

関数ポインタを使って楽しい(新しくできた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);

私はあなたがビットシフトでそれを手に入れる方法が好きです。しかし、後で簡単に説明すると、ダブルバンは何をしますか?そのビットごとまたは論理?私は迷子になり、グーグルは私を輪になって回らせましたfuncs[!!(limit-1)](x+1, limit-1);
jon_darkstar

私はむしろ単一!の関数ポインタ配列要素を切り替えたいのですが、それが他の狂気でうまく機能するかどうかはわかりません。
Chris Lutz

@Chris:私は完全に同意しますが、投稿後まで論理/関係演算子の使用を検討しなかったため、1行のパッチの方が適切であると考えました。その上、問題の全体的な難読化された感触と少し良く合います。
Michael Burr

24

この答えはとてもシンプルで理解しやすいと思います。

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
あなたの答えは条件文を使用していますが、これは質問に従って禁止されています。
stevelove 2011年

4
条件文は他の場合などです。論理演算を使用しただけです!! わかりました!
パプ

2
あなたのコメントでさえ、あなたは「はいならば、印刷するために再帰的な関数を呼び出します」と書きました。明白ではない方法で書かれた条件文は、まだ条件文です。デフォルトのnumも条件付きです。
ジェリー

23

私はすべての楽しみを逃しました、すべての良いC ++回答がすでに投稿されています!

これは私が思いつくことができる最も奇妙なことですが、それは合法的な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;
}

main私が覚えているように、呼び出しは未定義の動作になります。
Yakov Galka

4
それは完全に合法なCです。@ ybungalobill:main()の呼び出しが特に許可されていないC ++について考える必要があります。
Michael Foukarakis

@マイケル:たぶん、私はCにあまり慣れていない
Yakov Galka

Boostの使用はC ++を意味すると思います。とにかく、Boost.PPソリューションに対する称賛。
me22 2010

6
論理演算子&&||は、短絡するため(おそらく)、「条件付き」に該当し?:ます。
munificent

22

やさしい:

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

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

より多くのプリプロセッサ乱用:

#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()そのような議論なしであなたは呼ぶことができますか?
Chris Lutz、2011年

私自身、それについて知りました。GCCで適切に動作しますが、明確に定義された動作かどうかはわかりません。
keithmo、2011年

C99で明確に定義されている、C89が言ったことを覚えていない、メモリが機能する場合、少なくとも一部のバージョンのMSVCで問題を引き起こします。
zwol、2011年

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

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
PatrickSchlüter
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.