Dokusyo-nissi Bessitu 2004-06-12 φ(-_-) ■ [lang]はじめての C 与えられた文字列をポインタを用いて逆さに出力するプログラムを for文を使って 作成せよ。 できませんでした . . . おしまい。 気をとりなおして、 整数のアドレスを求めるプログラムを作成せよ。 1. /* access */ 2. #include 3. main() 4. { 5. int a; 6. int *p; 7. /* ポインタの宣言、実体はアスタリスク抜きの p */ 8. p = &a; 9. /* アドレスの安全な格納がポインタの絶対条件 */ 10. printf("address of a : %u\n", p); 11. /* %u は符号無しの整数値 */ 12. } 整数のアドレスと値を表示するプログラムを作成せよ。 1. /* access.2 */ 2. #include 3. main() 4. { 5. int a = 2; 6. int *p; 7. p = &a; 8. printf("address of a : %u\n", p); 9. printf("value of a : %d\n", *p); 10. /* この *p は間接参照演算子 */ 11. } 間接参照演算子を変更することで整数の値を変えるプログラムを作成せよ。 1. /* access.3 */ 2. #include 3. main() 4. { 5. int a = 1; 6. int *p; 7. p = &a; 8. printf("value of a : %d\n", a); 9. *p = 2; 10. printf("value of a : %d\n", a); 11. } ポインタに文字列を代入するプログラムを作成せよ。 1. /* string */ 2. #include 3. main() 4. { 5. char *p; 6. /* 文字型のポインタの宣言 */ 7. p = "abcde"; 8. printf("address of p : %u\n", p); 9. printf("value of p : %s\n", p); 10. /* 間接参照演算子 *p は使わない */ 11. } 配列を使用して文字列を代入するプログラムを作成せよ。 1. /* string.2 */ 2. #include 3. main() 4. { 5. char s[] = "abcde"; 6. printf("address of s : %u\n", s); 7. printf("value of s : %s\n", s); 8. } 配列を使用し for文を使って文字列を表示するプログラムを作成せよ。 1. /* calcstr */ 2. #include 3. main() 4. { 5. char s[] = "abcde"; 6. char *p; 7. for ( p = s ; *p != '\0' ; p++ ) { 8. /* '\0' は文字列の終わりをあらわす */ 9. putchar(*p) 10. /* putchar は文字を標準出力する関数 */ 11. } 12. printf("\n"); 13. } スペースをコロンに変換するのと小文字を大文字に変えるのとはこれの応用ですネ。 最初の設問でただ文字列のX番目の文字を表示するだけなら簡単なんだけど . . . 1. /* lastwd */ 2. #include 3. main() 4. { 5. char *p; 6. p = "abcde"; 7. printf("last of word : %c\n", *(p + 4)); 8. } 2004-06-18 φ(-_-) ■ [lang]はじめての C 文字の整数値を与えるとそれに対応した文字を返すプログラムを作成せよ。 1. /* itoc */ 2. #include 3. char itoc(int a); /* 関数の宣言 */ 4. main() 5. { 6. int a; 7. char c; 8. printf("%c\n", itoc(100)); /* 関数(引数) */ 9. } 10. char itoc(int a) { 11. char c; 12. c = a; 13. return c; 14. } 任意の整数値を -1.0 から 1.0 までの範囲の実数値に対応させるプログラムを作成 せよ。 1. /* rmap1 */ 2. #include 3. float rmap1(int num); 4. main() 5. { 6. int num; 7. printf("%f\n", rmap1(5)); 8. } 9. float rmap1(int num) { 10. if (num == 0) { 11. return 0.0; 12. } else if (num == 1) { 13. return 1.0; 14. } else if (num == -1) { 15. return -1.0; 16. } else { 17. return 1.0 / num; 18. } 19. } 整数値を2つ与えるとそれぞれに対応する文字を返すプログラムを作成せよ。 1. /* itoc.2 */ 2. #include 3. char test1(int i, int j); 4. main() 5. { 6. test1(97, 122); 7. } 8. char test1(int i, int j) { 9. printf("%c %c\n", i, j); 10. } ポインタを使って文字列のスペースをコロンに変更するプログラムを作成せよ。 1. /* sptoco */ 2. #include 3. void str(char *src); /* 型は void */ 4. main() 5. { 6. char s[] = "a bu da ka da bu ra"; 7. str(s); 8. printf("%s\n", s); 9. } 10. void str(char *src) { 11. char *s = src; 12. for ( ; *s != '\0' ; s++ ) { 13. if (*s == ' ') { 14. *s = ':'; 15. } 16. } 17. } グローバル変数を使って与えられた整数値を 1つ増やすプログラムを作成せよ。 1. /* glov */ 2. #include 3. int gloval = 1; /* グローバル変数 */ 4. test(void) { /* 引数は void */ 5. printf("グローバル変数 : %d\n", gloval); 6. } 7. main() 8. { 9. printf("グローバル変数 : %d\n", gloval); 10. gloval++; 11. test(); 12. } 2004-06-21 φ(-_-) ■ [lang]はじめての C ソースコード itoc を改良して任意の整数値を入力すると文字に変換するプログラ ムを作成せよ。 1. /* itoc.2 */ 2. #include 3. char itoc(int a); 4. main() 5. { 6. int a; 7. printf("99 から 122 までの間の整数値を入力して下さい a : "); 8. scanf("%d", &a); 9. printf("その整数値に対応する文字は %c ですネ。\n", itoc(a)); 10. } 11. char itoc(int a) { 12. char c; 13. c = a; 14. return c; 15. } 2004-06-22 φ(-_-) ■ [lang]はじめての C switch文を使って 1 を入力すると 1 を、 2 のときは 2 を、 3 と 4 のときは 3 を、 その他の整数の場合には すべて 4 を返し、 0 を入力すると終了するプログラムを作成せよ。 1. /* switch.1 */ 2. #include 3. int GetInput(int); 4. main() 5. { 6. int input, cont; 7. while (1) /* for文の無限ループのようなの ? */ 8. printf("適当な数字を入力して下さい。0 なら終了 -> "); 9. scanf("%d", &input); 10. cont = GetInput(input); 11. if (cont == 0) { 12. break; 13. } 14. printf("result : "%d\n", cont); 15. } 16. } 17. int GetInput(int input) { 18. int result; 19. switch(input) { 20. case 1: result = 1; break; 21. case 2: result = 2; break; 22. case 3: 23. case 4: result = 3; break; 24. case 0: result = 0; break; 25. default: result = 4; break; 26. } 27. return result; 28. } 2004-06-23 φ(-_-) ■ [lang]はじめての C 関数(ブロック)内部で静的変数を用いて整数値に 1 を加えるプログラムを作成せよ 。 分割コンパイルを使用すること。 まずモジュールを 2つ作成する。 1. /* file : part.1.c */ 2. #include 3. #include "head.1.h" 4. test() 5. { 6. static int count = 0; /* 静的変数 */ 7. int i = 0; 8. i++; 9. count++; 10. printf("i = %d, count = %d\n", i, count); 11. return; 12. } 1. /* file : part.2.c */ 2. #include 3. #include "head.1.h" 4. main() 5. { 6. test(); 7. test(); 8. test(); 9. } 次にヘッダーファイルを作成する。 1. /* file : head.1.h */ 2. int test(void); /* 今回は関数の宣言のみ */ モジュール毎にコンパイル - オブジェクトファイルを作成。 $cc -c part.1.c $cc -c part.2.c $ls -t ( part.1.o, part.2.o というオブジェクトファイルが作成されている) 最後に 2つのオブジェクトと標準ライブラリとのリンクを行う。 $cc -o finish part.1.o part.2.o これで finish という実行ファイルができるはず。 (最初にヘッダーファイルをつくったほうがよかったのかな ?) 2004-06-26 φ(-_-) ■ [lang]はじめての C 配列を使って 1 から 9 までの整数値を出力するプログラムを作成せよ。 1. /* plus1 */ 2. #include 3. main() 4. { 5. int data[10]; 6. int i; 7. for ( i = 0 ; i < 10 ; i++ ) { 8. data[i] = 1 + i; 9. printf("%d ", data[i]); 10. } 11. printf("\n"); 12. } 同じく配列を使って a から j までの文字を出力するプログラムを 2つ作成せよ。 1. /* pluswd */ 2. #include 3. main() 4. { 5. char word[10]; 6. char i; /* int i でもいいのかな ? */ 7. for ( i = 0 ; i < 10 ; i++ ) { 8. word[i] = 'a' + i; 9. printf("%c ", word[i]); 10. } 11. printf("\n"); 12. } 1. /* pluswd.2 */ 2. #include 3. main() 4. { 5. char word[10]; 6. char i; 7. for ( i = 0 ; i < 10 ; i++ ) { 8. word[i] = 'a' + i; 9. putchar(word[i]); /* putchar を使う */ 10. } 11. printf("\n"); 12. } 名前を出力するプログラムを「配列の初期化」を使用して作成せよ。 1. /* getname */ 2. #include 3. char name[] = {'a','k','a','t','y','a','n'}; /* 配列の初期化 */ 4. main() 5. { 6. int i; 7. for ( i = 0 ; i < 7 ; i++ ) { 8. putchar(name[i]); 9. } 10. printf("\n"); 11. } 2004-06-27 φ(-_-) ■ [lang]はじめての C あるファイル中の a から z までの文字の出現回数を数えるプログラムを作成せよ 。 標準入力の方法はつぎのとおり $./countwd < txt.file 1. /* countwd */ 2. #include 3. main() 4. { 5. char ch; 6. int count[26]; 7. int ii, num; 8. int a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0; 9. for ( ii = 0 ; ii < 26 ; ii++ ) { 10. count[ii] = 0; /* すべての配列に 0 を入れておく */ 11. } 12. while ((ch = getchar()) != EOF) { 13. num = ch - 'a'; 14. switch (num) { 15. case 0 : a++, count[0] = a; break; 16. case 1 : b++, count[1] = b; break; 17. case 2 : c++, count[2] = c; break; 18. case 3 : d++, count[3] = d; break; 19. case 4 : e++, count[4] = e; break; 20. case 5 : f++, count[5] = f; break; 21. case 6 : g++, count[6] = g; break; 22. case 7 : h++, count[7] = h; break; 23. case 8 : i++, count[8] = i; break; 24. case 9 : j++, count[9] = j; break; 25. case 10 : k++, count[10] = k; break; 26. case 11 : l++, count[11] = l; break; 27. case 12 : m++, count[12] = m; break; 28. case 13 : n++, count[13] = n; break; 29. case 14 : o++, count[14] = o; break; 30. case 15 : p++, count[15] = p; break; 31. case 16 : q++, count[16] = q; break; 32. case 17 : r++, count[17] = r; break; 33. case 18 : s++, count[18] = s; break; 34. case 19 : t++, count[19] = t; break; 35. case 20 : u++, count[20] = u; break; 36. case 21 : v++, count[21] = v; break; 37. case 22 : w++, count[22] = w; break; 38. case 23 : x++, count[23] = x; break; 39. case 24 : y++, count[24] = y; break; 40. case 25 : z++, count[25] = z; break; 41. } 42. } 43. printf("count of 'a' -> %d\n", count[0]); 44. printf("count of 'b' -> %d\n", count[1]); 45. printf("count of 'c' -> %d\n", count[2]); 46. printf("count of 'd' -> %d\n", count[3]); 47. printf("count of 'e' -> %d\n", count[4]); 48. printf("count of 'f' -> %d\n", count[5]); 49. printf("count of 'g' -> %d\n", count[6]); 50. printf("count of 'h' -> %d\n", count[7]); 51. printf("count of 'i' -> %d\n", count[8]); 52. printf("count of 'j' -> %d\n", count[9]); 53. printf("count of 'k' -> %d\n", count[10]); 54. printf("count of 'l' -> %d\n", count[11]); 55. printf("count of 'm' -> %d\n", count[12]); 56. printf("count of 'n' -> %d\n", count[13]); 57. printf("count of 'o' -> %d\n", count[14]); 58. printf("count of 'p' -> %d\n", count[15]); 59. printf("count of 'q' -> %d\n", count[16]); 60. printf("count of 'r' -> %d\n", count[17]); 61. printf("count of 's' -> %d\n", count[18]); 62. printf("count of 't' -> %d\n", count[19]); 63. printf("count of 'u' -> %d\n", count[20]); 64. printf("count of 'v' -> %d\n", count[21]); 65. printf("count of 'w' -> %d\n", count[22]); 66. printf("count of 'x' -> %d\n", count[23]); 67. printf("count of 'y' -> %d\n", count[24]); 68. printf("count of 'z' -> %d\n", count[25]); 69. } (変数の数をもっと減らせる方法はないんだろうか ?) 2004-06-30 φ(-_-) ■ [lang]はじめての C 文字型のアドレスを 3つ保持する配列を使って文章を出力するプログラムを作成せ よ。 1. /* pastr */ 2. #include 3. main() 4. { 5. char *pastr[3]; 6. pastr[0] = "This is"; 7. pastr[1] = "That is"; 8. pastr[2] = "there are"; 9. printf("%s a pen.\n", *pastr); 10. printf("%s a mirror.\n", *(pastr+1)); 11. printf("%s two tables in the room.\n", *(pastr+2)); 12. } putchar を使って文字列を順次出力するプログラムを作成せよ。 1. /* outptarry */ 2. #include 3. main() 4. { 5. char str[] = "aburakadabura"; 6. int i = 0; 7. while (str[i] != '\0') { 8. putchar(str[i]); 9. i++; 10. } 11. printf("\n"); 12. } (追記 上のプログラムは 6月12日に書いたコード calcstr に少し似ている) 文字列へのポインタ配列を利用して 3つの文章をランダムに 20行出力するプログラ ムを作成せよ。 1. /* randarray */ 2. #include 3. #include 4. main() 5. { 6. char *str[3]; 7. int seed, i, j; 8. str[0] = "ダメダメ (;_;) !"; 9. str[1] = "トノ、御無体な . ."; 10. str[2] = "office タン助けて !"; 11. printf("Input seed : "); 12. scanf("%d", &seed); 13. srand(seed); 14. i = 0; 15. while (i < 20) { 16. j = rand() % 3; 17. printf("%s\n", str[j]); 18. i++; 19. } 20. } (乱数をつくる関数 srand()と rand() はヘッダーファイルの が必要なはず . . . だけど、なくても上のプログラムが動いた ! ←なぜだかワカラナイヨ) 2004-07-01 φ(-_-) ■ [lang]はじめての C ポインタ配列に 5人の人名を記載してそのうち文字 'o'を含む名前のみを表示する プログラムを作成せよ。 1. /* searchwd */ 2. main() 3. { 4. char *name[5]; 5. char *p; 6. int i; 7. name[0] = "kitayama"; 8. name[1] = "okada"; 9. name[2] = "nisio"; 10. name[3] = "okamoto"; 11. name[4] = "catharine"; 12. for ( i = 0 ; i < 5 ; i++ ) { 13. p = name[i]; 14. while (*p != '\0') { 15. if (*p == 'o') { 16. printf("%s\n", name[i]); 17. break; 18. } 19. p++; 20. } 21. } 22. } 2004-07-06 φ(-_-) ■ [lang]はじめての C 構造体を使って前期、後期のテストの平均を求めるプログラムを作成せよ。 1. /* siken */ 2. #include 3. struct record { /* 構造体の宣言 */ 4. int num; 5. int prev; 6. int later; 7. int full; 8. } s; /* 構造体の変数 */ 9. main() 10. { 11. struct record s; 12. s.num = 100; 13. s.prev = 59; 14. s.later = 74; 15. s.full = (s.prev + s.later) / 2.0; 16. printf("学生番号[%d] : 通年成績 %d 点\n", s.num, s.full); 17. } 座標系上の点を格納する構造体を宣言し初期化して点 p1 に (3, 5) を代入、さら に点 p2 に再代入するプログラムを作成せよ。 1. /* init */ 2. #include 3. struct point { 4. float x; 5. float y; 6. }; 7. struct point init(void) { /*変数を初期化する関数 */ 8. struct point p; 9. p.x = 0.0; 10. p.y = 0.0; 11. return p; 12. } 13. main() 14. { 15. struct point p1, p2; /* p1, p2 は変数 */ 16. p1 = init(); 17. p2 = init(); 18. p1.x = 3.0, p1.y = 5.0; 19. p2 = p1; 20. printf("p2 = (%f, %f)\n", p2.x, p2.y); 21. } 名前、入学年度、番号、学科、組を格納する構造体を宣言、初期化してディスプレ イに表示するプログラムを作成せよ。 1. /* gakusei */ 2. #include 3. struct student { 4. char name[30]; 5. int year; 6. int num; 7. char cource[30]; 8. int class; 9. }; 10. struct student s = { "elizabeth", 2004, 1, "c_lang", 1 }; /* 初期化 */ 11. main() 12. { 13. printf("name : %s\n", s.name); 14. printf("entrance year : %d\n", s.year); 15. printf("number : %d\n", s.num); 16. printf("cource : %s\n", s.cource); 17. printf("class : %d\n", s.class); 18. } 上のプログラムをキーボードから入力できるように改造せよ。関数を使用すること 。 1. /* gakusei.2 */ 2. #include 3. struct student { 4. char name[30]; 5. int year; 6. int num; 7. char cource[30]; 8. int class; 9. } 10. struct student s; 11. struct student func1(void); /* 関数の宣言 */ 12. main() 13. { 14. func1(); 15. printf("\n"); 16. printf("あなたの名前 : %s\n", s.name); 17. printf("入学年度 : %d\n", s.year); 18. printf("学生番号 : %d\n", s.num); 19. printf("専攻科目 : %s\n", s.cource); 20. printf("所属クラス : %d\n", s.class); 21. } 22. struct student func1(void) { /* 関数 */ 23. printf("Input your name : "); 24. scanf("%s", s.name); 25. printf("Input entrance year : "); 26. scanf("%d", &s.year); 27. printf("Input your number : "); 28. scanf("%d", &s.year); 29. printf("Input your cource : "); 30. scanf("%s", s.cource); 31. printf("Input your class : "); 32. scanf("%d", &s.class); 33. } 2004-07-08 φ(-_-) ■ [lang]はじめての C 構造体へのポインタを使って鉛筆の色と太さを表示するプログラムを作成せよ。 1. /* pencil */ 2. #include 3. struct Pen { 4. char color; 5. int diam; 6. }; 7. void init(struct Pen *); 8. main() 9. { 10. struct Pen pen, *ppen = &pen; 11. init(&pen) /* &pen は省略できない */ 12. printf("color : %c\n", ppen->color); 13. printf("diameter : %d\n", ppen->diam); 14. } 15. void init(struct Pen *ppen) { 16. ppen->color = 'b'; 17. ppen->diam = 5; 18. } 上のコードで構造体の中にポインタが含まれている場合のプログラムを作成せよ。 1. /* pencil.2 */ 2. #include 3. struct Pen { 4. char *color; /* メンバーがポインタ */ 5. int diam; 6. } 7. void init(struct Pen *); 8. main() 9. { 10. struct Pen pen, *ppen = &pen; 11. init(&pen); 12. printf("color : %s\n", ppen->color); 13. printf("diameter : %d\n", ppen->diam); 14. } 15. void init(struct Pen *ppen) { 16. ppen->color = "black"; 17. ppen->diam = 5; 18. } さらにキーボードから入力できるようにプログラムを改造せよ。 1. /* pencil.3 */ 2. #include 3. struct Pen { 4. char color[20]; /* 配列を使う */ 5. int diam; 6. }; 7. void init(struct Pen *); 8. main() 9. { 10. struct Pen pen, *ppen = &pen; 11. init(&pen); 12. printf("\n"); 13. printf("color : %s\n", ppen->color); 14. printf("diameter : %d\n", ppen->diam); 15. } 16. void init(struct Pen *ppen) { 17. printf("Input color of pencil : "); 18. scanf("%s", ppen->color); 19. printf("Input diam. of pencil : "); 20. scanf("%d", &(ppen->diam)); 21. } 2004-07-10 φ(-_-) ■ [lang]はじめての C テストの結果を記録したリストから標準入力して名前と各点数および平均点をディ スプレイに表示するプログラムを作成せよ。 sscanf を使用すること。 テキストのとおりにコードを作成するとコンパイルはできるけど ・ gets みたいな dangerous な関数は使うな ! と警告をうけてしまう。今回は sscanf なしでプログラムを組み立てるか。 まずはリストの作成。 1. kitayama 70 42 2. okada 65 51 3. nisio 32 46 4. okamoto 82 58 5. catharine 75 49 ファイル名は test.list(↑各先頭のナンバーは実際にはナシ)。 1. /* siken */ 2. #include 3. #define MAX 5 /* マクロ ? まだテキストにはでてない */ 4. struct Test { 5. char name[30]; 6. int prev; 7. int later; 8. int ave; 9. }; 10. main() 11. { 12. struct Test s[100]; /* 構造体の配列 */ 13. int i, j; 14. for ( i = 0 ; i < MAX ; i++ ) { 15. scanf("%s %d %d", s[i].name, &s[i].prev, &s[i].later); 16. s[i].ave = (s[i].prev + s[i].later) / 2; 17. } 18. for ( j = 0 ; j < MAX ; j++ ) { 19. printf("%s %d %d %d\n", s[j].name, s[j].prev, s[j].later, s[j].ave); 20. } 21. } (標準入力は→ $./siken < test.list) 座標系上の直線 1 のそれぞれの端点は a(0, 0), b(3, 5) である。 構造体を使用してディスプレイ上に直線 1 の位置を表示するプログラムを作成せよ 。 1. /* line */ 2. #include 3. struct Point { 4. float x; 5. float y; 6. }; 7. struct Line { 8. int no; 9. struct Point a, b; 10. }; 11. main() 12. { 13. struct Line line; 14. line.no = 1; 15. line.a.x = 0.0; 16. line.a.y = 0.0; 17. line.b.x = 3.0; 18. line.b.y = 5.0; 19. printf("line name : %d\n", line.no); 20. printf("point a : (%f, %f)\n", line.a.x, line.a.y); 21. printf("point b : (%f, %f)\n", line.b.x, line.b.y); 22. } 関数を使って上のコードを改造せよ。 1. /* line.2 */ 2. #include 3. struct Point { 4. float x; 5. float y; 6. }; 7. struct Line { 8. int no; 9. struct Point a, b; 10. }; 11. struct Line func1(void); 12. main() 13. { 14. struct Line line; 15. line = func1(); 16. printf("line name : %d\n", line.no); 17. printf("point a : (%f, %f)\n", line.a.x, line.a.y); 18. printf("point b : (%f, %f)\n", line.b.x, line.b.y); 19. } 20. struct Line func1(void) { 21. struct Line line; 22. line.no = 1; 23. line.a.x = 0.0; 24. line.a.y = 0.0; 25. line.b.x = 3.0; 26. line.b.y = 5.0; 27. return line; 28. } 2004-07-11 φ(-_-) ■ [lang]はじめての C コード line.2 で関数にポインタを使うようプログラムを改造せよ。 1. /* line.3 */ 2. #include 3. struct Point { 4. float x; 5. float y; 6. }; 7. struct Line { 8. struct Point a, b; 9. }; 10. struct Line func1(struct Line *); 11. main() 12. { 13. struct Line line, *pline; 14. pline = &line; 15. func1(&line); 16. printf("point a : (%f, %f)\n", pline->a.x, pline->a.y); 17. printf("point b : (%f, %f)\n", pline->b.x, pline->b.y); 18. } 19. struct Line func1(struct Line *pline) { 20. struct Line line; 21. pline->a.x = 0.0; 22. pline->a.y = 0.0; 23. pline->b.x = 3.0; 24. pline->b.y = 5.0; 25. return line; 26. } (座標系上の三角形の面積を求めるプログラムは↑の応用だろうけどちょっとヤヤコシソ ー . . .) 2004-07-13 φ(-_-) ■ [lang]はじめての C 3つの頂点の座標が (1.0, 1.0), (5.0, 3.0), (4.0, 2.0) の位置にある三角形の面積を求めるプログラムを作成せよ。 1. /* sankaku */ 2. #include 3. struct Point { 4. float x; 5. float y; 6. }; 7. struct Triangle { 8. struct Point a, b, c; 9. }; 10. struct Triangle tri = {{1.0,1.0},{5.0,3.0},{4.0,2.0}}; 11. float func1(struct Triangle *); /* 関数の返り値は float 型 */ 12. main() 13. { 14. struct Triangle *ptri = &tri; 15. float s; 16. s = func1(&tri); 17. printf("area of triangle : %f\n", s); 18. } 19. float func1(struct Triangle *ptri) { 20. float s; 21. float x1, x2, x3, y1, y2, y3; 22. x1 = ptri->a.x; 23. x2 = ptri->b.x; 24. x3 = ptri->c.x; 25. y1 = ptri->a.y; 26. y2 = ptri->b.y; 27. y3 = ptri->c.y; 28. if ((x3 - x1) * (y2 - y1) - (x2 - x1) * (y3 - y1) > 0) { 29. s = ((x3 - x1) * (y2 - y1) - (x2 - x1) * (y3 - y1)) / 2; 30. } else { 31. s = ((x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)) / 2; 32. } 33. return s; 34. } 2004-07-17 φ(-_-) ■ [lang]はじめての C 各変数の型のメモリサイズを表示するプログラムを作成せよ。 1. /* ookisa */ 2. #include 3. main() 4. { 5. printf("char %d\n", sizeof(char)); 6. printf("int %d\n", sizeof(int)); 7. printf("float %d\n", sizeof(float)); 8. printf("char * %d\n", sizeof (char *)); 9. } 座標系上の点と線をあらわす構造体および配列のメモリサイズをそれぞれ表示する プログラムを作成せよ。 1. /* ookisa.2 */ 2. #include 3. main 4. { 5. char buf[512]; 6. struct Point { 7. float x; 8. float y; 9. }; 10. struct Line { 11. struct Point a, b; 12. }; 13. printf("buf %d\n", sizeof(buf)); 14. printf("struct Point %d\n", sizeof(struct Point)); 15. printf("struct Line %d\n", sizeof(struct Line)); 16. } 標準入力したファイルをディスプレイに表示するプログラムを作成せよ。 関数 malloc() を使用すること。 関数 gets() を使うよりほかないか . . . 1. /* yomikomi */ 2. #include 3. #include /* 関数 malloc() に必要 */ 4. #include /* 関数 strlen() に必要 */ 5. main() 6. { 7. char *s, buf[512]; 8. int i; 9. while (gets(buf) != NULL) { /*読み込む文字列がなくなるまで */ 10. s = (char *)malloc( strlen(buf) + 1 ); 11. /* strlen() : 文字列の長さを数える関数 ('\0'分、1つ追加しておく) */ 12. /* malloc() : メモリ割り当て関数 */ 13. /* (char *) : 関数 malloc() のキャスト (返り値は文字変数のポインタ) */ 14. for ( i = 0 ; buf[i] != '\0' ; i++ ) { 15. s[i] = buf[i]; 16. /* buf の文字列を確保されたメモリ領域に移す */ 17. } 18. s[i] = '\0'; /* 列の最後は '\0' */ 19. printf("%s\n", s); 20. } 21. } 上のプログラムをポインタを使って改造せよ。 1. /* yomikomi.2 */ 2. #include 3. #include 4. #include 5. main() 6. { 7. char *s, *ps, *pd, buf[512]; 8. /* ps : 文字列 buf のポインタ */ 9. /* pd : メモリ領域 s のポインタ */ 10. while (gets(buf) != NULL) { 11. ps = buf; 12. pd = s = (char *)malloc( strlen(buf) + 1 ); 13. for ( ; ps != '\0' ; ) { 14. *pd++ = *ps++; /* メモリ領域に文字列を移す */ 15. } 16. *pd = '\0'; 17. printf("%s\n", s); 18. } 19. } さらに関数 strcpy() を使用してプログラムを改良せよ。 1. /* yomikomi.3 */ 2. #include 3. #include 4. #include 5. main() 6. { 7. char *s, buf[512]; 8. while (gets(buf) != NULL) { 9. s = (char *)malloc( strlen(buf) + 1 ); 10. strcpy(s, buf); 11. /* strcpy() : 文字列をメモリ領域にコピーする */ 12. /* 引数はコピー先のメモリ領域のポインタともとの文字列のアドレス */ 13. printf("%s\n", s); 14. } 15. } 2004-08-21 φ(-_-) ■ [lang]はじめての C 線形リストを用いて入力したデータを順に出力するプログラムを作成せよ。 できませんでした . . . おしまい。 これがうわさの「アルゴリズムとデータ構造」ですか ? 今回だけは宮寺さんのページから課題を借りることにしました。宮寺さんに感謝。 線形リストを用いて入力したデータを記憶し先頭から順に出力するプログラムを作 成せよ。 (入力の終了は ctrl + 'd') 1. /* mklist.1 */ 2. #include 3. struct List { 4. int data; 5. struct List *next; 6. }; 7. struct List *get_mem(void); 8. void show_list(struct List *); 9. main() 10. { 11. struct List *start, *curr, *prev; 12. int n; /* 2回目以後入力するデータはすべて n で統一 */ 13. /* * * 初期設定をおこなう * * */ 14. start = get_mem(); /* 最初のノードのメモリを確保 */ 15. scanf("%d", &start->data); /* 最初のノードにデータを格納 */ 16. prev = start; 17. start->next = NULL; 18. /* * * データを格納してリストをつなぐ * * */ 19. while (scanf("%d", &n) != EOF) { 20. curr = get_mem(); 21. curr->data = n; 22. prev->next = curr; /* リストをつなぐ */ 23. prev = curr; /* 一つ前のノードを記憶 */ 24. } 25. curr->next = NULL; /* リストの最後は NIL */ 26. /* * * データをリスト順に出力 * * */ 27. show_list(start); 28. printf("\n"); 29. } 30. struct List *get_mem(void) { /* ノードの領域を確保 */ 31. struct List *pm; 32. pm = (struct List *)malloc(sizeof(struct List)); 33. return pm; 34. } 35. void show_list(struct List *pd) { /* リストの順に格納されたデータを出力 */ 36. while (pd != NULL) { 37. printf("%d ", pd->data); 38. pd = pd->next; 39. } 40. } 上のコードの初期設定の部分を省略したプログラムを作成せよ。 1. /* mklist.2 */ 2. #include 3. struct List { 4. int data; 5. struct List *next; 6. }; 7. struct List *get_mem(void); 8. void show_list(struct List *); 9. main() 10. { 11. struct List *start, *curr, *prev; 12. int n; /* 入力したデータはすべて n で統一 */ 13. prev = NULL /* ノードの中身は NIL */ 14. while (scanf("%d", &n) != EOF) { 15. curr = get_mem(); /* ノードの領域を確保 */ 16. curr->data = n; /* ここでデータを格納 */ 17. if (prev == NULL) { 18. start = curr; /* はじめに最初のノードへ */ 19. } else { 20. prev->next = curr; /* リストをつなげる */ 21. } 22. prev = curr; /* 一つ前のノードを記憶 */ 23. } 24. curr->next = NULL; 25. show_list(start); 26. printf("\n"); 27. } 28. struct List *get_mem(void) { 29. struct List *pm; 30. pm = (struct List *)malloc(sizeof(struct List)); 31. return pm; 32. } 33. void show_list(struct List *pd) { 34. while (pd != NULL) { 35. printf("%d", pd->data); 36. pd = pd->next; 37. } 38. } 逆順につながった線形リストを作成し入力終了後先頭から順に出力するプログラム を作成せよ。 1. /* mklist.3 */ 2. #include 3. struct List { 4. int data; 5. struct List *next; 6. }; 7. struct List *get_mem(void); 8. void show_list(struct List *); 9. main() 10. { 11. struct List *curr, *prev; 12. int n; 13. prev = NULL; 14. while (scanf("%d", &n) != EOF) { 15. curr = get_mem(); 16. curr->data = n; 17. curr->next = prev; /* つねに新しいデータが先頭に */ 18. prev = curr; 19. } 20. show_list(curr); 21. printf("\n"); 22. } 23. struct List *get_mem(void) { 24. struct List *pm; 25. pm = (struct List *)malloc(sizeof(struct List)); 26. return pm; 27. } 28. void show_list(struct List *pd) { 29. while (pd != NULL) { 30. printf("%d", pd->data); 31. pd = pd->next; 32. } 33. } 双方向リストを用いて入力したデータを記憶し先頭からと後ろからとそれぞれ順に 出力するプログラムを作成せよ。 1. /* mklist.4 */ 2. #include 3. struct List { 4. int data; 5. struct List *next; 6. struct List *back; 7. }; 8. struct List *get_mem(void); 9. void show_list(struct List *); 10. void show_list_prev(struct List *); 11. main() 12. { 13. struct List *start, *curr, *end; 14. int n; 15. start = get_mem(); 16. scanf("%d", &start->data); 17. end = start; 18. start->next = NULL; 19. start->back = NULL; 20. while (scanf("%d", &n) != EOF) { 21. curr = get_mem(); 22. curr->data = n; 23. end->next = curr; /* 両方向にリストをつなげる */ 24. curr->back = end; 25. end = curr; 26. } 27. curr->next = NULL; 28. show_list(start); 29. printf("\n"); 30. show_list_rev(end); 31. printf("\n"); 32. } 33. struct List *get_mem(void) { 34. struct List *pm; 35. pm = (struct List *)malloc(sizeof(struct List)); 36. return pm; 37. } 38. void show_list(struct List *pd) { 39. while (pd != NULL) { 40. printf("%d", pd->data); 41. pd = pd->next; 42. } 43. } 44. void show_list_rev(struct List *pd) { 45. while (pd != NULL) { 46. printf("%d", pd->data); 47. pd = pd->back; /* 逆方向に */ 48. } 49. } 上のコードから初期設定の部分を省略したプログラムを作成せよ。 1. /* mklist.5 */ 2. #include 3. struct List { 4. int data; 5. struct List *next; 6. struct List *back; 7. } ; 8. struct List *get_mem(void); 9. void show_list(struct List *); 10. void show_list_rev(struct List *); 11. main() 12. { 13. struct List *start, *curr, *end; 14. int n; 15. end = start = NULL; /* ノードの中身は NIL */ 16. while (scanf("%d", &n) != EOF) { 17. curr = get_mem(); 18. curr->data = n; 19. if (start == NULL) { 20. start = curr; 21. } else { 22. end->next = curr; /* リストをつなげる */ 23. curr->back = end; 24. } 25. end = curr; 26. } 27. curr->next = NULL; 28. show_list(start); 29. printf("\n"); 30. show_list_rev(end); 31. printf("\n"); 32. } 33. struct List *get_mem(void) { 34. struct List *pm; 35. pm = (struct List *)malloc(sizeof(struct List)); 36. return pm; 37. } 38. void show_list(struct List *pd) { 39. while (pd != NULL) { 40. printf("%d", pd->data); 41. pd = pd->next; 42. } 43. } 44. void show_list_prev(struct List *pd) { 45. while (pd != NULL) { 46. printf("%d", pd->data); 47. pd = pd->back; 48. } 49. } つかれました . . . text: 東京学芸大学の宮寺さんのページ 2004-08-24 φ(-_-) ■ [lang]はじめての C リストへのオブジェクトの追加、削除に関しては target の実際の用法がよくわからな い→今後の課題ですね。 あと覚えておくことは、 free 関数は malloc 関数で割り当てられたメモリの中身をクリーンにするので、プログ ラムの途中でデータを入れ替えるときに使う。 void free_list(struct List *p) { struct List *pn; while (p != NULL) { pn = p->next; free(p); p = pn; /* ポインタを一度 次につないで 解放 */ } } ↑これかな ?