PythonからC言語のプログラムを実行します。
1. 基本文法と入出力
項目 | 内容例 | Cコード例 |
---|---|---|
main() の構造 |
int main(void) |
printf("Hello, world!\n"); |
printf とscanf
|
%d %f %s %c |
%d で整数出力、scanf でユーザー入力 |
エスケープ文字 |
\n , \t , \\
|
"line1\nline2\t\t\\path" |
2. 演算子と式
演算子種類 | 使用例 | 備考 |
---|---|---|
算術演算子 | a + b |
% は剰余 |
代入演算子 | x += 2 |
連続代入にも注意 |
比較演算子 | x == y |
!= , < , >= など |
論理演算子 |
&& , ` |
|
ビット演算 |
a & b , a << 2
|
フラグ操作に活用 |
優先順位 | a + b * c |
括弧で明示化推奨 |
3. 条件分岐と制御構文
項目 | 使用例 |
---|---|
if , else
|
基本の分岐処理 |
switch-case |
switch(choice) で複数分岐 |
三項演算子 | x = (a > b) ? a : b; |
論理演算の代入ミス |
if (x = 0) ←間違い、== にすべき |
4. 繰り返し構文(ループ処理)
構文 | 特徴 |
---|---|
for |
インデックス変数付き |
while , do-while
|
条件評価の位置が異なる |
無限ループ | while(1) |
break , continue , goto
|
ループ制御 |
5. 変数とデータ型
型 | 例 |
---|---|
int , short , long , unsigned
|
整数の大きさと符号 |
float , double
|
小数表現と精度 |
char |
ASCIIコードとの関係 |
#define vs const
|
定数定義の違い |
enum |
状態管理に便利 |
型変換 | float x = (float)3 / 2; |
6. 関数の定義と利用
項目 | 内容 |
---|---|
プロトタイプ宣言 | int add(int a, int b); |
値渡し vs アドレス渡し |
int* , &変数名
|
void 型関数 |
戻り値なし |
再帰関数 | factorial(n) |
.h と.c の分離 |
モジュール管理 |
static , グローバル変数 |
スコープと保持期間 |
7. 配列と文字列操作
内容 | 使用関数 |
---|---|
一次元・二次元配列 | int a[3][4] |
sizeof で配列要素数取得 |
sizeof(arr) / sizeof(arr[0]) |
文字列終端\0
|
"Hello\0" |
<string.h> 関数 |
strcpy , strlen , strcmp , strstr , strchr , strncpy
|
安全な入力 |
fgets() 推奨 |
境界チェック | for (i < sizeof(arr)) |
8. ポインタの基礎と応用
概念 | 例 |
---|---|
& , *
|
アドレス取得と間接参照 |
char * で文字列処理 |
"Hello" は配列と同じ |
配列の同一性 | arr == &arr[0] |
多重ポインタ | int **ptr |
関数へのポインタ渡し | void modify(int *x) |
NULL 安全チェック |
if (p != NULL) |
const * 修飾 |
読み取り専用ポインタ |
9. 構造体と共用体
項目 | 内容 |
---|---|
struct |
ユーザー定義型 |
配列・ポインタ | struct Point *p = arr; |
typedef struct |
簡潔な記述 |
union |
メモリ共有型 |
enum + struct |
状態管理の組み合わせ |
関数引数渡し | void print(Point p) |
10. メモリ管理と動的確保
操作 | 関数 |
---|---|
動的確保 |
malloc , calloc , realloc
|
解放 | free() |
NULL チェック |
if (ptr == NULL) |
構造体の動的確保 | malloc(sizeof(Person)) |
メモリリーク防止 | 解放順に注意 |
valgrind , gdb
|
メモリ監視とデバッグ(ローカルで) |
11. ファイル入出力
操作 | 関数 |
---|---|
オープン・クローズ |
fopen , fclose
|
読み書き |
fprintf , fscanf , fputs , fgets
|
モード |
"r" , "w" , "a" , "rb"
|
エラー処理 |
feof , ferror
|
12. ビット演算と低レベル操作
操作 | 例 |
---|---|
AND, OR, XOR |
a & b , `a |
ビット反転 | ~a |
左右シフト |
a << 2 , a >> 1
|
マスク | x & 0x0F |
ビットフィールド構造体 | struct Flags { unsigned a:1; ... }; |
import subprocess
# === ステップ1: C言語プログラムを作成 ===
c_code = r"""
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if(argc != 3) {
printf("Usage: %s num1 num2\n", argv[0]);
return 1;
}
int a = atoi(argv[1]);
int b = atoi(argv[2]);
printf("%d\n", a + b);
return 0;
}
"""
# Cファイルとして保存
with open("add.c", "w") as f:
f.write(c_code)
# === ステップ2: gccでコンパイル ===
import subprocess
compile_result = subprocess.run(["gcc", "add.c", "-o", "add"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if compile_result.returncode != 0:
print(" コンパイルエラー:")
print(compile_result.stderr)
else:
print(" Cプログラムのコンパイル成功")
# === ステップ3: PythonからCを実行 ===
a = 12
b = 30
try:
result = subprocess.run(["./add", str(a), str(b)], stdout=subprocess.PIPE, text=True, check=True)
print(f" Cの計算結果: {a} + {b} = {result.stdout.strip()}")
except subprocess.CalledProcessError as e:
print(" 実行エラー:", e)
# プログラム名: run_basic_io_fixed.py
# 概要 / Description:
# C言語で入力値を固定した基本I/Oプログラム(basic_io_fixed.c)をPythonで自動的に書き込み・コンパイル・実行する
import subprocess
# --- C言語コード定義 / Define C code ---
c_code = r"""
// プログラム名: basic_io_fixed.c
// Program Name: basic_io_fixed.c
// 固定値によるCの基本構文デモ
// Basic I/O example with predefined values
#include <stdio.h>
int main(void) {
// --- 変数を初期化 / Initialize variables ---
int age = 23;
float height = 175.5;
char initial = 'S';
char name[] = "Saito";
// --- 結果表示 / Output Results ---
printf("こんにちは!C言語へようこそ。\n");
printf("Welcome to C programming!\n\n");
printf("------ 結果 / Result ------\n");
printf("名前 / Name: %s\n", name);
printf("年齢 / Age: %d 歳\n", age);
printf("身長 / Height: %.2f cm\n", height);
printf("イニシャル / Initial: %c\n", initial);
printf("ありがとう! / Thank you!\n");
// --- エスケープシーケンスの例 / Escape sequences ---
printf("\n--- エスケープ例 / Escape Sequences ---\n");
printf("タブ\t区切り / Tab\tdelimiter\n");
printf("バックスラッシュ: \\\n");
return 0;
}
"""
# --- ファイルに保存 / Save C code to file ---
with open("basic_io_fixed.c", "w") as f:
f.write(c_code)
# --- コンパイル ---
compile_result = subprocess.run(["gcc", "basic_io_fixed.c", "-o", "basic_io_fixed"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
# --- 結果出力 ---
if compile_result.returncode != 0:
print(" コンパイルエラー / Compilation Error:")
print(compile_result.stderr)
else:
print(" Cプログラムのコンパイル成功 / Compilation succeeded")
# --- 実行 ---
result = subprocess.run(["./basic_io_fixed"], stdout=subprocess.PIPE, text=True)
print("\n 実行結果 / Program Output:\n")
print(result.stdout)
# プログラム名: run_operator_and_control.py
# 概要: Cプログラム(演算子・条件分岐・ループ)の自動実行
import subprocess
# --- C言語コードを定義 ---
c_code = r"""
// プログラム名: operator_and_control_demo.c
// 演算子、条件分岐、ループ処理の基本例を網羅
#include <stdio.h>
int main(void) {
int a = 10, b = 3;
printf("\n--- 演算子と式 / Operators ---\n");
printf("算術: a + b = %d\n", a + b);
printf("代入: a += b → %d\n", (a += b));
printf("比較: a > b → %d\n", a > b);
printf("論理: (a > 5 && b < 10) → %d\n", (a > 5 && b < 10));
printf("ビット: a & b = %d\n", a & b);
printf("優先順位: a + b * 2 = %d\n", a + b * 2);
printf("カッコ: (a + b) * 2 = %d\n", (a + b) * 2);
printf("\n--- 条件分岐 / if, else if, switch ---\n");
int score = 85;
if (score >= 90) {
printf("評価: 優\n");
} else if (score >= 70) {
printf("評価: 良\n");
} else {
printf("評価: 可\n");
}
int pass = (score >= 60) ? 1 : 0;
printf("合格判定: %s\n", pass ? "合格" : "不合格");
int day = 3;
switch(day) {
case 1: printf("月曜\n"); break;
case 2: printf("火曜\n"); break;
case 3: printf("水曜\n"); break;
default: printf("その他\n");
}
printf("\n--- 繰り返し構文 / Loops ---\n");
for (int i = 0; i < 3; i++) {
printf("for: i = %d\n", i);
}
int i = 0;
while (i < 3) {
printf("while: i = %d\n", i);
i++;
}
i = 0;
do {
printf("do-while: i = %d\n", i);
i++;
} while (i < 3);
i = 0;
while (1) {
if (i >= 2) break;
printf("無限ループ中: i = %d\n", i);
i++;
}
for (int j = 0; j < 5; j++) {
if (j == 2) continue;
printf("continue例: j = %d\n", j);
}
printf("goto前\n");
goto skip;
printf("この行はスキップされる\n");
skip:
printf("goto後\n");
return 0;
}
"""
# --- Cファイルとして保存 ---
with open("operator_and_control_demo.c", "w") as f:
f.write(c_code)
# --- コンパイル ---
compile_result = subprocess.run(["gcc", "operator_and_control_demo.c", "-o", "operator_and_control_demo"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if compile_result.returncode != 0:
print("❌ コンパイルエラー:")
print(compile_result.stderr)
else:
print("✅ コンパイル成功")
# --- 実行 ---
result = subprocess.run(["./operator_and_control_demo"], stdout=subprocess.PIPE, text=True)
print("\n🖥️ 実行結果:\n")
print(result.stdout)
import subprocess
# --- Cコードをファイルとして保存 ---
c_code = r"""
// プログラム名: types_functions_arrays.c
// データ型、関数、配列・文字列操作の基本例
#include <stdio.h>
#include <string.h> // 文字列操作用
// --- 定数定義 / Constants ---
#define MAX_NAME 50 // マクロ定義 / Macro constant
const float PI = 3.14f; // const定数 / Constant variable
// --- enum定義 / Enumeration ---
enum Weekday { MON, TUE, WED, THU, FRI };
// --- 関数プロトタイプ宣言 / Function Prototypes ---
void greet(void);
int add(int a, int b);
void swap(int *x, int *y);
int factorial(int n);
int main(void) {
// --- データ型の例 / Data Types ---
int i = 10;
short s = 100;
long l = 10000;
unsigned int u = 255;
float f = 3.14f;
double d = 2.71828;
char c = 'A';
printf("文字: %c, ASCII: %d\\n", c, c);
printf("int: %d, short: %d, long: %ld, unsigned: %u\\n", i, s, l, u);
printf("float: %.2f, double: %.5f\\n", f, d);
printf("定数 PI: %.2f\\n", PI);
enum Weekday today = WED;
printf("今日は: %d (0=MON)\\n", today);
// --- 型変換 / Type Conversion ---
double result = (double)i / 3;
printf("明示的キャスト: (double)i / 3 = %.2f\\n", result);
// --- 関数利用 / Using Functions ---
printf("わはは!Cへようこそ!\\n");
greet();
printf("加算: add(3, 4) = %d\\n", add(3, 4));
int a = 5, b = 10;
swap(&a, &b);
printf("スワップ後: a = %d, b = %d\\n", a, b);
printf("階乗: factorial(5) = %d\\n", factorial(5));
// --- 配列と文字列操作 / Arrays and Strings ---
int arr[5] = {1, 2, 3, 4, 5};
int n = sizeof(arr) / sizeof(arr[0]);
printf("配列要素数: %d\\n", n);
char name[MAX_NAME] = "C Language";
printf("文字列: %s, 長さ: %lu\\n", name, strlen(name));
char copy[MAX_NAME];
strcpy(copy, name);
printf("コピー: %s\\n", copy);
char added[MAX_NAME] = "Hello, ";
strcat(added, "World!");
printf("連結: %s\\n", added);
printf("比較: strcmp(\\\"abc\\\", \\\"abd\\\") = %d\\n", strcmp("abc", "abd"));
printf("検索 strchr: %s\\n", strchr("banana", 'n'));
printf("検索 strstr: %s\\n", strstr("hello world", "world"));
// 安全な文字列入力
char input[20];
printf("名前を入力: ");
fgets(input, sizeof(input), stdin);
printf("入力: %s\\n", input);
return 0;
}
// --- 挨拶関数 / Simple function ---
void greet(void) {
printf("わはは!関数からこんにちは!\\n");
}
// --- 加算関数 / Function with return ---
int add(int a, int b) {
return a + b;
}
// --- スワップ関数 / Pass-by-address ---
void swap(int *x, int *y) {
int temp = *x;
*x = *y;
*y = temp;
}
// --- 再帰関数 / Recursive function ---
int factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
"""
# 保存先ファイル名
c_filename = "types_functions_arrays.c"
exe_filename = "types_functions_arrays"
# --- ファイル書き出し ---
with open(c_filename, "w") as f:
f.write(c_code)
# --- コンパイル ---
compile = subprocess.run(["gcc", c_filename, "-o", exe_filename],
capture_output=True, text=True)
if compile.returncode != 0:
print("❌ コンパイルエラー:")
print(compile.stderr)
else:
print("✅ コンパイル成功")
# --- 実行(fgets入力に対応)---
input_data = "Yamada\n"
result = subprocess.run([f"./{exe_filename}"],
input=input_data,
capture_output=True,
text=True)
print("\n🖥️ 実行結果:\n")
print(result.stdout)
# --- Step 1: Cコードをファイルに保存 ---
c_code = r'''
#include <stdio.h>
#include <string.h>
// 構造体の定義 / Struct definition
struct Person {
char name[32];
int age;
};
// ポインタを使ったスワップ関数 / Swap function using pointers
void swap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
int main() {
// ポインタの例 / Pointer example
int x = 10, y = 20;
swap(&x, &y);
printf("After swap: x=%d, y=%d\n", x, y);
// 構造体の例 / Struct example
struct Person p;
strcpy(p.name, "Tetsurou");
p.age = 26;
printf("Name: %s\n", p.name);
printf("Age: %d\n", p.age);
return 0;
}
'''
with open("pointer_struct_demo.c", "w") as f:
f.write(c_code)
# --- Step 2: コンパイル ---
!gcc -o pointer_struct_demo pointer_struct_demo.c
# --- Step 3: PythonからCプログラムを呼び出して出力を受け取る ---
import subprocess
# 実行ファイルを呼び出し / Run the binary
process = subprocess.Popen(
['./pointer_struct_demo'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
stdout, stderr = process.communicate()
# 結果を整形して表示 / Format and print output
print("=== C Output ===")
print(stdout.decode())
if stderr:
print("=== C Error ===")
print(stderr.decode())
# --- Step 1: Cコード(動的メモリ管理の例)を保存 / Write C code to file ---
c_code = r'''
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 構造体の定義 / Define struct
typedef struct {
char *name;
int age;
} Person;
int main() {
// --- mallocでint配列を動的確保 / Dynamically allocate array of int ---
int *arr = (int *)malloc(3 * sizeof(int));
if (arr == NULL) {
fprintf(stderr, "Memory allocation failed for arr\n");
return 1;
}
// 値の代入 / Assign values
for (int i = 0; i < 3; i++) {
arr[i] = (i + 1) * 10;
}
// 出力 / Print
printf("Dynamic array: ");
for (int i = 0; i < 3; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// --- callocでゼロ初期化された配列を確保 / Use calloc for zero-initialized memory ---
int *zero_arr = (int *)calloc(3, sizeof(int));
if (zero_arr == NULL) {
fprintf(stderr, "Calloc failed\n");
free(arr); // mallocしたメモリを解放 / Free arr
return 1;
}
printf("Zero-initialized array: ");
for (int i = 0; i < 3; i++) {
printf("%d ", zero_arr[i]);
}
printf("\n");
// --- 構造体の動的確保 / Allocate struct dynamically ---
Person *p = (Person *)malloc(sizeof(Person));
if (p == NULL) {
fprintf(stderr, "Person malloc failed\n");
free(arr);
free(zero_arr);
return 1;
}
// nameフィールドのメモリ確保 / Allocate memory for name
p->name = (char *)malloc(32 * sizeof(char));
if (p->name == NULL) {
fprintf(stderr, "Name malloc failed\n");
free(p); free(arr); free(zero_arr);
return 1;
}
strcpy(p->name, "Tetsurou");
p->age = 26;
printf("Person: name = %s, age = %d\n", p->name, p->age);
// --- メモリ解放 / Free memory ---
free(p->name);
free(p);
free(arr);
free(zero_arr);
return 0;
}
'''
with open("mem_manage_demo.c", "w") as f:
f.write(c_code)
# --- Step 2: コンパイル / Compile ---
!gcc -o mem_manage_demo mem_manage_demo.c
# --- Step 3: Pythonで実行 / Execute via Python ---
import subprocess
process = subprocess.Popen(
['./mem_manage_demo'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
stdout, stderr = process.communicate()
print("=== C Output ===")
print(stdout.decode())
if stderr:
print("=== C Error ===")
print(stderr.decode())