見出し画像

C言語教室 第15回 - 構造体の基本

同じ意味(型)の変数がたくさんある場合は配列を使うという說明はしましたが、異なる意味(型)の変数をまとめたい場合に構造体というものを使います。

構造体を使うには、まず構造体の型を宣言します。

例えば商品名と価格をまとめるには

struct product {
  char name[32];
  int price;
};

もちろん、同じ型の変数をまとめても構いません。座標を記憶する構造体を作ってみましょう。

struct position {
  int x;
  int y;
};

これらの型を使うには、まず定義してから、その名前を使って変数を宣言します。

struct product {
  char name[32];
  int price;
};
struct product stock;

構造体に含まれる変数をメンバ変数と言います。メンバ変数にアクセスするには、構造体として宣言された変数名に続けて “.” を書いてから、メンバ変数の名前を続けます。

stock.name = “Paper Knife”;
stock.price = 1500;

この例でもわかるように、name は char 配列で、メンバ変数に配列を使うことも出来ます。name の先頭の文字を取り出すのであれば、

printf(“top char of product name:%c\n”, stock.name[0]);

となりますね。

商品名の長さがわからないので、動的に確保するというのであれば、

struct product {
  char *name;
  int price;
} stock;

として、ちゃんと領域を確保してから使えばいいですね。

#define PRODUCT_NAME “Paper knife”

stock.name = (char*)malloc(strlen(PRODUCT_NAME) + 1);
strcpy(stock.name, PRODUCT_NAME);

さらに構造体の中に構造体を使うことも出来ます。先程の例に出した position を使ってみましょう。

struct rectangle {
  struct position top_left;
  struct position bottom_right;
} box;

box の座標を設定するには、

box.top_left.x = 0;
box.top_left.y = 0;
box.bottom_right.x = 100;
box.bottom_right.y = 50;

とすれば長方形のそれぞれの座標が扱えるわけです。

もちろん構造体の型を持つ変数の配列を使うことも出来ます。

#include <stdio.h>
#include <stdlib.h>

struct position {
  int x;
  int y;
};

struct rectangle {
  struct position top_left;
  struct position bottom_right;
};

void main() {
  struct rectangle boxes[10];
  int i;

  for (i = 0; i < 10; i++) {
    boxes[i].top_left.x = 0;
    boxes[i].top_left.y = 0;
    boxes[i].bottom_right.x = i;
    boxes[i].bottom_right.y = i * 2;
  }

  for (i = 0; i < 10; i++) {
    int width = abs(boxes[i].bottom_right.x - boxes[i].top_left.x);
    int height = abs(boxes[i].bottom_right.y - boxes[i].top_left.y);
    printf("area of box[%d] = %d\n", i, width * height);
 }
}

実行してみましょう。

area of box[0] = 0
area of box[1] = 2
area of box[2] = 8
area of box[3] = 18
area of box[4] = 32
area of box[5] = 50
area of box[6] = 72
area of box[7] = 98
area of box[8] = 128
area of box[9] = 162

構造体の「構造体名」と「構造体変数」で混乱しないように。構造体に含まれるメンバ変数は、構造体の変数名+"."+メンバ変数の「名前」でアクセスします。ここまでは配列で「変数名[正の整数]」を使っていたのが、構造体だと「変数名.メンバ変数名」となっただけだとわかってしまえば充分です。

ところで ChatGPT にもCの言語の構造体を説明してもらいました。

以下は、C言語の構造体の使用例です:

#include <stdio.h>
struct Point {
  int x;
  int y;
};

int main() {
  struct Point p;
  p.x = 10;
  p.y = 20;

  printf("Point: (%d, %d)\n", p.x, p.y);
  return 0;
}

この例では、構造体「Point」が定義されており、xとyという2つのフィールドを持っています。
その後、main関数では「Point」型の構造体変数「p」が宣言され、そのフィールドxとyに値が代入されます。
最後に、printf関数を使用して「Point」型の構造体変数「p」のフィールド値が表示されます。

ChatGPT

簡潔ですね。構造体の名前を大文字にする流儀もありますが、一般的であるわけではありません。


課題

立体空間における座標を表す構造体を定義してから、それを使って立体空間の2点を結ぶ直線を表す構造体を定義した上で、適当な座標を設定して、その直線の長さを求めなさい。なお、直線の長さは √((x2-x1)^2+(y2-y1)^2+(z2-z1)^2)で求められる。※^は累乗演算子だと解釈してください。右上に小さく書くやつです。

立体空間が難しければ平面でも良いですよ。

第14回の課題と演習は、今回の分と一緒に解答します。


ヘッダ画像は、いらすとや さんよりhttps://www.irasutoya.com/2015/12/blog-post_312.html

この記事が気に入ったらサポートをしてみませんか?