• ベストアンサー

C言語の文字列を含んだ構造体

下記のサイトに構造体のことが書かれています。 http://www.isl.ne.jp/pcsp/beginC/C_Language_14.html その中の (3)構造体の初期化 の記述で  //構造体の型宣言  struct student{   int no; // 学籍番号   char name[256]; // 氏名   int year; // 学年   char student_class[256]; // クラス  }; と書かれています。 次の(4)構造体のデータ参照では、  //構造体の型宣言  struct OLD{   int no; //番号   char *name; //名前   int s_year; //年   char s_class; //クラス  }; と書かれています。 ここで質問です。 前者の名前は char name[256] ですが、 後者の名前は char *name になっています。 name[256] と *name では何が違うのでしょうか? どういうときに使い分けるのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • jack-a3
  • ベストアンサー率33% (185/546)
回答No.4

これはサイトの記述が悪いです。 構造体の説明をやってる中でいきなり何の前触れもなく配列型とポインタ型が出てきたら質問者さんのように混乱するのもムリはないです。(4)のサンプルプログラムでもポインタ型を使う必要がないし、むしろ配列型の記述のほうがよいように思います。 ポイント型と配列型の違いは他の回答者さんの説明にあるとおり。 付け加えるならば、値をコピーせずに元の名前情報を格納している位置情報を管理するか、値がコピーされて別情報として管理されるかの違い。 (4)のように構造体のメンバとしてchar *name; // 氏名 と定義した状態でoldの初期化を行った場合、構造体の内部のnameには4byte(じゃないときもありますが)のメモリ領域が確保された上で、別のメモリ領域にある上杉謙信などの名前のデータが管理されているメモリ位置情報(アドレス情報)が格納されます。 一方で構造体のメンバとしてchar name[256]; // 氏名 と定義した状態で(4)のoldの初期化を行った場合、構造体の内部に265byteのメモリ領域が確保され、そこに上杉謙信などのの名前のデータがコピーされて格納されます。 (4)のサンプルプログラムに追加で printf("size-OLD=%d",sizeof(OLD)); ・・・などを書いてみれば理解の助けになるでしょうか?

EGA4545
質問者

お礼

ありがとうございます。

その他の回答 (4)

  • Wap58
  • ベストアンサー率33% (29/87)
回答No.5

配列とポインターの扱いは自力で乗り越えてください 文字列もポインターです。基本なのに結構スルーされてる printfとscanfの%sで扱い変わるように見えるからややこしい #include <stdio.h> int main(void){ char name_1[25] = "Hello World"; char *name_2 = "Hello World"; //name_1 = "Hey Mickey";//エラーになる name_2 = "Hey Mickey"; printf("%s : %s\nType to : ",name_1,name_2); scanf("%s",name_1);//文字列を配列ポインターに代入 printf("%s : %s\n",name_1,name_2); return 0; }

EGA4545
質問者

お礼

ありがとうごじます。

  • maiko0333
  • ベストアンサー率19% (840/4403)
回答No.3

char name[256] char型のデータを256個格納できる。 char *name   char型のデータがある位置(ポインター)を格納する。         データの格納には別のエリアが必要になります。

EGA4545
質問者

お礼

ありがとうございます。

  • wormhole
  • ベストアンサー率28% (1619/5652)
回答No.2

構造体は関係ないです。 配列とポインタの違いです。 配列とポインタがどう違うかは検索してみれば色々見付かると思います。 一応、一例 http://www9.plala.or.jp/sgwr-t/c/sec10-2.html

EGA4545
質問者

お礼

ありがとうございます。

  • f272
  • ベストアンサー率46% (7972/17042)
回答No.1

char name[256]はchar型のデータを格納する連続した領域を256個確保して,その先頭の領域にnameという名前を付けた。だからその先頭の領域はname[0]でアクセスできる。またここは*nameでもアクセスできる。その次の領域はname[1]でアクセスできるし,*(name+1)でもアクセスできる。 char *nameはchar*型のデータを格納する領域を1個確保して,そこにnameという名前を付けた。*nameでそこにアクセスできる。*(name+1)はその次の領域だが,どんな使われ方をしているかは保証されない。

EGA4545
質問者

お礼

ありがとうございます。

