プロが教える店舗&オフィスのセキュリティ対策術

char name[20]と*nameの違いがまだハッキリわかりません
sizeof()で調べたら*nameの方で実行した構造体のプログラムはname[20]で実行したのに比べてバイト数なども半分になり、アドレスの間隔も変化したので、ポインタで定義したほうが良いような感じはするのですがこんな単純な理由ではないと思います。

この2種の違いがインターネットを調べても納得いく答えがだせず、教科書にも詳しく書かれていなかったので、分かる方がおられれば教えてください。



作成中のプログラムです
#include<stdio.h>
structmdcl_chk{
//charname[20];
char*name;
intage;
floatweight;
floatheight;
};

void main(void)
{
inti,x;
structmdcl_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;

for(i=0;i<5;i++){
printf("%s %d %5.1f %5.1f\n",( MC+i )->name,( MC+i )->age,( MC+i )->weight,( MC+i )->height);
}

printf("\n");
printf("Mdcl_Chk = %3d bite\n",sizeof(Mdcl_Chk));
printf("mdcl_chk = %3d bite\n",sizeof(mdcl_chk));
printf(" MC = %3d bite\n",sizeof(MC));
//アドレス表示
MC=Mdcl_Chk;
printf("\n");
for(i=0;i<5;i++){
printf("Mdcl_Chk[%d] adr = %08d %08X\n",i,MC+i,&Mdcl_Chk[i]);

}

}

A 回答 (3件)

>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種の違いがインターネットを調べても納得いく答えがだせず

どう納得ができない…のでしょう?
    • good
    • 0
この回答へのお礼

構造体に固執するばかりにポインタの領域などの内部の知識が疎かになっていました。

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

お礼日時:2010/11/14 16:21

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
....
    • good
    • 0
この回答へのお礼

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

お礼日時:2010/11/14 16:24

*nameだと,newとか,mallocとかのように動的にメモリを確保する必要があります.


が,name[20]だと,静的に20のcharacterを確保するという違いがあります.
確保方法が違うだけです.
    • good
    • 0
この回答へのお礼

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

お礼日時:2010/11/14 16:26

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!