コース一覧
    C言語基礎 ポインタ・構造体・ファイル
    構造体と関数

    C言語基礎 ポインタ・構造体・ファイル

    C言語のポインタ、構造体、ファイル操作を学び、データを扱う基礎を固めるコースです。

    1
    ポインタの入口
    01. アドレスとは15分
    02. ポインタの&と*15分
    03. scanfの&の正体15分
    04. 関数で値を書き換える15分
    05. 配列を関数に渡す15分
    06. つくる 入力処理の関数化15分
    07. 第7章クイズ10分
    2
    構造体とファイル
    01. 構造体15分
    02. メンバの読み書き15分
    03. 構造体配列15分
    04. 構造体と関数15分
    05. ファイルに書き込む15分
    06. ファイルを読み込む15分
    07. ファイルの失敗に備える15分
    08. つくる 保存機能15分
    09. 第8章クイズ10分
    3
    総合制作
    01. メニュー統合15分
    02. 自由拡張15分
    03. 完成と次のステップ10分

    構造体と関数

    1人分をそのまま引数にできる

    表示処理を関数に切り出すとき、以前なら名前と点数を別々の引数で渡す必要がありました。構造体なら 1 個で済みます。

    c

    void print_student(struct Student s) {
        printf("%s %d点\n", s.name, s.score);
    }

    呼ぶときは print_student(first); です。引数の型が struct Student なので、名前も点数も一緒に届きます。あとから「学年」のメンバを増やしても、関数の引数リストを書き換えずに済みます。

    渡るのはコピー

    ここで前章のポインタの話が効いてきます。関数の引数は代入と同じで 値のコピー が渡ります。構造体も例外ではなく、中身がまるごと複製されて関数に入ります。

    つまり、関数の中で s.score = s.score + 5; と書いても、それは手元のコピーを変えただけです。呼び出し元の変数は 1 点も動きません。表示するだけの関数ならコピーで困りませんが、書き換えたいときはコピーでは届かない のです。

    書き換えたいならアドレスを渡す

    第7章の swap と同じ解き方をします。値ではなく アドレス を渡します。

    c

    void add_bonus(struct Student *p, int bonus) {
        (*p).score = (*p).score + bonus;
    }

    struct Student *p は「構造体のある住所を入れる変数」です。*p でその住所にある本体を取り出し、さらに .score でメンバを指します。* を先に効かせるためのカッコが要る点に注意してください。カッコを外した *p.score は意味が変わってしまいます。

    この (*p).score は使う頻度が高いわりに書きにくいので、C には専用の省略記法があります。

    c

    p->score = p->score + bonus;

    -> は「アドレスの先にあるメンバ」を意味する矢印です。(*p).score と完全に同じ意味で、読みやすいこちらを使うのが普通です。ポインタ変数なら ->、実体の変数なら .、という使い分けだけ覚えておけば当面は足ります。

    呼び出し側は add_bonus(&s, 5); と、& を付けて住所を渡します。scanf に & を付けていたのと同じ理屈です。

    どちらで受け取るか

    判断はごく単純です。中身を書き換えたいならポインタ、表示や計算をするだけなら値で受け取ります。実務ではもうひとつ、構造体が大きいときはコピーの手間を惜しんで、書き換えないのにポインタで受け取ることもあります。今のところ struct Student は小さいので、値で渡して困ることはありません。

    なお、ここで扱うポインタは「既にある変数の住所」だけです。メモリを新しく確保する malloc はこのコースでは使いません。手元の変数に & を付けて渡す、という形さえ守れば、住所が無効になる心配もありません。

    では、表示する関数と点数を書き換える関数の両方を作ってみましょう。

    要件

    1. print_student は struct Student を値で受け取り「田中 82点」の形で表示する
    2. add_bonus は struct Student のポインタと加点する点数を受け取り、点数を書き換える
    3. add_bonus の中では -> を使ってメンバを書き換える
    4. 加点前と加点後の2行を print_student で表示する

    ヒント

    呼び出すときは add_bonus(&s, bonus); のようにアドレスを渡します

    p->score は (*p).score と同じ意味です

    入力は 名前 点数 加点 の順に3つ読み込みます

    生田 陸人
    監修生田 陸人
    ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
    編集 ゆめさく編集部·公開 2026/08/07

    関連レッスン

    • ファイルに書き込む

      計算した成績をファイルに保存できるようになります。

    • ファイルを読み込む

      保存したデータを読み戻せるようになります。

    • ファイルの失敗に備える

      ファイルが無い初回起動でも落ちないプログラムを書けるようになります。

    • つくる 保存機能

      読み込みから更新、保存までを1本で通せるようになります。

    このレッスンに出てくる用語

    意味があいまいなまま進んだ語は、ここから読み直せます。

    • 引数位置引数=順番で渡す。
    • 処理計算や代入を表す長方形
    • 関数処理に名前を付けて再利用できる単位
    • リスト順序付きで複数の値を扱うデータ構造
    • 変数データに名前をつけて参照する仕組み
    • 判断YES/NO 分岐を表す菱形
    • メモリプログラムとデータを一時保持する高速領域
    main.c
    エディタを読み込んでいます

    メモ

    構造体と関数

    ⌘S で保存