[C言語]選択ソート

最小値を見つけて先頭に移動、2番目に小さい要素を見つけて2番目に移動 を繰り返していくアルゴリズム

#include 

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

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

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

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


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

	select_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

左右の比較ではなくて、先頭との比較 swap(&array[min_index], &array[i])ってところがなるほどなーって思う

[C言語]円周率

円周率の計算方法

### マチンの公式
π/4 = 4Arctan*1/5 – Arctan*1/239
これをコーディングすると

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

int main(void){

	double pi;

	pi = (4 * atan(1/5) - atan(1/239)) / 4;

	printf("%lf\n", pi);


	return 0;
}

$ ./main
0.000000
あれ?? 何故?

### 22/7、355/113、428224593349304/136308121570117

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

int main(void){

	double pi1, pi2, pi3;
	pi1 = 22.0/7.0;
	pi2 = 355.0/113.0;
	pi3 = 428224593349304.0/136308121570117.0;

	printf("%lf\n", pi1);
	printf("%lf\n", pi2);
	printf("%lf\n", pi3);


	return 0;
}

$ ./main
3.142857
3.141593
3.141593

22/7で計算すると、int型で3.000000になってしまう

### モンテカルロ法

#include 
#include 
#include 

int main(void){

	int j, jmax = 100000000;
	int Ni;
	double x,y,max,pi;

	max = (double)RAND_MAX;
	srand(time(NULL));

	for(j=0, Ni=0; j

$ ./main
3.141687

円周率、侮ってた、奥が深い

[C言語]経路探索

バックトラック: 失敗したら後戻りして別の道を選ぶ -> メモリ使用量が少ない
幅優先探索: 全ての経路を並行して探索 -> メモリ使用量が多い

隣接行列
N|ABCDEFG
A|0110000
B|1011000
C|1100100
D|0100110
E|0011001
F|0001000
G|0000100

int adjacent[N][N] {
	{0, 1, 1, 0, 0, 0, 0},
	{1, 0, 1, 1, 0, 0, 0},
	{1, 1, 0, 0, 1, 0, 0},
	{0, 1, 0, 0, 1, 1, 0},
	{0, 0, 1, 1, 0, 0, 1},
	{0, 0, 0, 1, 0, 0, 0},
	{0, 0, 0, 0, 1, 0, 0},
}

隣接リスト

enum {S, A, B, C, D, E, F, G};

int adjacent[N + 1][M] = {
	{S},
	{B, C, S},
	{A, C, D, S},
	{A, B, E, S},
	{B, E, F, S},
	{C, D, G, S},
	{D, S},
	{E, S},
};

### プログラム

#include 
#include  //  4 つのマクロが定義 bool, true, false, __bool_true_false_are_defined

#define N 7
#define M 4

enum {S, A, B, C, D, E, F, G};

int adjacent[N + 1][M] = {
	{S},
	{B, C, S},
	{A, C, D, S},
	{A, B, E, S},
	{B, E, F, S},
	{C, D, G, S},
	{D, S},
	{E, S},
};


// 経路
int path[N];
bool visited[N + 1];

// 経路の表示
void print_path(int n){
	for(int i = 0; i

$ ./main
A B C E G
A B D E G
A C B D E G
A C E G

関数のdfsのint y = adjacent[x][i];で進んでいってるってこと?
A->B->C の順番の経路だから上のロジックでも成り立っているように見えるが。。。
それとvisitedの書き方がtrue -> 再帰処理 -> falseにする意味がよくわからん

[C言語]クリップボード

クリップボードの動き
——-
1.OpenClipboard()  // 開く
2.EmptyClipboard() // 現在の確保メモリを開放
3.GlobalAlloc()、GlobalLock() // 書き込むメモリを確保
4.上記メモリに書き込む
5.GlobalUnlock()   // メモリのロックを解除
6.SetClipboardData() // メモリをクリップボードにセット
7.CloseClipboard() // 閉じる

#include <stdio.h>
#include <string.h> // strlenに使用

int main(void){
	char str[256];
	int len;

	scanf("%s", str);
	len = strlen(str);

	printf("入力した文字列は:%s\n文字数:%d\n", str, len);

	thandl = GlobalAlloc(str, len+1);

	OpenClipboard(NULL);
	EmptyClipboard();

	SetClipboardData(str, thandl);
	CloseClipboard();

	return 0;
}

$ gcc -o main main.c
main.c: In function ‘main’:
main.c:13:2: error: ‘thandl’ undeclared (first use in this function)
thandl = GlobalAlloc(str, len+1);
^~~~~~
main.c:13:2: note: each undeclared identifier is reported only once for each function it appears in
main.c:13:11: warning: implicit declaration of function ‘GlobalAlloc’ [-Wimplicit-function-declaration]
thandl = GlobalAlloc(str, len+1);
^~~~~~~~~~~
main.c:15:2: warning: implicit declaration of function ‘OpenClipboard’ [-Wimplicit-function-declaration]
OpenClipboard(NULL);
^~~~~~~~~~~~~
main.c:16:2: warning: implicit declaration of function ‘EmptyClipboard’ [-Wimplicit-function-declaration]
EmptyClipboard();
^~~~~~~~~~~~~~
main.c:18:2: warning: implicit declaration of function ‘SetClipboardData’ [-Wimplicit-function-declaration]
SetClipboardData(str, thandl);
^~~~~~~~~~~~~~~~
main.c:19:2: warning: implicit declaration of function ‘CloseClipboard’ [-Wimplicit-function-declaration]
CloseClipboard();
^~~~~~~~~~~~~~

windows.hでないと無理か。。
APIがOSによって異なることをあまり理解できていない。

[C言語]あみだくじを作りたい

C言語であみだくじを作りたい

配列0〜8に数字1〜9が入っているとする
(1, 2, 3, 4, 5, 6, 7, 8, 9)

横線が入ると、数字の値が入れ替わる
(2, 3) -> (3, 2)
(8, 9) -> (9, 8)

最終的に
(1, 3, 2, 4, 5, 6, 7, 9, 8)

図で書くとこんな感じか

これをプログラミングで書きたい

1回交換するだけなら

#include 
#include 
#include 

int main(){
	int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
	int i, num1, num2, tmp;

	srand((unsigned int)time(NULL));
	num1 = rand() % 9;
	if(num1 == 8){
		num1 = 7;
	}
	num2 = num1 + 1;

	tmp = a[num1];
	a[num1] = a[num2];
	a[num2] = tmp;
	
	
	for(i=0; i<9; i++){
		printf("%d ",a[i]);
	}
	printf("\n");

	return 0;
}

$ gcc -o main main.c
$ ./main
0 1 2 4 3 5 6 7 8
$ ./main
0 1 2 3 5 4 6 7 8

これを複数回変更したい

#include 
#include 
#include 

int main(){
	static int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
	int i, j, num1, num2, tmp;
	srand((unsigned int)time(NULL));

	for(i=0; i<3; i++){
		num1 = rand() % 9;
		if(num1 == 8){
			num1 = 7;
		}
		num2 = num1 + 1;
		printf("%d回目に変更したのは%d番目と%d番目\n", i+1, num1+1, num2+1);

		tmp = a[num1];
		a[num1] = a[num2];
		a[num2] = tmp;
	}
		
	for(j=0; j<9; j++){
		printf("%d ",a[j]);
	}
	printf("\n");

	return 0;
}

$ ./main
1回目に変更したのは3番目と4番目
2回目に変更したのは4番目と5番目
3回目に変更したのは8番目と9番目
0 1 3 4 2 5 6 8 7
$ ./main
1回目に変更したのは7番目と8番目
2回目に変更したのは6番目と7番目
3回目に変更したのは5番目と6番目
0 1 2 3 7 4 5 6 8

いいねー、3時間ぐらいかかったけど

[C言語]MIDI

MIDIとはMusical Instrument Digital Interface, 電子機器の演奏データを機器間で転送・共有するための共通規格


ん? なんだこれは?

#include 
#include 

typedef struct {   // typedefはtype definition 構造体
	char type[4];
	int size; // トラックチャンクデータのサイズ[4byte]
	char *data;
} TrackChunk;

short mergeChar7bit(char x, char y){
	short s;
	s = (unsigned char)x;
	s <<= 7;
	s = (s |(unsigned char)(y & 0x7f));
	return s;
}

int convertEndian(void *input, size_t s){
	int i;
	char *temp;

	if((temp = (char *)calloc(s, sizeof(char))) == NULL){
		perror("Error: Cannot get money for temp.");
		return 0;
	}

	for(i=0; i

$ gcc -o main main.c
main.c: In function ‘main’:
main.c:64:3: warning: implicit declaration of function ‘eperror’; did you mean ‘perror’? [-Wimplicit-function-declaration]
eperror("Error:Cannot open the file.");
^~~~~~~
perror
main.c:147:5: error: ‘jLL’ undeclared (first use in this function); did you mean ‘NULL’?
jLL;
^~~
NULL
main.c:147:5: note: each undeclared identifier is reported only once for each function it appears in
main.c:317:13: warning: too many arguments for format [-Wformat-extra-args]
printf(")=%d",c,(unsigned char)track_chunks[i].data[j]);
^~~~~~
main.c:319:12: warning: zero-length gnu_printf format string [-Wformat-zero-length]
printf("");
^~
main.c:334:15: error: ‘statu’ undeclared (first use in this function); did you mean ‘status’?
} else if((statu & 0xf0) == 0xf0){
^~~~~
status
main.c:335:5: warning: implicit declaration of function ‘swtich’ [-Wimplicit-function-declaration]
swtich(status & 0x0f){
^~~~~~
main.c:335:26: error: expected ‘;’ before ‘{’ token
swtich(status & 0x0f){
^
main.c:573:22: error: invalid suffix "O" on integer constant
switch(cnt & 0xCO){
^~~~
main.c:645:11: warning: zero-length gnu_printf format string [-Wformat-zero-length]
printf("");

..$ gcc -o main main.c
main.c: In function ‘main’:
main.c:64:3: warning: implicit declaration of function ‘eperror’; did you mean ‘perror’? [-Wimplicit-function-declaration]
eperror("Error:Cannot open the file.");
^~~~~~~
perror
main.c:147:5: error: ‘jLL’ undeclared (first use in this function); did you mean ‘NULL’?
jLL;
^~~
NULL
main.c:147:5: note: each undeclared identifier is reported only once for each function it appears in
main.c:317:13: warning: too many arguments for format [-Wformat-extra-args]
printf(")=%d",c,(unsigned char)track_chunks[i].data[j]);
^~~~~~
main.c:319:12: warning: zero-length gnu_printf format string [-Wformat-zero-length]
printf("");
^~
main.c:334:15: error: ‘statu’ undeclared (first use in this function); did you mean ‘status’?
} else if((statu & 0xf0) == 0xf0){
^~~~~
status
main.c:335:5: warning: implicit declaration of function ‘swtich’ [-Wimplicit-function-declaration]
swtich(status & 0x0f){
^~~~~~
main.c:335:26: error: expected ‘;’ before ‘{’ token
swtich(status & 0x0f){
^
main.c:573:22: error: invalid suffix "O" on integer constant
switch(cnt & 0xCO){
^~~~
main.c:645:11: warning: zero-length gnu_printf format string [-Wformat-zero-length]
printf("");

シューティングゲーム

#include "display.h"

void displayMain(){
	glClear(GL_COLOR_BUFFER_BIT);

	float test1 = 1.0f;
	int test2 = 23;

	// font test
	fontBegin();
	fontSetPosition(0.0, 100.0);
	fontSetSize(FONT_DEFAULT_SIZE * 0.25);
	fontSetWeight(1.0);
	fontSetColor(0, 0, 255);
	fontDraw("float:%f, int:%d", test1, test2);
	fontEnd();

	glutSwapBuffers();
}
#ifndef __HEADER_FONT
#define __HEADER_FONT

#define FONT_DEFAULT_SIZE (100.0f)

void fontBegin();
void fontEnd();

void fontSetPosition(float _x, float _y);
void fontSetSize(float _size);
void fontSetWeight(float _weight);
void fontSetColor(unsigined char _red, unsigned char _green, unsigned char _blue);
void fontDraw(const char *format, ...);

#endif
#include "font.h"

#include <GL/glut.h>
#include <stdio.h>
#include <stdarg.h> // 可変長引数の関数を実装

static float positionX;  // staticは静的記憶クラス
static float positionY;
static float size = FONT_DEFAULT_SIZE;
static float weight = 1.0;

void fontBegin(){
	glPushMatrix();
	glPushAttrib(GL_ALL_ATTRIB_BITS);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	GLint viewport[4];
	glGetIntegerv(GL_VIEWPORT, viewport);
	gluOrtho2D(0, viewport[2], viewport[3], 0); 

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void fontEnd(){
	glPopMatrix();
	glPopAttrib();
}

void fontSetPosition(float _x, float _y){
	positionX = _x;
	positionY = _y;
}

void fontSetSize(float _size){
	size = _size;
}

void fontSetWeight(float _weight){
	weight = _weight;
}

void fontSetColor(unsigned char _red, unsigned char _green, unsigned char _blue){
	color[0] = red;
	color[1] = green;
	color[2] = blue;
}

void fontDraw(const char *format, ...){
	va_list argList;
	va_start(argList, format);
	char str[256];
	vsprintf(str, format, argList);
	va_end(argList);

	glLineWidth(weight);
	glColor3ub(color[0], color[1], color[2]);
	glPushMatrix();

	glTranslatef(positionX, positionY + size, 0.0);
	float s = size / FONT_DEFAULT_SIZE;
	glScalef(s, -s, s);
	for(char *p = str; *p != '\0'; p++)
		glutStrokeCharacter(CLUT_STROKE_ROMAN, *p);

	glPopMatrix();
}
main: main.c game.o display.o font.o
	gcc main.c game.o display.o font.o -o main -lglut -lGLU -lGL

game.o: game.c game.h define.h display.h
	gcc -c game.c -o game.o -lglut -lGLU -lGL 

display.o: display.c display.h
	gcc -c display.c -o display.o -lglut -lGLU -lGL

font.o: font.c font.h
	gcc -c font.c -o font.o -lglut -lGLU -lGL

clean:
	rm -rf main *.o

$ make
gcc -c display.c -o display.o -lglut -lGLU -lGL
display.c: In function ‘displayMain’:
display.c:4:2: warning: implicit declaration of function ‘glClear’ [-Wimplicit-function-declaration]
glClear(GL_COLOR_BUFFER_BIT);
^~~~~~~
display.c:4:10: error: ‘GL_COLOR_BUFFER_BIT’ undeclared (first use in this function)
glClear(GL_COLOR_BUFFER_BIT);
^~~~~~~~~~~~~~~~~~~
display.c:4:10: note: each undeclared identifier is reported only once for each function it appears in
display.c:10:2: warning: implicit declaration of function ‘fontBegin’ [-Wimplicit-function-declaration]
fontBegin();
^~~~~~~~~
display.c:11:2: warning: implicit declaration of function ‘fontSetPosition’ [-Wimplicit-function-declaration]
fontSetPosition(0.0, 100.0);
^~~~~~~~~~~~~~~
display.c:12:2: warning: implicit declaration of function ‘fontSetSize’ [-Wimplicit-function-declaration]
fontSetSize(FONT_DEFAULT_SIZE * 0.25);
^~~~~~~~~~~
display.c:12:14: error: ‘FONT_DEFAULT_SIZE’ undeclared (first use in this function)
fontSetSize(FONT_DEFAULT_SIZE * 0.25);
^~~~~~~~~~~~~~~~~
display.c:13:2: warning: implicit declaration of function ‘fontSetWeight’ [-Wimplicit-function-declaration]
fontSetWeight(1.0);
^~~~~~~~~~~~~
display.c:14:2: warning: implicit declaration of function ‘fontSetColor’ [-Wimplicit-function-declaration]
fontSetColor(0, 0, 255);
^~~~~~~~~~~~
display.c:15:2: warning: implicit declaration of function ‘fontDraw’ [-Wimplicit-function-declaration]
fontDraw(“float:%f, int:%d”, test1, test2);
^~~~~~~~
display.c:16:2: warning: implicit declaration of function ‘fontEnd’ [-Wimplicit-function-declaration]
fontEnd();
^~~~~~~
display.c:18:2: warning: implicit declaration of function ‘glutSwapBuffers’ [-Wimplicit-function-declaration]
glutSwapBuffers();
^~~~~~~~~~~~~~~
GNUmakefile:8: recipe for target ‘display.o’ failed
make: *** [display.o] Error 1

何故だーーーーーー

[C言語]Makefile2

main.c // 初期化、ゲーム実行処理

#include "game.h"

int main(int argc, char *argv[]){ // コマンドライン引数 int argcは引数の個数、char *argvは引数の文字列
	gameInit(&argc, argv);

	gameRun();

	return 0;
}

game.h

#ifndef __HEADER_GAME

#define __HEADER_GAME

void gameInit(int *argc, char **argv);
void gameRun();

#endif

game.c  // glut初期化 ※glInit

#include "game.h"

#include <GL/glut.h>
#include "define.h"
#include "display.h"

void glInit(int *argc, char **argv);

void gameInit(int *argc, char **argv){
	glInit(argc, argv);
}

void gameRun(){
	glutMainLoop();
}

void glInit(int *argc, char **argv){
	glutInit(argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
	glutCreateWindow("myGame");
	glutDisplayFunc(displayMain);
}

define.h

#ifndef __HEADER_DEFINE

#define __HEADER_DEFINE

#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480

#endif

display.h

#ifndef __HEADER_DISPLAY

#define __HEADER_DISPLAY

void displayMain();

#endif

display.c  // ゲーム処理

#include "display.h"

void displayMain(){
	
}

GNUmakefile // コンパイル

main: main.c game.o display.o
	gcc main.c game.o display.o -o main -lglut -lGLU -lGL

game.o: game.c game.h define.h display.h
	gcc -c game.c -o game.o -lglut -lGLU -lGL 

display.o: display.c display.h
	gcc -c display.c -o display.o -lglut -lGLU -lGL

clean:
	rm -rf main *.o

$ make
gcc -c game.c -o game.o -lglut -lGLU -lGL
gcc -c display.c -o display.o -lglut -lGLU -lGL
gcc main.c game.o display.o -o main -lglut -lGLU -lGL

[C言語]Makefile

各ファイルとコンパイルに必要なコマンド、ファイル間の依存関係を書く

makeの種類
– Microsoft nmake (Windows)
– Borland make (Windows)
– GNU make (windows, UNIX 系)
– Solaris make (Solaris)

hello.c

#include <stdio.h>

int main(int argc, char *argv[]){
	printf("Hello C\n");
	return 0;
}

GNUmakefile

hello: hello.c
	gcc -Wall -O2 -o hello hello.c

依存関係行

hello: hello.c
	gcc -Wall -O2 -o hello hello.c print.o

hello.o: hello.c
	gcc -c hello.c

print.o: print.c
	gcc -c print.c

clean:
	rm -f hello hello.o print.o

make cleanで不要なファイルを削除する

#ifndefと#endif

機能 :識別子が定義されていないかどうかの判定
書式 :
#ifndef <識別子名>
<処理>
詳細 :<識別子名>が未定義なら<処理>を実行。<処理>が複数行にわたる場合は、処理ブロックの最後を示すために#endifを記述。

#ifndef ARRAY_H // 二重でincludeされることを防ぐ
#define ARRAY_H

複数のソースから array.hがインクルードされていたとしても、 確実に1度だけ array.hの中身を有効にすることができる

array.hをARRAY_Hと書くのはコンベンションか?
特殊な書き方のような印象