1202355906 【はてな五番勝負!】キーワード:C言語なら、オレに聞け!


おれは32才、10年間プログラムを一生懸命作ってきた。
C言語しか知らないがC言語なら誰にも負けない...
・キーワードに関連して、なんでも質問してくれ。
・あなたの質問に全力で答えるが、C-FAQ載ってる質問をすると全力で煽るかも知れない。
・回答に納得したらスターを付けろ。

この質問はhttp://q.hatena.ne.jp/1202314128への応募だ。

回答の条件
  • 1人1回まで
  • 登録:
  • 終了:2008/02/11 21:20:49
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:pyopyopyo No.4

回答回数377ベストアンサー獲得回数98

ポイント100pt

以下のコードを解読して,解説してください.

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);}
id:dev_zer0

何かのゲームらしいことは理解できたが、それ以外は分からん

適当なコメントは入れてみたが意味が分からん

/**
 * 変数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);
}
2008/02/10 21:44:32

その他の回答5件)

id:BLOG15 No.1

回答回数20ベストアンサー獲得回数5

ポイント20pt

プログラミングのことは全く何も知らない素人です。C言語には、C++というのとC♯という言語もあると思います。

wikipediaの説明を見てみましたが、専門用語だらけでこれらの違いが全くわかりません。この3つの言語の違いを素人にもわかるように、専門用語を使わずやさしく私に教えて下さい。

id:dev_zer0

あなたは日本語という自然言語で質問されていますが、

日本語しか話せない人に英語やフランス語の違いを分かりやすく説明できると思いますか?

多分、日本語しか知らない質問された人間は、適当なことを言うか、

自分の中の語彙を総動員して煙に巻くに違いありません。


ハッキリ言ってしまいますが、3歳程度の子供に対して日本語と英語の文法や単語の違いを

専門用語を使わずに子供に理解させようとする行為をあなたは私に要求しています。

もし、あなたが気軽に行ったその質問の答えが知りたいのならば

C、C++、C#のプログラム言語を知って、理解してください。

そうすれば自ずと答えは導き出されます。


私は(設定上)Cしか知りませんが、Cの良書としてプログラミング言語C(通称K&R)

をお勧めします。まず、これを読んでCを知るという努力をしてください。


以上

2008/02/09 17:09:02
id:miharaseihyou No.2

回答回数5224ベストアンサー獲得回数717

ポイント35pt

それでは、C言語の「性別」を二択で答えていただきましょう。 

 男らしいですか? それとも女っぽいでしょうか?

 男性向き or 女性向き ?

50文字以下でお答えください。

id:dev_zer0

私は男であり、Cは女、そしてプログラミングの結果できたプログラムは私の子供ですが何か?

(43文字)

2008/02/09 17:25:10
id:ffmpeg No.3

回答回数1202ベストアンサー獲得回数9

ポイント10pt

プログラミングはソフトを作ってなんぼのもん。クイズごっこなんていうてる時点でクズ


http://www

id:dev_zer0

オマエモナー

# 煽りたいだけならコメントで好きなだけやってくれ

2008/02/09 20:05:20
id:pyopyopyo No.4

回答回数377ベストアンサー獲得回数98ここでベストアンサー

ポイント100pt

以下のコードを解読して,解説してください.

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);}
id:dev_zer0

何かのゲームらしいことは理解できたが、それ以外は分からん

適当なコメントは入れてみたが意味が分からん

/**
 * 変数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);
}
2008/02/10 21:44:32
id:shirasaki No.5

回答回数1ベストアンサー獲得回数0

ポイント30pt

真面目に知りたいことを質問します。複数の質問が不可であるならば、どれか1つ選んで回答お願いします。

1.while()ではなく、do while()を使ったほうがよいと思われるケースを理由とともに教えてください。

  できれば、2つ以上お願いします。

2.C99には可変配列があるようですが、これについてどう思われますか。

  私は使えないと思うのですが、もし使えると考えるならば、どういったケースで使いますか。

3.どういったプログラムをCで組むべきでしょうか。逆に、どういったプログラムをCで組んではいけないと考えますか。

  他言語との比較ではなく、Cのみで語ってください。

id:dev_zer0

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はプログラマは間違ったことをしないという誤った前提の上に確立された言語である

誤った設計の言語だが、我々は残念ながら「まだ」それを手放せない

2008/02/10 17:44:39
id:DASM No.6

回答回数6ベストアンサー獲得回数0

ポイント50pt

1. qmail を再実装してバグ全取り、新機能追加、保守性うpで DJB 信者をギャフン! と言わせてください (難易度: 高)

2. http://pc11.2ch.net/test/read.cgi/tech/1142467359/ で紹介された C 以外のコードを C で縮めて C TUEEEEEEE!!!!!!! と言わしめてください (難易度: 低)

3. はてなクローンを C で作ってください (難易度: どこまで実装するか次第)

4. P2P のコンソールゲームを作ってください (難易度: 超低)

id:dev_zer0

1.俺がするなら、まずsmtpを廃止する。そもそも、telnetがsshに置き換わったように

糞ほどもセキュリティを考慮していないstmpを死滅させるべきだ。

# smtp over sshなんて延命措置などいらない

そして、RFCにssmtp(仮称)を提案し、qmailもDJB信者も涙目にさせてやる

でも、それは多分Cでは実装しないと思うし、自分もデバッグで涙目になりそうな気がする


2.スマン。そのスレの7行オセロで「TUEEEEEEE!!!!!!! 」と言わされた方だ

 7行でオセロゲーム(思考回路付き)なんて出来るわけないと思ってた。


3.Don't Repeat Yourself.(DRY)


4.仕様書は?

2008/02/10 15:01:48
  • id:dev_zer0
    さて、勝負したいと思います。
     
    今回のポイントの振り分け基準に関してはルールにはないので
    私の独断と偏見で振り分けます。
    一応、質問した方1人に対し、10~50ポイントを差し上げます。
    ポイントが高い質問は
    ・質問自体が高レベルであると私が判断したもの
    ・質問文が簡潔で分かりやすく、誤解を招きにくいものであること
    一方、ポイントが低い質問は
    ・質問自体が「ググレカス」で終わるようレベル
    ・質問が分かりにくい
    ・特定のOSやコンパイラでしか再現しないような状態なのに、
     自分のOSやコンパイラを書いていない質問
    とします。
     
    また、私が質問に答えられない「勝負に負けた」状態だったり
    明らかに間違った解答をした場合には、100ポイント差し上げます。
    # コメントは開けていますので、指摘は随時行ってください。
     
     
    さて、見せてもらおうか、連邦の質問とやらを
  • id:dev_zer0
    一応、終わり。
    割り振る予定のポイントは一応下記の通り
    #1 20pt:Cの質問にプログラミング言語の質問をしたので減点
    #2 35pt:意表をついた質問と50文字縛りが意外と難しかった
    #3 10pt:(注参照)
    #4 100pt:悔しいが出来なかったので仕方ない
    #5 30pt:こういう質問を想定していた
    #6 30pt:ま、こういうのも想定していた
     
    (注)
    本来は0ptにしたかったが、質問ではない回答を想定していなかった
    # なので回答数を+1したが...
    プログラマとしてどんなエラーケースも想定すべきだということを改めて思い知った
     
    異論、反論は認める
    月曜の夜に〆るのでそれまでに何らかのコメントがあれば反映する
    なお、延長は無い。#4の回答のダメージを抜きたい...
  • id:miharaseihyou
    お疲れ様でした。今度お会いできたときはお互いにもっと楽しみましょう。それではまたいつの日か。
  • id:DASM
    できるプログラマは使える情報を全て使う。

    - http://www.google.co.jp/search?q=%22stty+cbreak+-echo+stop+u%22
    - http://f4.aaa.livedoor.jp/~pointc/log559.html

    自分で解読しようとした努力は買うけど、そんなのただの自己満足だよ。
    べ、別に責めてるわけじゃないんだからねっ!!
  • id:dev_zer0
    > できるプログラマは使える情報を全て使う。
    その通り、反論の余地は無いが、言い訳をさせてもらうと
    IOCCCのだと断定してしまった俺の判断ミスだ
    これで余計な時間を食った挙句に、IOCCCのコードが精神を蝕んだ
     
    結局負けには変わりないし、授業料としては安いものだ
    回答を教えてくれたので+20ptを進呈しようと思う。
  • id:pyopyopyo
    #4の問題ですが,これは tetris.c というソースコードで,1989年のIOCCCで優勝したコードです

    termcap/terminfo のサンプルコード(!)として,GNU の screen におまけでついています.
    これじゃ,サンプルコードなのに読めませんね.
  • id:dev_zer0
    ・・・やっぱIOCCCで合ってはいたのか
    俺の目と検索能力はザルかよ...
     
    となると12は横幅でG()は消去判定か
    f[]のテーブルはテトリスのデータ
     
    ここまでマヌケだともう何も言えない
  • id:DASM
    ヒント: デバッグ実行も解読手法の一つ
  • id:hokuraku
    【はてな五番勝負!】事務局です。
    dev_zer0さん、ご苦労様でした。
    現在☆をくれた質問者さんはid:shirasakiさんとid:miharaseihyouさんのお二人ですね。
    他の方はどうでしょうか?今日の夜中くらいに締め切ってもいいですか?
  • id:DASM
    スターってブックマークのやつか。初めてつけた。
  • id:dev_zer0
    私は一向に構いません。
    が、他の勝負師のkazubokkuriさんやdoriasoさんはどうなんでしょう?
  • id:hokuraku
    ありがとうございます。
    kazubokkuriさんはOKいただきました。
    doriasoさんはスタートが遅かったので後で清算する予定です。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません