コース一覧
    C言語中級 文字列・構造体
    構造体ポインタと->

    C言語中級 文字列・構造体

    C言語の文字列と構造体を学び、複数のデータを整理して扱うコースです。

    1
    文字列処理の実践
    01. strlenを自作する15分
    02. strcpyを自作する15分
    03. バッファオーバーフロー体験15分
    04. 文字列を分解する15分
    05. 動的な文字列15分
    06. つくる 名前入力の安全化15分
    07. 第3章クイズ10分
    2
    構造体とポインタ
    01. 構造体ポインタと->15分
    02. 構造体の動的確保15分
    03. 動的な構造体配列15分
    04. 関数ポインタ15分
    05. qsortで並べ替える15分
    06. つくる 動的Student完成15分
    07. 第4章クイズ10分

    構造体ポインタと->

    構造体は値で渡すと丸ごとコピーされる

    入門で書いた Student は、名前用の char name[32] と点数の int score を持っていました。これを関数に値で渡すと、36 バイト前後の中身がまるごとコピーされます。しかもコピーを書き換えているだけなので、関数の中で点数を直しても呼び出し元には反映されません。

    前回までに使ってきたポインタ渡しは、ここでも同じように効きます。渡すのは番地ひとつだけで、しかも呼び出し元の実体をそのまま触れます。構造体こそポインタ渡しの本命だと思ってください。

    -> はカッコを書かずに済ませるための記号

    Student *p が構造体を指しているとき、その中の score を触るには「p が指す先」を取り出してからメンバを選びます。素直に書くとこうなります。

    c

    (*p).score = 80;

    丸カッコが要ります。* よりも . のほうが強く結び付くので、カッコを外した *p.score は「p.score が指す先」という別の意味になり、コンパイルエラーになります。

    このカッコが毎回うるさいので、C には専用の記号が用意されています。

    c

    p->score = 80;

    -> は「指す先のメンバ」を一手で指します。(*p).score と p->score は完全に同じ意味で、コンパイル結果も同じです。実務の C コードはほぼ全部 -> で書かれているので、読めないと困ります。

    ドットと矢印は、左側が何かで決まる

    迷ったら記号の左側を見てください。左が構造体の実体ならドット、左がポインタなら矢印です。

    c

    Student st;
    Student *p = &st;
    
    st.score = 80;    /* 左は実体なのでドット */
    p->score = 90;    /* 左はポインタなので矢印 */

    st と p は別の変数ですが、p は st を指しているので、p->score を書き換えると st.score も 90 になります。コピーではなく本体を触っているからです。この 1 行が、ポインタ渡しした関数の中で値を直せる理由そのものです。

    メンバを scanf に渡すときの &

    char name[32] は配列なので、名前そのものが先頭の番地になります。scanf に渡すときは & を付けません。一方 int score は普通の変数なので & が要ります。

    c

    scanf("%31s %d", p->name, &p->score);

    &p->score は「p->score が置かれている番地」という意味です。-> のほうが & より強く結び付くので、カッコなしでこの読み方になります。%31s の 31 は、終端の \0 を含めて 32 バイトに収めるための上限です。ここを %s にすると、長い名前を打たれた瞬間に隣の score を壊します。第 3 章でやった幅の指定は、構造体のメンバでもそのまま必要です。

    要件

    1. add_point は受け取ったポインタが指す学生の score に delta を足す
    2. メンバの読み書きは -> を使う。(*p).score の形は使わない
    3. scanf の書式は %31s と %d を使い、名前の長さを制限する
    4. 出力は「名前 点数」を半角スペース区切りで1行

    ヒント

    p->name は配列なので scanf に渡すとき & を付けません。p->score は変数なので &p->score です

    add_point の中で s->score += delta; と書くと、呼び出し元の st がそのまま変わります

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

    関連レッスン

    • 構造体の動的確保

      構造体をヒープに1つ作れるようになります。

    • 動的な構造体配列

      構造体の一覧を動的な配列で持てるようになります。

    • 関数ポインタ

      関数そのものを引数として渡せるようになります。

    • qsortで並べ替える

      比較関数を書いて qsort で並べ替えられるようになります。

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

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

    • 関数処理に名前を付けて再利用できる単位
    • コンパイルソースをバイトコードへ変換する処理
    • 変数データに名前をつけて参照する仕組み
    • 配列サイズ固定の同型データの集まり
    main.c
    エディタを読み込んでいます

    メモ

    構造体ポインタと->

    ⌘S で保存