[C言語]十二支

十二支は12年周期
西暦を12で割った時に余りがないのが申(さる)

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

int main(){

	char buf[128],eto[32];
	int yy;

	printf("あなたは西暦何年生まれですか?");
	fflush(stdin);
	gets(buf);
	yy=atoi(buf);

	switch(yy % 12){
		case 0: strcpy(eto,"申(さる)");break;
		case 1: strcpy(eto,"酉(とり)");break;
		case 2: strcpy(eto,"戌(いぬ)");break;
		case 3: strcpy(eto,"亥(い)");break;
		case 4: strcpy(eto,"子(ね)");break;
		case 5: strcpy(eto,"丑(うし)");break;
		case 6: strcpy(eto,"寅(とら)");break;
		case 7: strcpy(eto,"卯(う)");break;
		case 8: strcpy(eto,"辰(たつ)");break;
		case 9: strcpy(eto,"巳(み)");break;
		case 10: strcpy(eto,"午(うま)");break;
		case 11: strcpy(eto,"未(ひつじ)");break;
	}
	printf("%s年生まれのあなたの十二支は%sです。",buf, eto);

	return 0;
}

$ ./main
あなたは西暦何年生まれですか?1990
1990年生まれのあなたの十二支は午(うま)です。

[C言語]整数型データの内部形式

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

int main(){

	char c[128], *cp;
	int a;

	printf("\n整数を入力してください:\n"); fflush(stdout); // fflushで標準入出力を即座に書き出す
	gets(c); a=atoi(c);

	cp = (char*)&a;

	printf("input data address is %p\n", &cp);

	printf("上位バイトから表示すると次のようになります。\n");
	printf("address %p: %02X\n", &cp, *cp); // %02Xは足りない部分を0で埋め、最小2桁
	printf("address %p: %02X\n", &cp+1, *(cp+1));
	printf("address %p: %02X\n", &cp+2, *(cp+2));
	printf("address %p: %02X\n", &cp+3, *(cp+3));
	return 0;
}

$ ./main

整数を入力してください:
1024
input data address is 0x7ffd473ccfd8
上位バイトから表示すると次のようになります。
address 0x7ffd473ccfd8: 00
address 0x7ffd473ccfe0: 04
address 0x7ffd473ccfe8: 00
address 0x7ffd473ccff0: 00

[C言語]Beep音

Beep音とは?
-> 電子機器が通知のために発する音

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h> // for usleep
#include <sys/io.h> // for inb(バイトデータを呼び出し), outb(バイトデータを出力)

static void beep_on(void){
	outb(inb(0x61)|3, 0x61);  // 0x61はa
}

static void beep_off(void){
	outb(inb(0x61)&0xfc, 0x61);
}


int main(int argc, char *argv[]){

	uint32_t count; // 32ビットの符号なし整数型

	if((ioperm(0x0040, 4, 1)) ||(ioperm(0x0061, 1, 1))){  //iopermはポートの入出力を許可
		perror("ioperm");
		return 1;
	} 

	count = 1193180 / 1000;
	outb(0xb6, 0x43);
	outb(count & 0xff, 0x42);
	outb((count>>8) & 0xff, 0x42);

	beep_on();
	usleep(1000000);
	beep_off();

	return 0;
}

$ ./main
ioperm: Operation not permitted

ん? 何故だ?

[C言語]バブルソート

隣と比べて、逆順なら入れ替える

#include 

void swap (int *x, int *y){
	int temp;

	temp = *x;
	*x = *y;
	*y = temp;
}

void bubble_sort(int array[], int array_size){
	int i, j;

	for(i = 0; i < array_size - 1; i++){
		for(j = array_size - 1; j >=  i + 1; j-- ){
			if(array[j] < array[j -1]) {swap(&array[j], &array[j-1]);}
		}
	}
}


int main(void){

	int array[10] = { 2, 1, 8, 5, 4, 7, 9, 0, 6, 3};
	int i;

	bubble_sort(array, 10);

	for(i = 0; i < 10; i++){
		printf("%d ", array[i]);
	}
	printf("\n");

	return 0;
}

