おれは32才、10年間プログラムを一生懸命作ってきた。
C言語しか知らないがC言語なら誰にも負けない...
・キーワードに関連して、なんでも質問してくれ。
・あなたの質問に全力で答えるが、C-FAQ載ってる質問をすると全力で煽るかも知れない。
・回答に納得したらスターを付けろ。
この質問はhttp://q.hatena.ne.jp/1202314128への応募だ。
以下のコードを解読して,解説してください.
long h[4];t(){h[3]-=h[3]/3000;setitimer(0,h,0);}c,d,l,v[]={(int)t,0,2},w,s,I,K =0,i=276,j,k,q[276],Q[276],*n=q,*m,x=17,f[]={7,-13,-12,1,8,-11,-12,-1,9,-1,1, 12,3,-13,-12,-1,12,-1,11,1,15,-1,13,1,18,-1,1,2,0,-12,-1,11,1,-12,1,13,10,-12, 1,12,11,-12,-1,1,2,-12,-1,12,13,-12,12,13,14,-11,-1,1,4,-13,-12,12,16,-11,-12, 12,17,-13,1,-1,5,-12,12,11,6,-12,12,24};u(){for(i=11;++i<264;)if((k=q[i])-Q[i] ){Q[i]=k;if(i-++I||i%12<1)printf("\033[%d;%dH",(I=i)/12,i%12*2+28);printf( "\033[%dm "+(K-k?0:5),k);K=k;}Q[263]=c=getchar();}G(b){for(i=4;i--;)if(q[i?b+ n[i]:b])return 0;return 1;}g(b){for(i=4;i--;q[i?x+n[i]:x]=b);}main(C,V,a)char* *V,*a;{h[3]=1000000/(l=C>1?atoi(V[1]):2);for(a=C>2?V[2]:"jkl pq";i;i--)*n++=i< 25||i%12<2?7:0;srand(getpid());system("stty cbreak -echo stop u");sigvec(14,v, 0);t();puts("\033[H\033[J");for(n=f+rand()%7*4;;g(7),u(),g(0)){if(c<0){if(G(x+ 12))x+=12;else{g(7);++w;for(j=0;j<252;j=12*(j/12+1))for(;q[++j];)if(j%12==10){ for(;j%12;q[j--]=0);u();for(;--j;q[j+12]=q[j]);u();}n=f+rand()%7*4;G(x=17)||(c =a[5]);}}if(c==*a)G(--x)||++x;if(c==a[1])n=f+4**(m=n),G(x)||(n=m);if(c==a[2])G (++x)||--x;if(c==a[3])for(;G(x+12);++w)x+=12;if(c==a[4]||c==a[5]){s=sigblock( 8192);printf("\033[H\033[J\033[0m%d\n",w);if(c==a[5])break;for(j=264;j--;Q[j]= 0);while(getchar()-a[4]);puts("\033[H\033[J\033[7m");sigsetmask(s);}}d=popen( "stty -cbreak echo stop \023;sort -mnr -o HI - HI;cat HI","w");fprintf(d, "%4d from level %1d by %s\n",w,l,getlogin());pclose(d);}
プログラミングのことは全く何も知らない素人です。C言語には、C++というのとC♯という言語もあると思います。
wikipediaの説明を見てみましたが、専門用語だらけでこれらの違いが全くわかりません。この3つの言語の違いを素人にもわかるように、専門用語を使わずやさしく私に教えて下さい。
あなたは日本語という自然言語で質問されていますが、
日本語しか話せない人に英語やフランス語の違いを分かりやすく説明できると思いますか?
多分、日本語しか知らない質問された人間は、適当なことを言うか、
自分の中の語彙を総動員して煙に巻くに違いありません。
ハッキリ言ってしまいますが、3歳程度の子供に対して日本語と英語の文法や単語の違いを
専門用語を使わずに子供に理解させようとする行為をあなたは私に要求しています。
もし、あなたが気軽に行ったその質問の答えが知りたいのならば
C、C++、C#のプログラム言語を知って、理解してください。
そうすれば自ずと答えは導き出されます。
私は(設定上)Cしか知りませんが、Cの良書としてプログラミング言語C(通称K&R)
をお勧めします。まず、これを読んでCを知るという努力をしてください。
以上
それでは、C言語の「性別」を二択で答えていただきましょう。
男らしいですか? それとも女っぽいでしょうか?
男性向き or 女性向き ?
50文字以下でお答えください。
私は男であり、Cは女、そしてプログラミングの結果できたプログラムは私の子供ですが何か?
(43文字)
オマエモナー
# 煽りたいだけならコメントで好きなだけやってくれ
以下のコードを解読して,解説してください.
long h[4];t(){h[3]-=h[3]/3000;setitimer(0,h,0);}c,d,l,v[]={(int)t,0,2},w,s,I,K =0,i=276,j,k,q[276],Q[276],*n=q,*m,x=17,f[]={7,-13,-12,1,8,-11,-12,-1,9,-1,1, 12,3,-13,-12,-1,12,-1,11,1,15,-1,13,1,18,-1,1,2,0,-12,-1,11,1,-12,1,13,10,-12, 1,12,11,-12,-1,1,2,-12,-1,12,13,-12,12,13,14,-11,-1,1,4,-13,-12,12,16,-11,-12, 12,17,-13,1,-1,5,-12,12,11,6,-12,12,24};u(){for(i=11;++i<264;)if((k=q[i])-Q[i] ){Q[i]=k;if(i-++I||i%12<1)printf("\033[%d;%dH",(I=i)/12,i%12*2+28);printf( "\033[%dm "+(K-k?0:5),k);K=k;}Q[263]=c=getchar();}G(b){for(i=4;i--;)if(q[i?b+ n[i]:b])return 0;return 1;}g(b){for(i=4;i--;q[i?x+n[i]:x]=b);}main(C,V,a)char* *V,*a;{h[3]=1000000/(l=C>1?atoi(V[1]):2);for(a=C>2?V[2]:"jkl pq";i;i--)*n++=i< 25||i%12<2?7:0;srand(getpid());system("stty cbreak -echo stop u");sigvec(14,v, 0);t();puts("\033[H\033[J");for(n=f+rand()%7*4;;g(7),u(),g(0)){if(c<0){if(G(x+ 12))x+=12;else{g(7);++w;for(j=0;j<252;j=12*(j/12+1))for(;q[++j];)if(j%12==10){ for(;j%12;q[j--]=0);u();for(;--j;q[j+12]=q[j]);u();}n=f+rand()%7*4;G(x=17)||(c =a[5]);}}if(c==*a)G(--x)||++x;if(c==a[1])n=f+4**(m=n),G(x)||(n=m);if(c==a[2])G (++x)||--x;if(c==a[3])for(;G(x+12);++w)x+=12;if(c==a[4]||c==a[5]){s=sigblock( 8192);printf("\033[H\033[J\033[0m%d\n",w);if(c==a[5])break;for(j=264;j--;Q[j]= 0);while(getchar()-a[4]);puts("\033[H\033[J\033[7m");sigsetmask(s);}}d=popen( "stty -cbreak echo stop \023;sort -mnr -o HI - HI;cat HI","w");fprintf(d, "%4d from level %1d by %s\n",w,l,getlogin());pclose(d);}
何かのゲームらしいことは理解できたが、それ以外は分からん
適当なコメントは入れてみたが意味が分からん
/** * 変数h[4]の本来の構造 * struct itimerval { * struct timeval { * long tv_sec; * long tv_usec; * } interval; * struct timeval { * long tv_sec; * long tv_usec; * } timeval; * }; */ long h[4]; /** * タイマ設定 */ int t(void) { // h[3]とはtimeval.tv_secである h[3] -= h[3] / 3000; setitimer (0, h, 0); } int c; // getchar()の結果とa[0]~a[5]が入ることがある int d; // FILE * だろうが!popen()の戻りは! int l; // レベル、これが高いと、割り込む間隔が短くなる /** * 変数v[]の本来の構造 * struct sigvec { * void (*sv_handler)(); * int sv_mask; * int sv_flags; * }; */ int v[] = { (int)t, 0, 2 }; int w; // 得点じゃね?ひたすらインクリメントされてるだけ int s; // シグナルのブロック、解除用 int I; // 良くわからない、iと関係ありそう int K= 0; // 良くわからない、kと関係ありそう int i = 276; // カウンタ、色々な箇所で使われている int j; // カウンタその2、12の倍数でトリッキーな挙動をする int k; // 何かの判定で使われているらしい int q[276]; // ここが肝 int Q[276]; // ここが肝 int *n = q; // このnの使われ方が一番の謎 int *m; // まぁ、mもnと同じぐらい謎だけどさ int x = 17; // これは17に初期化しとかないとマズイらしい /** * 怪しいテーブル * 使っている箇所 * n = f + rand () % 7 * 4 * n = f + 4 ** (m = n), G (x) || (n = m); * とにかく、nの挙動に注意 */ int f[] = { 7, -13, -12, 1, 8, -11, -12, -1, 9, -1, 1, 12, 3, -13, -12, -1, 12, -1, 11, 1, 15, -1, 13, 1, 18, -1, 1, 2, 0, -12, -1, 11, 1, -12, 1, 13, 10, -12, 1, 12, 11, -12, -1, 1, 2, -12, -1, 12, 13, -12, 12, 13, 14, -11, -1, 1, 4, -13, -12, 12, 16, -11, -12, 12, 17, -13, 1, -1, 5, -12, 12, 11, 6, -12, 12, 24 }; /** * 何かをprintfしたいらしい * in :q * out:Q, I * 多分、ローカル変数でも良いもの * i, k */ int u(void) { // 11以降から最後までQを舐める for (i = 11; ++i < 264;) { // q[i] - Q[i]が\0以外の場合 if ((k = q[i]) - Q[i]) { Q[i] = k; // Q[i] = q[i] // 12って何?後回し if (i - ++I || i % 12 < 1) printf("\033[%d;%dH", (I = i) / 12, i % 12 * 2 + 28); printf("\033[%dm " + (K - k ? 0 : 5), k); K = k; } } // Qの最後(\0除く)に文字保存 Q[263] = c = getchar(); } /** * 何かを見つけて、 * 見つかったら0, 見つからなかったら1を返す * in :n, q * out:なし * 多分、ローカル変数でも良いもの * i */ int G(int b) { // 4回繰り返し for (i = 4; i--;) { // 何かを見つけている // i != 0の場合、q[b + n[i]]が0以外なら0を返す // i == 0の場合、q[b]が0以外なら0を返す if (q[i ? b + n[i] : b]) return 0; } // 見つからなかったら1を返す return 1; } /** * bをqのどこかに代入 * in :n, q * out:q * 多分、ローカル変数でも良いもの * i */ int g(int b) { // 4回繰り返し // i == 0 の場合、q[x] = b(ループ最後だけ、特殊) // i != 0 の場合、q[x + n[i]] = b for (i = 4; i--; q[i ? x + n[i] : x] = b) ; } /** * main、*aは環境変数だったっけ? */ //main (C, V, a) // char **V, *a; int main(int C, char **V, char *a) { // タイマの設定、引数が無い場合デフォルト値2 // 引数が存在する場合、その値にする // なお、数値以外が設定されると0割しないか? h[3] = 1000000 / (l = C > 1 ? atoi (V[1]) : 2); // キーバインドの設定、デフォルトでは // a[0] = 'j', a[1] = 'k', a[2] = 'l', a[3] = ' ', // a[4] = 'p', a[5] = 'q' for (a = C > 2 ? V[2] : "jkl pq"; i; i--) *n++ = i < 25 || i % 12 < 2 ? 7 : 0; srand(getpid()); system("stty cbreak -echo stop u"); // SIGBUSをトラップし、t()を再度実行させる sigvec(14, v, 0); t(); puts("\033[H\033[J"); // 無限ループし、g(7), u(), g(0)を呼び続ける // よく分からない用途であるnの初期化 for (n = f + rand () % 7 * 4;; g(7), u(), g(0)) { if (c < 0) { // また12が出てきた、12って何だ? if (G(x + 12)) { x += 12; } else { g(7); ++w; // j = 12 * (j / 12 + 1)ではjは12の倍数を取る for (j = 0; j < 252; j = 12 * (j / 12 + 1)) { // whileで良くね? for (; q[++j];) { if (j % 12 == 10) { for (; j % 12; q[j--] = 0) ; u(); for (; --j; q[j + 12] = q[j]) ; u (); } // nの再初期化 n = f + rand () % 7 * 4; // xを17に初期化(), cには何を代入している? G (x = 17) || (c = a[5]); } } } } // jがキー入力された場合 if (c == *a) // Gが0を返すと、++xは実行しない G(--x) || ++x; // kがキー入力された場合 if (c == a[1]) // n = f[4 * *n]? わけ分からん n = f + 4 * *(m = n), G (x) || (n = m); // lがキー入力された場合 if (c == a[2]) G(++x) || --x; // スペースがキー入力された場合 if (c == a[3]) for (; G(x + 12); ++w) x += 12; // p, qがキー入力された場合 if (c == a[4] || c == a[5]) { // この最中はシグナル割り込みされると困るらしい s = sigblock(8192); printf ("\033[H\033[J\033[0m%d\n", w); // qなら終了 if (c == a[5]) break; // Qの初期化。memset使えよ! for (j = 264; j--; Q[j] = 0) ; // pが押されるまでループ while (getchar() - a[4]) ; puts ("\033[H\033[J\033[7m"); // シグナル割り込み解除 sigsetmask(s); } } // HIというファイルを操作しているらしい(多分、ハイスコアと言う意味) d = popen("stty -cbreak echo stop \023;sort -mnr -o HI - HI;cat HI", "w"); // もしかして、得点、レベル、名前を表示してるのか? fprintf(d, "%4d from level %1d by %s\n", w, l, getlogin()); pclose(d); }
真面目に知りたいことを質問します。複数の質問が不可であるならば、どれか1つ選んで回答お願いします。
1.while()ではなく、do while()を使ったほうがよいと思われるケースを理由とともに教えてください。
できれば、2つ以上お願いします。
2.C99には可変配列があるようですが、これについてどう思われますか。
私は使えないと思うのですが、もし使えると考えるならば、どういったケースで使いますか。
3.どういったプログラムをCで組むべきでしょうか。逆に、どういったプログラムをCで組んではいけないと考えますか。
他言語との比較ではなく、Cのみで語ってください。
1.do while()を使ったほうがよいと思われるケース
基本は1回以上処理を行うときにdo-while, 0回以上の場合はwhileを使えばいいんじゃね?
思いつく例としては
例1:コンソールからの入力の妥当性チェック
#include <stdio.h> int main(void) { char buf[256]; int i = 0; do { printf("input>"); fgets(buf, sizeof buf, stdin); i = atoi(buf); } while(i <= 0); printf("i = %d\n", i); return 0; }
例2:コーディング規約でgotoが禁止されてしまった場合のエラー処理
#include <stdio.h> /* ファイルコピー */ int main(int argc, char **argv) { FILE *src = NULL; FILE *dst = NULL; int c = 0; /* パラメータチェックは本論ではないので省略 */ do { src = fopen(argv[1], "rb"); if (src == NULL) break; dst = fopen(argv[2], "wb"); if (dst == NULL) break; do { if ((c = fgetc(src)) == EOF) break; if ((c = fputc(c, dst)) == EOF) break; } while (c != EOF); if(ferror(dst) || ferror(src)) fprintf(stderr, "エラーが発生\n"); } while (0); /* OPENしてたらCLOSE */ if(dst != NULL) fclose(dst); if(src != NULL) fclose(src); return 0; }
例3:マクロ内で変数を使いたいとき
#define swap(type, a, b) \ do { type tmp; tmp = a; b = a; a = tmp; } while[0]
2.可変長配列の私見
可変長配列なんて中でallocaが呼ばれてるだけでしょ?
http://www.linux.or.jp/JM/html/LDP_man-pages/man3/alloca.3.html
gcc拡張でよく使われているし、allocaが規格として認められたと思えばいいと思う。
# 個人的にC99規格は好きではないけれど...
使うケースとしては例えばコード変換とかで
int conv(const char *src, size_t siz, char *dst) { char tmp[siz];
とできると便利だとは思う。
3-a.Cで組むべきプログラムとは
移植性と速度を両立させたい場合、2008年現在ではC以外の選択肢は少ない
よって、移植性と速度を両立させなければならないプログラム、ライブラリを
作らなければならなくなった場合、Cかbetter CなC++にならざる得ないだろう
3-b.Cで組んではいけないプログラムとは
Cで組んではいけないプログラムなどこの世界には存在しない。好きにしろ
ただ、文字列処理はCでは面倒だし、バグの温床になるのでCで組むのは止めておけとは忠告する。
初心者が良く扱うscanf()はバッファ溢れをさせないためにはえらい注意が必要だし、
strtok()はスレッドセーフでないし、gets()はC89,C99では非推奨だ。
# C99ではgets()は非推奨とかいう生ぬるい措置ではなく、ライブラリから外せと問い詰めたい
最後に「あえて」他言語と比較しよう
Cはレジスタを意識させること無く、アセンブラ並みの性能を引き出したことに成功した言語だ
# register宣言は?という突っ込みは却下する
そして、最近の言語はメモリ管理を意識することなくプログラミングができることを可能にしている
プログラマは低級な資源の管理に気を取られること無く、問題の本質に集中することができる
これは、わたしも歓迎する
Cはプログラマは間違ったことをしないという誤った前提の上に確立された言語である
誤った設計の言語だが、我々は残念ながら「まだ」それを手放せない
1. qmail を再実装してバグ全取り、新機能追加、保守性うpで DJB 信者をギャフン! と言わせてください (難易度: 高)
2. http://pc11.2ch.net/test/read.cgi/tech/1142467359/ で紹介された C 以外のコードを C で縮めて C TUEEEEEEE!!!!!!! と言わしめてください (難易度: 低)
3. はてなクローンを C で作ってください (難易度: どこまで実装するか次第)
4. P2P のコンソールゲームを作ってください (難易度: 超低)
1.俺がするなら、まずsmtpを廃止する。そもそも、telnetがsshに置き換わったように
糞ほどもセキュリティを考慮していないstmpを死滅させるべきだ。
# smtp over sshなんて延命措置などいらない
そして、RFCにssmtp(仮称)を提案し、qmailもDJB信者も涙目にさせてやる
でも、それは多分Cでは実装しないと思うし、自分もデバッグで涙目になりそうな気がする
2.スマン。そのスレの7行オセロで「TUEEEEEEE!!!!!!! 」と言わされた方だ
7行でオセロゲーム(思考回路付き)なんて出来るわけないと思ってた。
3.Don't Repeat Yourself.(DRY)
4.仕様書は?
何かのゲームらしいことは理解できたが、それ以外は分からん
適当なコメントは入れてみたが意味が分からん