75日目 printf("a:%a\n", EOF);〜printf("z:%z\n", EOF);

ひさしぶりに何も用事のない穏やかな休日だったので遊んでみた。

#include <stdio.h>

int main()
{
	printf("a:%a\n", EOF);
	printf("b:%b\n", EOF);
	printf("c:%c\n", EOF);
	printf("d:%d\n", EOF);
	printf("e:%e\n", EOF);
	printf("f:%f\n", EOF);
	printf("g:%g\n", EOF);
	printf("h:%h\n", EOF);
	printf("i:%i\n", EOF);
	printf("j:%j\n", EOF);
	printf("k:%k\n", EOF);
	printf("l:%l\n", EOF);
	printf("m:%m\n", EOF);
	printf("n:%n\n", EOF);
	printf("o:%o\n", EOF);
	printf("p:%p\n", EOF);
	printf("q:%q\n", EOF);
	printf("r:%r\n", EOF);
	printf("s:%n\n", EOF);
	printf("t:%t\n", EOF);
	printf("u:%u\n", EOF);
	printf("v:%v\n", EOF);
	printf("w:%w\n", EOF);
	printf("x:%x\n", EOF);
	printf("y:%y\n", EOF);
	printf("z:%z\n", EOF);

	return 0;
}
続きを読む

75日目 K&R3.3と格闘中

なんか基本をおざなりにしたまま進んでしまった感がある…
とりあえずbinsearch()を使える形にしてみた。
array[]の要素とsを、自分で入力した値でできるように修正しないといけないね。

// from K&R p.58 (Japansese p.70)


#include <stdio.h>

int binsearch(int x, int v[], int n);

int main()
{
	int s, array[6] = {12, 25, 33, 46, 58}, i, num;
	s = 22;
	i = 0;

	printf("s = %d\n", s);		// print s

	printf("array[] = ");		// print array for sure
	for(i = 0; i < 5; i++)
		printf("%d ", array[i]);
	printf("\n\n");

	num = binsearch(s, array, i);

	if (num != -1)				//check if s is found or not
		printf("s is found at %d", num + 1);
	else 
		printf("s is not found in array[]");

	return 0;
}

/* binsearch: find x in v[0] <= v[1] <= ... <v[n-1] */

int binsearch(int x, int v[], int n)
{
	int low, high, mid;

	low = 0;
	high = n - 1;
	while (low <= high) {
		mid = (low + high) / 2;
		if (x < v[mid])				// focuses on the lower half
			high = mid -1;
		else if (x > v[mid])		// on the upper half
			low = mid+1;
		else					// found match
			return mid;
	}
	return -1;					// no match
}

実行結果

s = 25
array[] = 12 25 33 46 58

s is found at 2

このsの値をいじくるのをファイル書き換え→再コンパイルってやってるのが恥ずかしいな。
getchar云々がいまだに頭に染み付いてないので本見ないとできない

s = 22
array[] = 12 25 33 46 58

s is not found

今回やりたいことは、課題(Excercise)の3.1なのでそこまでどうにかたどり着けるようがんばる。

65日目 FizzBuzzと文字列ポインタ

いまさらFizzBuzzなど - hogelogの日記 - ハチロク世代


ずいぶん昔に*1id:hogelogにif分岐無しでFizzBuzz教えてもらったのだが、その時はなぜそう書けるのかわかってなかった。

じゃんけんゲームを改変したときのashitanoのアドバイスを思い出したので、ようやく文字列ポインタを理解することにした。

まずね、!2が0になることにおどろいた。

#include <stdio.h>

int main()
{
	printf("!2: %d", !1);
	return 0;
}

これがフラグってやつか、とはじめて気付いた。いや、まだ違うかもだけど。

#include <stdio.h>
#define NUM 10

int main()
{
	int i;

	for(i = 1; i < NUM+1; i++)						
		printf("%2d: %d\n", i, !(i%3));		//3で割れるフラグ
	return 0;
}

