0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

この記事について

「C言語の基礎を学ぼう」をテーマに、自身の知識 + α をアドベントカレンダーにまとめます。
25日間でC言語をマスターしよう - Qiita Advent Calendar 2025 - Qiita

こんな方を対象としています

  • コンピュータがプログラムをどのように動かしているか知りたい/知らない方

  • プログラミングをしてみたい方

  • C言語初心者の方

キーワード

  • 構造体

説明

構造体

複数の変数をひとまとまりに扱いたい場合、 構造体 を利用します。

#include <stdio.h>
#include <string.h> // strcpy()

struct Employee { // 構造体
    int id; // メンバ変数
    char name[20]; // メンバ変数
};

int main(void) {
    // 宣言
    struct Employee emp;
    // 初期化
    emp.id = 123;
    strcpy(emp.name, "edamame");
    // 表示
    printf("id: %d name: %s", emp.id, emp.name);
    return 0;
}
id: 123 name: edamame

struct で構造体のメンバを定義します。
定義した構造体は、型のように扱うことができます。

上記の emp.id のように、 . で各メンバにアクセスすることができます。

上記の emp.name はchar配列のため、単純に = で値を代入することができません。
配列の要素を1つずつコピーすることもできますが、今回は string.hstrcpy() を使用しています。

strcpy(コピー先char[], コピー元char[])

また、 enum と同様 typedef を使用することで、変数の宣言を簡単にすることができます。

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

typedef struct {
    int id;
    char name[20];
} Employee;

int main(void) {
    Employee emp; // structが不要
    emp.id = 123;
    strcpy(emp.name, "edamame");
    printf("id: %d name: %s", emp.id, emp.name);
    return 0;
}
id: 123 name: edamame

今回、 . を使用して初期化しましたが、宣言と同時に初期化することも可能です。

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

typedef struct {
    int id;
    char name[20];
} Employee;

int main(void) {
    Employee emp = {123, "edamame"}; // 初期化
    printf("id: %d name: %s", emp.id, emp.name);
    return 0;
}
id: 123 name: edamame

構造体のポインタ

構造体を指すポインタを定義することができます。
ポインタからメンバ変数へアクセスする場合、アロー演算子 -> を使用します。

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

typedef struct {
    int id;
    char name[20];
} Employee;

int main(void) {
    Employee emp = {123, "edamame"};
    Employee *emp_p; // ポインタ

    emp_p = &emp; // アドレスをコピー

    printf("id: %d name: %s", emp_p->id, emp_p->name);

    return 0;
}
id: 123 name: edamame

練習

1. コンビニの在庫管理をしよう

  1. 商品名、価格、在庫数をメンバ変数とした構造体 Product を作成しよう。
  2. Product の配列を定義しよう。
  3. 1つの Product を初期化する init_product を作成しよう。
  4. Product のメンバ変数を表示する print_product を作成しよう。
// 引数 : Productのアドレス、商品名、価格、在庫数
init_product(*Product, char[], int, int)
// 引数 : Product
print_product(Product)
Apple : 120円 在庫数 : 55
Banana : 200円 在庫数 : 30
Coffee : 100円 在庫数 : 180

ポイント

init_product は参照渡し、 print_product は値渡しです。
それぞれ適した演算子でメンバ変数にアクセスしましょう。

値渡しの場合、関数内での変更は呼び出し元に影響しません。
(新しいメモリ領域を確保するため)
参照渡しの場合、関数内での変更が呼び出し元に影響します。
(呼び出し元のメモリ領域を操作するため)

通常、構造体は値渡しをすることはあまりなく参照渡しがほとんどです。
今回は値渡しも練習してみます。

解答例

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

typedef struct {
    char name[20];
    int price;
    int stock;
} Product;

void init_product(Product *product, char* name, int price, int stock);
void print_product(Product product);

int main(void) {
    Product items[3];

    init_product(&items[0], "Apple", 120, 55);
    init_product(&items[1], "Banana", 200, 30);
    init_product(&items[2], "Coffee", 100, 180);

    print_product(items[0]);
    print_product(items[1]);
    print_product(items[2]);

    return 0;
}

void init_product(Product *product, char* name, int price, int stock) {
    strcpy(product->name, name);
    product->price = price;
    product->stock = stock;
}

void print_product(Product product) {
    printf("%s : %d円 在庫数 : %d\n", product.name, product.price, product.stock);
}
Apple : 120円 在庫数 : 55
Banana : 200円 在庫数 : 30
Coffee : 100円 在庫数 : 180

おわりに

構造体を使うことでデータベースのレコードのようなものを表現することができます。
オブジェクト指向言語のクラスにも似ていますね。Javaっぽいな。

参考文献

↓↓↓ はじめてプログラミングを学んだときに読んだ本です ↓↓↓
詳細(プログラミング入門 C言語)|プログラミング|情報|実教出版

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?