• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:構造体で char name[]と*nameの違い)

構造体でname[]と*nameの違い

このQ&Aのポイント
  • 構造体でchar name[20]と*nameの違いがわかりません。sizeof()で調べたら*nameの方で実行した構造体のプログラムはname[20]で実行したのに比べてバイト数なども半分になり、アドレスの間隔も変化したので、ポインタで定義したほうが良いような感じはするのですがこんな単純な理由ではないと思います。
  • この2種の違いがインターネットを調べても納得いく答えがだせず、教科書にも詳しく書かれていなかったので、分かる方がおられれば教えてください。
  • 作成中のプログラムで、構造体のメンバーとしてchar name[20]と*nameの違いがわかりません。プログラム内でのバイト数やアドレスの間隔の変化の理由などについて、詳しい方がいらっしゃれば教えてください。

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

  • ベストアンサー
  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.1

>char name[20]と*nameの違いがまだハッキリわかりません char []は配列です。 指定されたサイズのメモリがあることは保証されます。 # 変数の寿命については考慮する必要がありますが。 char *はchar型の領域を指すポインタです。 # ポインタ変数の領域として、32BitOS上のソフトであれば一般的に4バイト必要です。 ポインタ変数は有効などこかの領域を指している必要があります。 たいていのローカル変数は初期化されていませんので、正しい領域を指しません。 掲示されている例の場合、ポインタは文字列リラテルを指しているので問題ありませんが… 文字列リラテルを指していますので、内容を書き換える事はできません。 strcpy(Mdcl_Chk[1].name, "ホクトウミ"); というようなコトはできません。 # 代わりに Mdcl_Chk[1].name = "ホクトウミ"; は可能。 # C言語の文字列処理の経験が浅いと、こっちの方が便利に見えるかも知れませんけどね…。 掲示の場合は変数宣言時に初期値が設定されているので問題ありませんが… 配列Mdcl_Chkが未初期化の場合に外部からデータを読み込む時に問題になるでしょう。 char name[20]; の場合は、文字列終端の'\0'込みで20バイト確保されています。 char *name; の場合は動的メモリ確保(malloc()など)で正しい場所を指すようにしないとアクセス違反になります。 # 動的確保したら不要になった時点で自分で開放する必要があります。 # 動的確保の為、確保できるメモリ容量以外に文字数を制限する要素はありません。 # 勿論、メモリ確保に失敗する可能性も考慮する必要がありますが。 >この2種の違いがインターネットを調べても納得いく答えがだせず どう納得ができない…のでしょう?

MK-22
質問者

お礼

構造体に固執するばかりにポインタの領域などの内部の知識が疎かになっていました。 納得ができないと言うのか構造体で使われる配列とポインタの違いばかり考えていたので基礎の配列とポインタの役割の違いが頭から抜けていました。 今回のみなさんの回答でスッキリしました。ありがとうございます

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

char[20]だとこんな感じ name:□□□□□□□□□□□□□□□□□□□□ age:???? weight:?.?? height:?.?? char*だとこんな感じ name: →??? age:???? weight:?.?? height:?.?? 初期化後の状態は char[20]だとこんな感じ Mdcl_Chk[0].name:タカノハナ'\0'□□□□□□□□□□□□□□ Mdcl_Chk[1].name:ワカノハナ'\0'□□□□□□□□□□□□□□ Mdcl_Chk[2].name:ムサシマル'\0'□□□□□□□□□□□□□□ .... (文字コードによっては、仮名一文字あたり何マス使うかが変化します) char*だとこんな感じ どこかの領域No1:タカノハナ'\0' どこかの領域No2:ワカノハナ'\0' どこかの領域No3:ムサシマル'\0' .... Mdcl_Chk[0].name:→どこかの領域No1 Mdcl_Chk[1].name:→どこかの領域No2 Mdcl_Chk[2].name:→どこかの領域No3 ....

MK-22
質問者

お礼

配列にしてしまうと、もし使わなくなった部分がでればそれだけ無駄が増えるということですね

全文を見る
すると、全ての回答が全文表示されます。
回答No.2

*nameだと,newとか,mallocとかのように動的にメモリを確保する必要があります. が,name[20]だと,静的に20のcharacterを確保するという違いがあります. 確保方法が違うだけです.

MK-22
質問者

お礼