フラグは0,1だけじゃなくてもいい。(4進なら4通りの分岐が表せる)

#include <stdio.h>
#define NUM 20

int main()
{
	int i;

	for(i = 1; i < NUM+1; i++)						
		printf("%2d: %d\n", i, !(i%3)+!(i%5)*2);	// 0,1,2,3の場合分け(3 = 1 + 2)

	return 0;
}

そしたら数字とFizz, Buzz, FizzBuzzに当てはめるだけじゃん…

と思ったがprintfでの数字表示がちょっと面倒だった。とりあえず0を表示。

#include <stdio.h>
#define NUM 20

int main()
{
	int i;
	char *str[]={"0", "Fizz", "Buzz", "FizzBuzz"};	//「文字列の配列を表すポインタ」

	for(i = 1; i < NUM+1; i++)
		printf("%2d: %s\n", i, str[!(i%3)+!(i%5)*2]);

	return 0;
}

たどりついたのはこんなところ。ほとんどコピぺですが。

#include <stdio.h>
#define NUM 20

int main()
{
	int i;
	char *str[]={"%d\n", "Fizz\n", "Buzz\n", "FizzBuzz\n"};

	for(i = 1; i < NUM+1; i++)
		printf(str[!(i%3)+!(i%5)*2], i);
	//何番目かが表示できなくなって悲しい ってか""いらんのかprintf

return 0;
}

文字列配列の中に%d入れても、printfで読み込んでくれるってのが裏技的だな。
もちょっと追記する。

*1:約二ヶ月前だった

48日目 K&RのEcercise2-5 (「・ω・)「

ごめんなさい。アンサーブック見ました。
ループをどこで止めるのかわかんなかった。そうだよねヌル文字だよねあたりまえだよねorz
もったいないことしたなぁ もっと考える時間確保しとけばよかった

続きを読む

45日目 getcharの基本に戻る

K&RのExcersise1-8やろうと思ったらgetchar()も忘れていた。
まずは単語カウント。
単純にカウントしたいならスペース+1じゃないかと考えた。

#include <stdio.h>
main()
{
	int c, ws;

	ws = 0;
	printf("Please type a sentence.\n\n");
	while ((c = getchar()) != '\n')
		if (c == ' ')
			++ws;
	printf("There is %d words.", ws+1);
}

実行結果

Please type a sentence.

Hello, world!
There is 2 words.

でもよく考えたら、

Please type a sentence.

Hello,   world!
There is 4 words.

こういう結果もありうる。これはいかん。というわけでp.20ではstateなる変数が導入されます。

#include <stdio.h>
main()
{
	int c, wc, state;

	wc = 0;
	state = 0;
	printf("Please type a sentence.\n\n");
	while ((c = getchar()) != '\n')
		if (c == ' ')
			state = 0;
		else if (state == 0) {
			state = 1;
			++wc;
		}
		printf("There is %d words.", wc);
}

実行結果

Please type a sentence.

Hello, world!
There is 2 words.
Please type a sentence.

Hello,   world!
There is 2 words.

はい。スペースがいくつあっても大丈夫ですね。

#define IN 1
#define OUT 0

としてstate==の右辺を書き換えてあげればより見やすいという備忘録でした。

44日目 5分以内に九九の表を出力しなさい

5分でできる頭の体操。初心者向け。
九九の表をつくってみよう。
g:generation1986:id:oldfishはwhileとかでやるといいよ!

#include <stdio.h>

main()
{
	int i, j;
	for(i = 0; i < 9; i++) { 
		for(j = 0; j < 9; j++) {
			printf("%2d\t", (i+1)*(j+1));
		}
		printf("\n");
	}
	return 0;
}
実行結果
 1       2       3       4       5       6       7       8       9
 2       4       6       8      10      12      14      16      18
 3       6       9      12      15      18      21      24      27
 4       8      12      16      20      24      28      32      36
 5      10      15      20      25      30      35      40      45
 6      12      18      24      30      36      42      48      54
 7      14      21      28      35      42      49      56      63
 8      16      24      32      40      48      56      64      72
 9      18      27      36      45      54      63      72      81