$ ./main
0 1 2 3 4 5 6 7 8 9

二重でforループを回している時に、"j >= i + 1" として左から順番に大きい値を配列に入れていく。

[C言語]正接(tangent)

sine, cosine, tangentを日本語で、正弦、余弦、正接という
tanは45°で1, 30°で√3/3

#include 
#include 


int main(void){

	int thd;
	double th;
	FILE *fp = NULL;
	char c[128];

	fp=fopen("tangent.txt", "w");
	if(fp == NULL) return 1;
	fputs("正接表\n\n", fp);

	fputs("角度\t正接\n",fp);
	printf("\n角度\t正接\n");

	for(thd=-89; thd<90; thd+=1){
		th = thd*0.017453295;
		sprintf(c, "%3d\t%10.6f\n",thd, tan(th));
		fputs(c,fp);
		printf("%s",c);
	}
	if(fp!=NULL) fclose(fp);

	return 0;
}

$ gcc -o main main.c
/tmp/cc1hB26c.o: In function `main':
main.c:(.text+0xe1): undefined reference to `tan'

あれ? tanは特にincludeは要らないはずだが。
stackoverflowに買いてありますな。

You should add -lm to your compiler option.
Besides of that, you could also change -lpthread to -pthread.

$ gcc -o main main.c -lm
$ ./main

角度 正接
-89 -57.290686
-88 -28.636432
-87 -19.081215
-86 -14.300710
-85 -11.430080
-84 -9.514384
-83 -8.144360
-82 -7.115380
-81 -6.313760
-80 -5.671288
-79 -5.144559
-78 -4.704635
-77 -4.331480
-76 -4.010784
-75 -3.732054
-74 -3.487417
-73 -3.270855
-72 -3.077685
-71 -2.904213
-70 -2.747479
-69 -2.605090
-68 -2.475088
-67 -2.355853
-66 -2.246038
-65 -2.144508
-64 -2.050305
-63 -1.962611
-62 -1.880727
-61 -1.804048
-60 -1.732051
-59 -1.664280
-58 -1.600335
-57 -1.539865
-56 -1.482561
-55 -1.428148
-54 -1.376382
-53 -1.327045
-52 -1.279942
-51 -1.234897
-50 -1.191754
-49 -1.150369
-48 -1.110613
-47 -1.072369
-46 -1.035531
-45 -1.000000
-44 -0.965689
-43 -0.932515
-42 -0.900404
-41 -0.869287
-40 -0.839100
-39 -0.809784
-38 -0.781286
-37 -0.753554
-36 -0.726543
-35 -0.700208
-34 -0.674509
-33 -0.649408
-32 -0.624869
-31 -0.600861
-30 -0.577350
-29 -0.554309
-28 -0.531710
-27 -0.509526
-26 -0.487733
-25 -0.466308
-24 -0.445229
-23 -0.424475
-22 -0.404026
-21 -0.383864
-20 -0.363970
-19 -0.344328
-18 -0.324920
-17 -0.305731
-16 -0.286745
-15 -0.267949
-14 -0.249328
-13 -0.230868
-12 -0.212557
-11 -0.194380
-10 -0.176327
-9 -0.158384
-8 -0.140541
-7 -0.122785
-6 -0.105104
-5 -0.087489
-4 -0.069927
-3 -0.052408
-2 -0.034921
-1 -0.017455
0 0.000000
1 0.017455
2 0.034921
3 0.052408
4 0.069927
5 0.087489
6 0.105104
7 0.122785
8 0.140541
9 0.158384
10 0.176327
11 0.194380
12 0.212557
13 0.230868
14 0.249328
15 0.267949
16 0.286745
17 0.305731
18 0.324920
19 0.344328
20 0.363970
21 0.383864
22 0.404026
23 0.424475
24 0.445229
25 0.466308
26 0.487733
27 0.509526
28 0.531710
29 0.554309
30 0.577350
31 0.600861
32 0.624869
33 0.649408
34 0.674509
35 0.700208
36 0.726543
37 0.753554
38 0.781286
39 0.809784
40 0.839100
41 0.869287
42 0.900404
43 0.932515
44 0.965689
45 1.000000
46 1.035531
47 1.072369
48 1.110613
49 1.150369
50 1.191754
51 1.234897
52 1.279942
53 1.327045
54 1.376382
55 1.428148
56 1.482561
57 1.539865
58 1.600335
59 1.664280
60 1.732051
61 1.804048
62 1.880727
63 1.962611
64 2.050305
65 2.144508
66 2.246038
67 2.355853
68 2.475088
69 2.605090
70 2.747479
71 2.904213
72 3.077685
73 3.270855
74 3.487417
75 3.732054
76 4.010784
77 4.331480
78 4.704635
79 5.144559
80 5.671288
81 6.313760
82 7.115380
83 8.144360
84 9.514384
85 11.430080
86 14.300710
87 19.081215
88 28.636432
89 57.290686