メモリの確保の違いですか。頭で考えるだけでなくて一連の流れを書いてみて頭に叩き込んでいきます

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • C言語 構造体へのポインタ 値を変化させず出力

    struct mdcl_chk{ char*name; intage; floatweight; floatheight; }; void main(void) { inti,x; struct mdcl_chkMdcl_Chk[5]={ {"タカノハナ ",38,150.0,183.0}, {"ワカノハナ ",39,120.0,180.0}, {"ムサシマル ",39,237.0,192.0}, {"アサショウリュウ",30,147.0,184.0}, {"ハクホウ ",25,149.0,192.0} },*MC,*DEF,*OFF; MC=Mdcl_Chk;       //貴乃花と若乃花を体重の半分の値で戦わせて、防御側の体重が0になったら終了 do{ for(i=0;i<2;i++){ OFF=&Mdcl_Chk[i]; DEF=&Mdcl_Chk[i^0x00000001]; DEF->weight -= (OFF->weight/2); if(DEF->weight <= 0)DEF->weight=0; printf("%s %5.1f\n",OFF->name,OFF->weight); printf("%s %5.1f\n",DEF->name,DEF->weight); rewind(stdin); getchar(); if(DEF->weight==0){ printf("%s の勝利\n",OFF->name); break; } } }while(DEF->weight > 0);       //全選手のデータ表示 for(i=0;i<5;i++){ printf("%s %d %5.1f %5.1f\n",MC->name,MC->age,MC->weight,MC->height); MC++; } 変なプログラムですが 今悩んでいるのはデータを表示させると、戦わせた後の体重がそのまま出力されていまいます。 新たにポインタ(*MC)を別で定義してもできず・・ データを先に表示させれば問題はないですが、それ以外で値を変えず(戦わせても数値は元のまま)に出力させるにはどうすれば良いのでしょうか 説明が下手ですがよろしくお願いします

  • 構造体についてです。

    身体測定表を作っていて最初に作ったデータを変更して表示したいのですがNo1の168cm→162cm No2の74kg→74.5kg  No3の20歳→19歳 No4の田中三郎→小林三郎 (No3と4は構造体ポインタを使ってデータを変更) 全データを表示させてその後No1と3の名前~体重を丸ごと入れ替えて全データを表示させたいのですがエラーがでてしまいます。 分かる人がいましたらどこを直したらいいか教えて下さい。 #include <stdio.h> #include <string.h> struct data{ int no; char name[21]; int age; int height; float weight; }; struct data *sp; void main(){ int i; struct data a[4]={ {1,"鈴木太郎",23,168,60}, {2,"山本次郎",17,180,74}, {3,"山田花子",20,156,53}, {4,"田中三郎",35,172,68}, }; struct data b; for(i=0;i<4;i++){ printf("番号 :%d\n",a[i].no); printf("名前 :%s\n",a[i].name); printf("年齢 :%d歳\n",a[i].age); printf("身長 :%dcm\n",a[i].height); printf("体重 :%4.1fkg\n\n",a[i]. weight); } a[0].height=162; a[1].weight=74.5; *sp[2].age=19; strcpy(*sp[3].name,"小林三郎"); for(i=0;i<=4;i++){ b=a[0]; a[0]=a[2]; a[2]=b; a[0].no=1; a[2].no=3; } for(i=0;i<=4;i++){ printf("番号 :%d\n",a[i].no); printf("名前 :%s\n",a[i].name); printf("年齢 :%d歳\n",a[i].age); printf("身長 :%dcm\n",a[i].height); printf("体重 :%4.1fkg\n\n",a[i].weight); } }

  • 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; } としたら、エラーは出ませんが、実行すると何も表示されませんでした。

  • 構造体の配列 char *' 型は 'char' 型に変換できない

    大学の課題で構造体の配列の課題が出て、自分で考えてはみたもののわからないところが出たので質問させていただきます。 内容 人物の名前と年齢を入力し、表示するプログラム。 1、typedefを用いて、その構造体にpersonという名前をつける 2、main()にて以下の処理を行う。 (a)person型のサイズNの配列を用意する。 (b)N人分の名前と年齢入力して(a)で用意した配列に格納する。 (c)N人分入力後、名前と年齢を画面に表示する。 #include <stdio.h> #define ninzu 1 typedef struct{ char name[ninzu][20]; int age[ninzu]; } person; int main(void){ int i,ag[ninzu]; char nam[ninzu][20]; for(i=0;i<ninzu;i++){ printf("名前を入力\n"); scanf("%s\n",nam[i]); printf("年齢を入力\n"); scanf("%d\n",&ag[i]); } for(i=0;i<ninzu;i++){ person pro={nam[i],ag[i]}; printf("%s\n",pro.name[i]); printf("%d\n",pro.age[i]); } return(0); } 現在、↑のところまでいったのですが、 for(i=0;i<ninzu;i++){ person pro={nam[i],ag[i]}; printf("%s\n",pro.name[i]); printf("%d\n",pro.age[i]); } の部分の配列の表示の仕方がいまいちわかりません。 現在" 'char *' 型は 'char' 型に変換できない(関数 main() "のエラーが出ています。 わかり難いかもしれませんが、ご指導のほう宜しくお願いいたします。

  • C言語の構造体について

    ご質問があります。 現在C言語について学習しているのですが、構造体を勉強しているときに下記のようなコードを作ったのですが storage size of 'mydata' isn't known というエラーが出てきてしまいます。 どこが間違っているのかがわかりません。 ご指南ご指導して頂けると助かります。 以下コード int main(void){ struct data mydata; mydata.name = "Yamada"; mydata.age = 30; mydata.height=173; mydata.weight = 65.4; printf("name = %s\n",mydata.name); printf("age = %d\n",mydata.age); printf("height = %d\n",mydata.height); printf("weight = %1f\n",mydata.weight); return EXIT_SUCCESS; }

  • char型+char型ってint型? if(char型==int型)?

    C言語の「汎整数拡張(インテグラルプロモーション)」というものに関するものだと思います。 char型とchar型を加えた結果は、char型でしょうか。それともint型でしょうか。 (下のプログラムの printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */ という部分の結果は4なので、int型と考えるべきなのかな。) 私は、char型とint型の加算の結果はint型だと思っていましたが、 char型とchar型の加算の結果はやはりchar型だと思っていました。 (それが間違えているのでしょうか。) if(a[0]==i) /* char型とint型の比較(?) */ の部分では、左辺はchar型、右辺はint型ですが、このように型の違う変数を比較しても文法上構わないのでしょうか。 (私は、「比較は必ず型の同じもの同士でしかできない」と思っていました。) 左辺はchar型のように見えて、じつはint型ですか。 #include <stdio.h> int main(void) { char a[4]; int i=77; printf("sizeof(int)は%d\n", sizeof(int)); printf("sizeof(char)は%d\n", sizeof(char)); printf("sizeof('M')は%d\n", sizeof('M')); printf("sizeof(a[0])は%d\n", sizeof(a[0])); a[0]='M'; a[1]=7+6; a[2]=a[0]+a[1]; printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */ printf("sizeof(+a[0])=%d\n", sizeof(+a[0])); if(a[0]==i) /* char型とint型の比較(?) */ puts("a[0]==i"); else puts("a[0]!=i"); return(0); } ちなみにワーニングもエラーもなんにもでません。

  • 構造体の構造体 引数

    構造体の中の構造体の関数の引き渡し方法がわかりません。 下記ソースで試したのですが、うまくいきませんでした。 助言お願いいたします。 //repo.c #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #define NUM 20 #define MAX 15 struct seiseki{ float shu[3]; }; struct seito{ char name[NUM]; int age; struct seiseki kekka; }; void input(struct seito *p); void s_input(struct seiseki *p); void ss_input(struct seiseki *data); int main(){ int i; struct seito data[2]; for(i=0;i<2;i++){ printf("------------------------------\n"); printf("%d人目",i+1); input(&data[i]); } printf("%f\n",data[0].kekka.shu[0]); printf("%f\n",data[0].kekka.shu[1]); printf("%f\n",data[0].kekka.shu[2]); //data[1]に格納できない。 printf("%f\n",data[1].kekka.shu[0]); printf("%f\n",data[1].kekka.shu[1]); printf("%f\n",data[1].kekka.shu[2]); return 0; } void input(struct seito *p){ printf("名前->"); scanf("%s",p->name); printf("年齢->"); scanf("%d",p->age); s_input(&(p->kekka)); } void s_input(struct seiseki *data){ printf("国語->"); ss_input(data); printf("算数->"); ss_input(data); printf("英語->"); ss_input(data); } //下記関数で成績をchar型で受け取り、数値化したい。 void ss_input(struct seiseki *data){ char p[100]; int i=0; static int o=0; scanf("%s",p); while( p[i] != '\0'){ if(isdigit(p[i])==0){ printf("再入力してください"); scanf("%s",p); } i++; } data->shu[o]=atof(p); printf("%f\n",data->shu[o]); o++; }

  • リストの削除について(構造体)

    リストの削除のプログラムを実行して行ってみると、リストの削除処理中にプログラムが終わって変更後処理がうまく表示されません。どこが間違っているかが分からないしだいです。返答のほどよろしくお願いいたします。 #include<stdio.h> #include<malloc.h> #include<string.h> struct list{ char name[20]; int age; struct list *next; }; void main(void) { struct list *head, *p, *n, *old; char key[20]; /*ダミーノード作成*/ head = (struct list*)malloc(sizeof(struct list)); old = head; while(p = (struct list*)malloc(sizeof(struct list)), printf("name age入力\n"), scanf("%s %d", p -> name, &p -> age) != EOF){ old -> next = p; old = p; } free(p); old -> next = NULL; p = head -> next; printf("変更前リスト\n"); while(p != NULL){ printf("name:%s age:%d\n",p -> name, p -> age); p = p -> next; } printf("削除key入力(name)\n"); gets(key); n = head; while(n != NULL){ old = n; n = n -> next; //printf("n -> name %s\n", n -> name); if(strcmp(n -> name, key) == 0){ printf("%s削除\n", key); //printf("n -> name %s old -> name %s\n", n -> name, old -> name); old -> next = n -> next; } } p = head -> next; printf("変更後リスト\n"); while(p != NULL){ printf("name:%s age:%d\n", p -> name, p -> age); p = p -> next; } }

  • C言語 「構造体のソートと結果のファイル出力」 緊急です。助けてください。

    授業で課題が出され内容は以下となってます。 1.歴代アメリカ大統領の情報を構造体とする. 2.ソートを昇順で行うこと 3.結果を出力すること〔参考:http://www-it.sci.waseda.ac.jp/CPR1/class08/kekka.log) 以下が自分で作ってみたものですが、多数のエラーが出てしまいどうしたらいいのか分かりません。。。抜本的な変更でもかまいませんので、分かる方助けてください。 -----作成分------ #include <stdio.h> #include <string.h> struct president { int no, age; char name1[20], name2[20]; /* 氏名 */ }; int main(void) { int i; struct president pre1[44] = { {1,57,"George","Washington"}, {2,61,"John","Adams"}, {3,57,"Thomas","Jefferson"}, //リストが長いので省略// {44,47,"Barack","Obama"}, }; struct president *pres; pres = pre1; //ポインタ// sort(pres, 44, sizeof(struct president), president_cmp);//ソート構文 エラーがでます。。。// printf("---------sortted list by age------- \n # age first last \n");} for (i = 0; i < 44; i++){printf("------------------------------------ \n") printf("%d %d %s %s \n, pres[i]->no, pres[i]->name, pres[i]->name1, pres[i]->name2);} for(i = 0; i < 44; i++) { if (i==0){printf("---------list of presidents---------- \n");//RAW DATAの表示を行ない。ここは問題ないみたいです// printf(" age first last \n");}; printf("%d %d %s %s \n", pres->no, pres->age, pres->name1, pres->name2); ++pres; } return 0; } int president_cmp(const void*p1, const void*p2){ //比較関数// struct president *cmp1 = (struct president*)p1; struct president *cmp2 = (struct president*)p2; return strcmp(cmp1->age, cmp2->age); } ここにファイル出力の分をたしたいのですが、どこにどうすればいいのでしょう。 大変申し訳ありませんが、緊急です!!お願いします。

  • 構造体とポインタについて教えてください。

    #include <stdio.h> typedef struct ningen { char *name; char *sex; int age; } NINGEN; NINGEN data = {"牧村 五郎",NULL,30}; char mf[2][3] = {"男","女"}; void main(void) { data.sex=mf[0]; printf("%s (%s) %d歳\n", data.name, data.sex, data.age); } このプログラムで実行結果は 牧村 五郎 (男) 30歳 となるのですが、最初の typedef struct ningen { char *name; char *sex; int age; } NINGEN; のところで、nameとsexはアドレスで宣言しているので printf("%s (%s) %d歳\n", data.naem, data.sex, data.age);でのdata.naem, data.sexでの対象もアドレスを示していると思うのですが、 結果は値を表示しているのはなぜでしょうか?