あかん。もっと難しいことやんなきゃ。
例えば配列だとこうなる。

#include <stdio.h>

main()
{
	int i, j, kuku[9][9];
	for(i = 0; i < 9; i++) { 
		for(j = 0; j < 9; j++) {
			kuku[i][j] = (i+1)*(j+1);
			printf("%2d\t", kuku[i][j]);
		}
		printf("\n");
	}
	return 0;
}

せっかく配列を使ってみたのでもっと違うことできないか。
パスカルの三角形とか。

#include <stdio.h>

main()
{
	int i, j, pasc[4][4];
	pasc[0][0] = pasc[0][1] = pasc[1][0] = pasc[0][2] = pasc[2][0] = pasc[0][3] = pasc[3][0] = 1;
	for(i = 1; i < 4; i++) { 
		for(j = 1; j < 4; j++) {
			pasc[i][j] = pasc[i-1][j] + pasc[i][j-1];
			printf("%2d\t", pasc[i-1][j-1]);
		}
		printf("\n");
	}
	return 0;
}
実行結果
 1       1       1
 1       2       3
 1       3       6

初期化が汚い。
そもそも三角形じゃないし4×4領域確保して3×3しか表示できてないし、猛省。
なんかいい方法ないかなぁ。

二項定理自体を格納すればいいような気もしてきた。あとで追加するかも。

私信

こんなのどうだろう。

#include<stdio.h>

int main(void){
	int dan = 1, gyou;
	while(dan <= 9){
		gyou = 1;
		while(gyou <= 9) {
			printf("%3d", gyou * dan);
			gyou += 1;	
		}
		dan += 1;
		printf("\n");
	}
return 0;
}

switchのぐーちょきぱー表示をまとめられないだろか、とかうにうに考えてた。

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

int main(void){
	int x,y;
	srand((unsigned) time(NULL));
	
	printf("じゃん、けん…\n1.ぐー 2.ちょき 3.ぱー\n");
		scanf("%d",&y);
	
	printf("ぽん!\nあなた:");
	y = y-1;
	switch(y){  			//プレイヤの出した手を表示
		case 0:
		printf("ぐー!");
		break;

		case 1:
		printf("ちょき!");
		break;

		case 2:
		printf("ぱー!");
		break;
	}
	printf("\nCPU:");	
        x = rand() % 3;		//1~3の乱数でCPUの手を決定
	switch(x){  			
		case 0:
		printf("ぐー!\n\n");
		break;

		case 1:
		printf("ちょき!\n\n");
		break;

		case 2:
		printf("ぱー!\n\n");
		break;
	}

	if(x == y)
		printf("あいこ!");
	else if ((y+1)%3 == x%3)
		printf("かち!");
	else if ((y+2)%3 == x%3)
		printf("まけ!");
	else
		printf("1〜3の数を入力してね!");
	
return 0;
}

2008.6.7追記

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

int main(void){
	int x, y;
	char *str[]={"ぐー!", "ちょき!", "ぱー!"};	//「文字列の配列を表すポインタ」

	srand((unsigned) time(NULL));
	
	printf("じゃん、けん…\n1.ぐー 2.ちょき 3.ぱー\n");
		scanf_s("%d",&y);

	y = y-1;
	x = rand() % 3;

	printf("ぽん!\nあなた:%s", str[y]);		//プレイヤの出した手を表示
	printf("\nCPU:%s\n\n", str[x]);	

	if(x == y)
		printf("あいこ!");
	else if ((y+1)%3 == x%3)
		printf("かち!");
	else if ((y+2)%3 == x%3)
		printf("まけ!");
	else
		printf("1〜3の数を入力してね!");
	
return 0;
}