[C言語]マンデルブロ集合

マンデルブロ集合
充填ジュリア集合に対する指標として提唱された集合

ジュリア集合
複素平面上のある近傍で反復関数が非正規族となる点の集合
ガストン・ジュリアの名による

#include 
#include 

#define C0r -0.743
#define C0i 0.1145
#define VS 0.003

#define NMAX 20000
#define STEP 800.0

double mandelbrot(double a, double b){
	double x = 0.0;
	double y = 0.0;
	double x1, y1;

	int n;

	for(n = 1; n <= NMAX; n++){
		x1 = x * x - y * y + a;
		y1 = 2.0 * x * y + b;
		if(x1 * x1 + y1 * y1 > 4.0) return log(n);
		x = x1;
		y = y1;
	}
	return 0;
}


int main(void){

	double a, b;

	for(a = C0r-VS; a < C0r+VS; a += 2.0*VS/STEP){
		for(b = C0i - VS; b < C0i+VS; b += 2.0*VS/STEP){
			printf("%1.14e %1.14e %1.14e\n", a, b, mandelbrot(a, b));
		}
		printf("\n");
	}
	return 0;
}

[C言語]2の冪乗

#include

int main(void){
int i, n;
int k = 1;

printf(“2を何乗しますか? ->”);
scanf(“%d”, &n);

for(i=0; i3
計算結果: 8
$ ./main
2を何乗しますか? ->4
計算結果: 16

そのまんまか

[C言語]2進数変換

– 整数iを2で割った値を配列に入れていく

#include <stdio.h>

int main(void){
	int n, i, a[32];

	printf("数を入力してください->");
	scanf("%d", &n);
	for(i=0; n>0; i++){
		a[i] = n % 2;
		n = n / 2;
	}
	while(i > 0) printf("%1d",a[--i]);
	printf("\n");

	return 0;
}

$ ./main
数を入力してください->15
1111

$ ./main
数を入力してください->6
110

変数の先頭に–演算子を書くのを前置形式という
前に置く場合は、まずiの値を減らしてから表示する

あれ、何でこれで上手く表示できるんだ??

[C言語]関数電卓

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

#define PI 3.14159265

int main(void){
	char c[128],fnc[128];
	double x=0,y,z=0;
	double rd=PI/180.0;

	printf("関数電卓\n");
	printf("sin X, cos X, tan X\n");
	printf("exp X, log X, ln X\n");
	printf("sqr X, X ^ Y\n");

	printf("数値 X:");
	gets(c); x=atof(c);
	printf("関数:");
	gets(fnc);
	if(strcmp(fnc,"^")==0){   // strcmpは文字列の比較
		printf("数値 Y:");
		gets(c); y=atof(c);
	}  
	if(strcmp(fnc,"sin")==0)
		{z=sin(x*rd);}
	else if(strcmp(fnc,"cos")==0)
		{z=cos(x*rd);}
	else if(strcmp(fnc,"tan")==0)
		{z=tan(x*rd);}
	else if(strcmp(fnc,"exp")==0)  // exp(x)とは自然対数の底eのx乗, 微分しても値が変わらない
		{z=exp(x);}
	else if(strcmp(fnc,"log")==0) // 底が10である対数
		{z=log10(x);}
	else if(strcmp(fnc,"ln")==0)  // 底がeである対数
		{z=log(x);}
	else if(strcmp(fnc,"sqr")==0)  // x の y 乗の値
		{z=sqrt(x);}
	else if(strcmp(fnc,"pow")==0)
		{z=pow(x,y);}
	else
		{printf("関数がありません。\n");}
	
	printf("答え:%4.8f\n\n",z);

	return 0;
}

v$ gcc -o main main.c
main.c: In function ‘main’:
main.c:19:2: warning: implicit declaration of function ‘gets’; did you mean ‘fgets’? [-Wimplicit-function-declaration]
gets(c); x=atof(c);
^~~~
fgets
/tmp/ccbBDDqy.o: In function `main’:
main.c:(.text+0x93): warning: the `gets’ function is dangerous and should not be used.
main.c:(.text+0x15c): undefined reference to `sin’
main.c:(.text+0x19c): undefined reference to `cos’
main.c:(.text+0x1dc): undefined reference to `tan’
main.c:(.text+0x222): undefined reference to `exp’
main.c:(.text+0x268): undefined reference to `log10′
main.c:(.text+0x2ae): undefined reference to `log’
main.c:(.text+0x2f4): undefined reference to `sqrt’
main.c:(.text+0x343): undefined reference to `pow’
collect2: error: ld returned 1 exit status
あれ??

[C言語]素因数分解

素因数分解とは自然数を素数の掛け算で表すこと
素因数分解の対象は自然数であること(0を除く)
素数とは、1とその数以外に約数を持たないこと

### 素因数分解のやり方?
対象の自然数をNとする
1. Nを2で割る
-> 2で割り切れた場合: 割り切れた値を更に2で割る
-> 2で割り切れない場合: 下に行く

2.3で割る(※2+1)
-> 3で割り切れた場合: 割り切れた値を更に3で割る
-> 3で割り切れない場合: 下に行く

3.5で割る(※2+2)
-> 5で割り切れた場合: 割り切れた値を更に5で割る
-> 5で割り切れない場合: 7 下に行く

2から始めて、これをN回繰り返す であってる??
割る数は2から3へは+1だが、3以降は+2の方が無駄な計算がなくなる
プログラムで書きたい

#include 

int main(void){
	int prime = 27; // 素因数
	int assemble[prime]; // 割り切れる数
	int i, j, k;

	j = 0;
	for(i=2; i < prime; i++){
		while(prime % i == 0){
			prime = prime / i;
			assemble[j] = i;
			j++;
		}
	}

	for(k=0; k < j; k++){
		printf("%d ", assemble[k]);
	}
	printf("\n");

	return 0;
}

素因数が27の時
$ ./main
3 3 3
上手くいってる。

素因数が21の時
$ ./main
3

あれ、何でだ。。
あ、forループでprimeが割られた数を代入するからおかしくなるんだ。
forループの変数を変えて再度計算します。

#include 

int main(void){
	int prime = 60; // 素因数
	int cal = 60;
	int assemble[prime]; // 割り切れる数
	int i, j, k;

	j = 0;
	for(i=2; i < cal; i++){
		while(prime % i == 0){
			prime = prime / i;
			assemble[j] = i;
			j++;
		}
	}

	for(k=0; k < j; k++){
		printf("%d ", assemble[k]);
	}
	printf("\n");

	return 0;
}

素因数が60の時
$ ./main
2 2 3 5

素因数が115の時
$ ./main
5 23

わお、中々素晴らしい。
forループの時に、最初だけi++として、2回目以降をi+2とするにはどう書けばいいんだろう。
1回目の割り算を切り離して書いて、2回目以降をforループで書くのだろうか。