アルゴリズムの「考え方」と「実装」の違いを理解する。基本情報技術者試験の対策にも。
| 疑似コード | C言語 |
|---|---|
| 整数型: x | int x; |
| 実数型: x | double x; |
| 文字型: c | char c; |
| x ← 10 | x = 10; |
| x を表示する | printf("%d", x); |
| x を入力する | scanf("%d", &x); |
| もし x > 0 ならば 処理 そうでなければ 処理 を実行する | if (x > 0) { 処理; } else { 処理; } |
| i を 1 から n まで 繰り返す 処理 を実行する | for (int i = 1; i <= n; i++) { 処理; } |
| 条件 の間 繰り返す 処理 を実行する | while (条件) { 処理; } |
| 整数型の配列: A[n] | int A[n]; |
| 関数 add(a, b) 戻り値: a + b | int add(int a, int b) { return a + b; } |
| x の絶対値 | abs(x) or fabs(x) |
| x の平方根 | sqrt(x) |
| A[i] と A[j] を交換する | int t=A[i]; A[i]=A[j]; A[j]=t; |
← は代入、= は等値比較(C言語の ==)。セミコロンや中括弧は不要で、インデントで構造を示します。#include <stdio.h> int main(void) { int sum = 0; for (int i = 1; i <= 10; i++) { sum = sum + i; } printf("%d\n", sum); // 55 return 0; }
#include <stdio.h> int main(void) { int x; scanf("%d", &x); if (x > 0) { printf("正\n"); } else if (x == 0) { // 疑似コードの = はC言語では == printf("零\n"); } else { printf("負\n"); } return 0; }
#include <stdio.h> int main(void) { int A[] = {3, 8, 15, 22, 7}; int count = 0; for (int i = 0; i <= 4; i++) { if (A[i] % 2 == 0) { count++; } } printf("偶数の個数: %d\n", count); // 2 return 0; }
#include <stdio.h> int main(void) { int n = 5; while (n > 0) { printf("%d\n", n); n--; } printf("発射!\n"); return 0; }
#include <stdio.h> int max(int a, int b) { if (a > b) return a; else return b; } int main(void) { printf("%d\n", max(7, 12)); // 12 return 0; }
int find_max(int A[], int n) { int max = A[0]; for (int i = 1; i < n; i++) { if (A[i] > max) { max = A[i]; } } return max; }
i < n(0始まりなので)。配列を関数に渡すとき、サイズも引数で渡す必要がある。int search(int A[], int n, int key) { for (int i = 0; i < n; i++) { if (A[i] == key) { // ← 疑似コードの = はC言語で == return i; } } return -1; }
void bubbleSort(int A[], int n) { for (int i = 0; i < n - 1; i++) { for (int j = n - 1; j > i; j--) { // 降順ループ if (A[j-1] > A[j]) { int tmp = A[j-1]; // 交換には一時変数が必要 A[j-1] = A[j]; A[j] = tmp; } } } }
j--。int gcd(int a, int b) { while (b != 0) { int temp = b; b = a % b; a = temp; } return a; }
int binarySearch(int A[], int n, int key) { int lo = 0, hi = n - 1; while (lo <= hi) { int mid = (lo + hi) / 2; // ÷ はC言語では /(整数除算) if (A[mid] == key) return mid; else if (A[mid] < key) lo = mid + 1; else hi = mid - 1; } return -1; }
int factorial(int n) { if (n <= 1) return 1; return n * factorial(n - 1); }
#include <stdio.h> void addTen(int *px) { // 「アドレス」→ ポインタ引数 *px = *px + 10; // 「アドレスが指す値」→ *px } int main(void) { int a = 5; addTen(&a); // 「aのアドレス」→ &a printf("%d\n", a); // 15 return 0; }
&(アドレス取得)と *(間接参照)で表現。これがポインタの本質。#include <stdio.h> #include <math.h> struct Point { double x, y; }; double distance(struct Point p1, struct Point p2) { double dx = p2.x - p1.x; double dy = p2.y - p1.y; return sqrt(dx*dx + dy*dy); } int main(void) { struct Point a = {0.0, 0.0}; struct Point b = {3.0, 4.0}; printf("%.1f\n", distance(a, b)); // 5.0 return 0; }
void swap(int *a, int *b) { int t = *a; *a = *b; *b = t; } void quickSort(int A[], int lo, int hi) { if (lo >= hi) return; int pivot = A[hi]; int i = lo; for (int j = lo; j < hi; j++) { if (A[j] < pivot) { swap(&A[i], &A[j]); i++; } } swap(&A[i], &A[hi]); quickSort(A, lo, i - 1); quickSort(A, i + 1, hi); }
return;。#include <math.h> double f(double x) { return x*x - 2; } double df(double x) { return 2*x; } double newton(double x0, double eps) { double x = x0; while (1) { // 「繰り返す」→ 無限ループ double x_new = x - f(x) / df(x); if (fabs(x_new - x) < eps) // |...| → fabs() return x_new; x = x_new; } }
while(1)。「|x|」(絶対値)は fabs(x)。関数を引数に渡す疑似コードは、C言語では関数ポインタになるが、初心者向けにグローバル関数として実装するのが簡単。| 疑似コード | C言語での落とし穴 |
|---|---|
| x = y (比較) | x == y (= だと代入になる!) |
| A[i] と A[j] を交換する | 一時変数 tmp が必要(1行では書けない) |
| x の平方根 | sqrt(x) (math.h の include が必要) |
| 繰り返す(条件なし) | while(1) + break で脱出 |
| i を 1 から n まで | for(i=1; i<=n; i++) (0始まりの配列と混同注意) |
| 関数(配列, サイズ) | 配列のサイズも引数で渡す(Cには配列長の取得方法がない) |
| アドレスで渡す | ポインタ引数 int *px と & で渡す |
| ÷(整数の割り算) | /(intどうしなら自動的に切り捨て) |