関連するQ&A

  • 文字列の構造体キャスト

    文字列を構造体にキャストした際に、メンバ変数は以下のようには、 取得できないのでしょうか? typedef struct { int year; /* 学年 */ int clas; /* クラス */ int number; /* 出席番号 */ char name[64]; /* 名前 */ } student; int main(void) { student *data=NULL; char c[] = "123456789012abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij1234"; char* tmp; tmp = &c[0]; student_print(data, tmp); return 0; } void student_print(student *data, char *mkg) { void* buff = NULL;    buff = (student*)mkg; printf("[year]:%s\n", buff ->year);←ここ return; }

  • 構造体について

    凄く初歩的な質問で申し訳ありませんが… 入門書の構造体のところで 以下のようなプログラムの例がありました。 #include <stdio.h> struct seiseki { /* 構造体の宣言 */ int no; char name[20]; double average; }; int main(void) { int i; struct seiseki seito1, seito2[20]; /* 構造体変数と構造体配列の宣言 */ >char name[20] というのは、NAMEの領域を20文字 確保すると言うことですよね? >struct seiseki seito1, seito2[20] ここの箇所が分からないのですが seito2[20]の20というのは どうして20なのですか? NAMEだけではないので もっと大きな数字になるような気がするのですが… またseito1の方は どうして数字が何もないんですか? 考え違いをしているところを ご指摘して頂ければ幸いです。

  • 構造体のすべての変数を文字列に変換したい

    以下のような3つの構造体が与えられたときに、構造体tdが初期化されているとします。 そのときに、構造体tdのすべての要素を文字列に変換したいのですが,ひとつひとつ sprintf を使って変換するのは、ソースファイルにひとつずつ書かなければならず、あまり用いたくありません。 何かよい方法はないのでしょうか? ご回答よろしくお願いします。 struct area{  int x;  int y;  int r[20]; }; struct pinf{  struct area;  int s;  int r[18]; }; struct td{  char no[4];  char name[20];  struct pinf p1,p2[10];  int tpc;  int r[20]; };

  • C言語の構造体

    組込み系でマイコンにソフトをプログラミングの仕事をしています。 C言語は初心者です。 http://www9.plala.or.jp/sgwr-t/c/sec15.html のページの冒頭に、 「構造体は幾つかの異なる型のデータをまとめて 1つのデータ型として扱うものなのです。」と書かれています。 1つのデータ型として扱うとどのようなメリットがあるのでしょうか? 例えば、 struct seiseki seito1; のように対象が1つ(seito1)なら int seito1_no; char  seito1_name[20]; double seito1_average; と変数を確保すれば済むのに、 何故、構造体で宣言するのでしょうか? 例えば、 struct seiseki seito2[20]; のように、似たものが複数ある場合は(seito2が20人分なるなら、) 構造体で宣言する意味があるとはなんとなくわかります。 後ページの http://www9.plala.or.jp/sgwr-t/c/sec15-4.html では、関数でのやり取りが書かれています。 関数で引数や返値で扱うときに構造体にしておいた方が良いからでしょうか? 構造体のメリットというのが今一わかりません。 対象が1つでも構造体で書いた方がいろんな意味で良いのでしょうか? 如何せん、初心者なので質問がうまく書けませんがご了承ください。 ※上から目線的な回答はご遠慮願います。

  • C言語での構造体

    C言語の構造体で配列を扱うとき、 struct ○○{  char ○○[○] とすれば出来ますが、同じようにして構造体で二次元配列を扱うことは出来ますか? 一度組んでみたのですが、 #include<stdio.h> struct aaa{ int no; char name[128]; char y_name[128]; char n_name[128]; char s_name[128][128]; }; int main(void){ int i; struct aaa iryo[99]; printf("入力前\n"); /* 構造体配列に scanf()でデータを入力 */ for(i = 0; i < 3; i++) { // printf("input...\n"); scanf("%d", &iryo[i].no); scanf("%s", iryo[i].name); scanf("%s", iryo[i].y_name); scanf("%s", iryo[i].n_name); scanf("%s", iryo[i].s_name); } printf("入力後\n"); printf("出力前\n"); /* 入力データの確認 */ for(i = 0; i < 3; i++) { printf("番号:%02d 内容:%s Y分岐:%s N分岐:%s 他分岐:%s\n", iryo[i].no, iryo[i].name, iryo[i].y_name, iryo[i].n_name, iryo[i].s_name); } printf("出力後\n"); printf("%d",sizeof(struct aaa)); return 0; } としたら、エラーは出ませんが、実行すると何も表示されませんでした。

  • 構造体についてです。

    typedef struct student{ int id; char name[20]; int kokugo; int sansu; int eigo; }STUDENT; と、 struct student{ int id; char name[20]; int kokugo; int sansu; int eigo; }; の違いはなんでしょう? 私は下記をよく使うのですが・・・。 typedefについて詳しく知りたいです。

  • クラス内の構造体の実体化とアクセス方法が・・

    クラス内の構造体の実体化とアクセス方法が解らなくて困っていまし。 ヘッダーで class data { public: struct SET_A { int time; char name[24]; }; }; と宣言したクラス内の構造体を使いたくて data::SET_A dataseta; dataseta.time = 1; などとしても構文エラーになってしまいます。 クラス内の構造体はどう実体化してアクセスしたりすれば良いのでしょうか?

  • C言語 構造体配列について

    6人分の小テストの点数を記録し,平均値などを計算するプログラムを作成している. 以下の手順と条件に従ってプログラムを作成. 手順 (1) 氏名(name[100], char 型) と点数( score , int 型) をメンバにもつ構造体「struct_TEST」を(main 関数の外で)定義. (2) struct _TEST 型構造体配列 element[6] を定義. (3) キーボードから氏名(ローマ字でよい)と点数を入力する処理を6 回繰り返す. (4) 平均点を計算して画面表示. (5) 最高点を出した人の名前と点数を画面表示. (6) 平均点に満たない人の名前と点数を画面表示. 条件 (3)~(6)の処理には以下に示す関数を利用する. (3) ・・・ 氏名と点数を入力する処理をn 回繰り返す関数 void input_score( struct _TEST *a, int n ) (4) ・・・ n 個の構造体配列に対して平均を計算し,平均点を返す関数 double calc_ave( struct _TEST *a, int n ) (5) ・・・ n 個の構造体配列に対して最高点を算出し,そのユーザの配列番号を返す関数 int calc_max( struct _TEST *a, int n ) (6) ・・・ n 個の構造体配列に対して平均点に満たない人の名前と点数を画面表示する関数 void show_under_ave( struct _TEST *a, int n ) C言語の構造体が良く分かっていません。 こういった条件が多いと考えづらく分からなくなります。 考えても分かっていないので困っています。 誰かすみませんが解答を教えて下さい。

  • C言語 構造体配列 list

    プログラミングでこの問題がわからないので教えてください! 下記の構造体タグseisekiを使って,表に示すデータをもつ構造体配列listを作成する. 構造体配列listを利用して,一番点数の高い 者を探し,その名前を表示する. struct seiseki{ char name[30]; int score; name score }; 表 佐藤 80 鈴木 75 田中 95 高橋 90

  • C言語について教えてください。

    名前、身長、体重をメンバとする構造体オブジェクトを要素とする配列を宣言・定義する。 (1)名前、身長、体重を構造体オブジェクトのメンバに格納する関数 (2)平均身長を計算する関数 (3)平均体重を計算する関数 をそれぞれ定義し、その関数の機能を確認するプログラムを作成する。 構造体オブジェクトの各メンバは以下の値をもつとする。 Name Height(cm) Weight(kg) Tom 174.2 72.3 Jerry 152.3 49.2 Spike 168.6 84.8 ただし、平均身長と平均体重は呼び出し元の関数(関数main())で表示する。 また(2)(3)については、生徒の人数が変更されても処理できる関数を作成する。 [実行結果の例] 平均身長:165.0cm 平均体重: 68.0kg [ヒント] 構造体の配列でまとめられたデータから平均身長あるいは平均体重を計算する関数 <返却値型><関数名>(構造体の配列の受け渡しに対応した仮引数の宣言、生徒の人数) この問題について教えてください。 下のプログラムは自分でつかりかけたプログラムです。 #include <stdio.h> #include <string.h> struct student { char name[6]; double height; double weight; }; struct student set_student(char *n, double h, double w) { struct student ss; strcpy(&ss.name[0], n); ss.height = h; ss.weight = w; return ss; } int main(void) { struct student seito[3]; seito[0] = set_student("Tom", 174.2, 72.3); seito[1] = set_student("Jerry", 152.3, 49.2); seito[2] = set_student("Spike", 168.6, 84.8); return 0; } (2)(3)計算の計算する関数を定義し、表示させる方法がよく分かりません。具体的に教えてもらえませんか。よろしくお願いします。