ページ 11

配列の要素数(大きさ?)プラス雑談

Posted: 2010年5月16日(日) 01:11
by ムンバ
こんばんはっ!

先日は、ご迷惑をお掛けしまして、大変申し訳御座いませんでした。(_ _)
相変わらず質問ばかりのプログラマーで、すみません。
気が付いたら「熟練のプログラマー」に昇進してますが
「熟練の質問するだけのプログラマー」ですので、お許し下さい。w

添付させて頂いたファイルは、sprintf関数について、後々
自分が見て理解できる様に(すぐ忘れるから)、自分向けに作った例文(ソース)です。
ここでは、ポインタは使いません。
(環境:Windows NT VC++2008(SP1))

#include <stdio.h>

int main(){

char str_all[36+11];

char no[2+1] = "の"; // 2バイト
char ha[2+1] = "は"; // 2バイト
char ten[2+1] = "、"; // 2バイト
char maru[2+1] = "。"; // 2バイト

char str1[2+1] = "今"; // 2バイト
char str2[8+1] = "総理大臣"; // 8バイト
char str3[6+1] = "民主党"; // 6バイト
char str4[8+1] = "鳩山さん"; // 8バイト
char str5[4+1] = "です"; // 4バイト

---修正部位(↓straii → str_all)---

sprintf(str_all, "%s%s%s%s%s%s%s%s%s%s", str1, no, str2, ha, ten, str3, no, str4, str5, maru);
// 表示結果:今の総理大臣は、鳩山さんです。

printf("%s\n\n", str_all);

return 0;
}

添付したソースを、色々いじって遊んでいます。
結果、配列の値は上述の様になって、実行できました。
(環境:Windows NT VC++2008(SP1))

質問1:各配列の要素数(大きさ?)で、無駄にメモリ(バイト数)を使ってる箇所はありますか?
質問2:各配列の要素数(大きさ?)で、メモリ(バイト数)が足りない箇所はありますか?
質問3:各配列の[/url]内の +1 ([36+11]を除く)は、ヌル文字「\0」または「NULL」が入るのでしょうか?
質問4:char str_all[36+11]; の +11 は、char型を宣言で10個用意したので +1 で +11 にしてみました。
   +10 でも大丈夫でしょうか? 

どうも頭がごちゃごちゃになっていて、配列の要素数の整理が付かなくなってしまいました。
sprintf関数の質問ではなく、配列の質問です。
これって、ノイローゼーなのですかね?^^;

質問5:質問4で、「char型を宣言で10個用意したので +1 で +11 にしてみました。」
    と質問してますが、質問の意味が解りますでしょうか?


     画像

Re:配列の要素数(大きさ?)プラス雑談

Posted: 2010年5月16日(日) 01:27
by box
> 質問1:各配列の要素数(大きさ?)で、無駄にメモリ(バイト数)を使ってる箇所はありますか?

はい。
str_all[/url]です。

> 質問2:各配列の要素数(大きさ?)で、メモリ(バイト数)が足りない箇所はありますか?

いいえ。
ただ、no[/url]~str5[/url]の配列要素数は省略できます。例えば、
char no[/url] = "の";
と書けば、コンピューターが自動的に3バイト確保してくれます。
自分でバイト数を数えるより、コンピューターに数えさせる方が楽だし、
間違いないですよね。

> 質問3:各配列の[/url]内の +1 ([36+11]を除く)は、ヌル文字「\0」または「NULL」が入るのでしょうか?

'\0'が入ります。NULLは入りません。
'\0'とNULLとは、全く別のものです。

> 質問4:char str_all[36+11]; の +11 は、char型を宣言で10個用意したので +1 で +11 にしてみました。
>    +10 でも大丈夫でしょうか? 

+1でじゅうぶんです。

Re:配列の要素数(大きさ?)プラス雑談

Posted: 2010年5月16日(日) 01:51
by たかぎ
この手の問題を考えるときは、いくつかの点を考慮しなければなりません。

各配列の内容は変わることがありますか?
もし、次の総選挙後に、たちあがれ日本の与謝野さんが総理大臣になったらどうするのでしょう?

もうひとつはエンコーディングの問題です。
VC++2008とのことなので、シフトJISに決め打ちになっているのでしょうが、移植性は皆無です。
わかっていてやっているのなら構いませんが、一般的な理解を目指すのであれば不十分です。

Re:配列の要素数(大きさ?)プラス雑談

Posted: 2010年5月16日(日) 02:06
by ムンバ
boxさん、早速のご返答、ありがとうございます。
ご解説、悩む(調べる)時間下さい。

特に

>>'\0'とNULLとは、全く別のものです。<(ヌル文字とNULL)
>> +1でじゅうぶんです。<(配列)

ありがとうございます。
今日は、寝てしまいます。すみません。
おやすみなさい。<(_ _)>

Re:配列の要素数(大きさ?)プラス雑談

Posted: 2010年5月16日(日) 02:38
by ムンバ
たかぎさん、こんばんは。
すみません。
レスさせて頂いていたので、気が付きませんでした。<(_ _)>

boxさん、たかぎさん、詳細は後日、必ずご返信させて頂きます。

ん?むむっ?
次の総理大臣が与謝野さんになった時は・・・
もしかしたら、高速道路の料金が、統一1円になってたり
働かなくても、毎月50万円の生活費が知らぬ間に、自分の口座に入ってたり・・・
とかですか?

つまり、+1 がプラスになる事もありマイナスになる事にもなる?

>>各配列の内容は変わることがありますか?
 政治家は、常に変わると思います。

>>もし、次の総選挙後に、たちあがれ日本の与謝野さんが総理大臣になったらどうするのでしょう?
 総理大臣の「名前」が変わるだけかと私は思います。w

ごめんなさい。改めてレスさせて頂きます。
おやすみなさい!ε=ε=┏( ^_^)┛

Re:配列の要素数(大きさ?)プラス雑談

Posted: 2010年5月16日(日) 09:14
by たかぎ
> 総理大臣の「名前」が変わるだけかと私は思います。w

なぜ、"たちあがれ日本"の"与謝野さん"と書いたかを考えてください。
"民主党"(3文字)、鳩山さん(4文字)分の領域しかないところに、"たちあがれ日本"(7文字)、"与謝野さん"(5文字)をどうやって格納するのでしょう?

Re:配列の要素数(大きさ?)プラス雑談

Posted: 2010年5月16日(日) 11:44
by ムンバ
おはようございます。

boxさん、ありがとうございます。

>>'\0'とNULLとは、全く別のものです。<(ヌル文字とNULL)
 了解しました。ありがとうございます。
 [/url]内、省略できるのは、勉強済みです。
 そこで、char str_all[36+11]; なのですが
 +3 までは普通に実行できたのですが、
 +2 と +1 では、私の環境ではデバックエラー表示が出てしまいます。
 環境依存?って事なのでしょうか?

たかぎさん、ありがとうございます。

>>各配列の内容は変わることがありますか?
>>わかっていてやっているのなら構いませんが(略)
 あっ、いや。言葉が足りなくてすみません。
 各配列の内容を変えながら、配列の要素数も変えて遊んでいたら
 今回の疑問が出たので、質問させて頂きました。
>>なぜ、"たちあがれ日本"の"与謝野さん"と書いたかを考えてください。
 タイトルに「・・・プラス雑談」とさせて頂いたので
 ブラックジョークかと思って答えてしまったのですが・・・。(汗
 char str4[10+1] = "与謝野さん"; // 10バイト  
 で、合ってますか?
 
となると、全体的には char str_all[36+11];
の +11 の所が、賢くないと言う事になるのでしょうか?

あと、エンコーディングの問題が解りません。(←編集・追加させて頂きました。)

---追加---
レスもれなど、御座いましたら申し訳御座いません。
ご指摘頂けます様、宜しくお願い致します。
(久々に、カレーハウスCoCo壱番屋の宅配待ちです。<10辛 ^^)  画像

Re:配列の要素数(大きさ?)プラス雑談

Posted: 2010年5月16日(日) 12:13
by たかぎ
> ブラックジョークかと思って答えてしまったのですが・・・。(汗

ブラックジョークということはないと思いますよ。
反民主連立政権ができれば、平沼さんを擁立する可能性が出てきますが、健康問題を考えると与謝野さんに白羽の矢が立つ可能性はゼロではありません。自民以外から首相を出すのであれば、舛添さんは参議院議員ですし、山田さんはそもそも国会議員ではありません。渡辺さんは連立に加わるかどうかも怪しいです。だとすると...
実際には、そんな深読みをして挙げた名前ではなく、姓が三文字の国会議員といえば真っ先に思いつくのが与謝野さんだっただけです。

いずれにせよ...

> もしかしたら、高速道路の料金が、統一1円になってたり
> 働かなくても、毎月50万円の生活費が知らぬ間に、自分の口座に入ってたり・・・

こういうのはあり得ませんね。

> char str4[10+1] = "与謝野さん"; // 10バイト  
> で、合ってますか?

そのやり方だと、総理大臣がかわるたびに再コンパイルが必要になりますが、そういう意図なのでしょうか?
実行時に名前を変えるつもりであれば、十分な大きさの配列を用意するか、その都度malloc等で動的に割りつける必要があります。

Re:配列の要素数(大きさ?)プラス雑談

Posted: 2010年5月16日(日) 12:16
by たかぎ
> あと、エンコーディングの問題が解りません。

WindowsではシフトJISを使いますので、多バイト文字は2バイト以内です。
けれども、Windows以外では、最近ではUTF-8を使うことが圧倒的に多くなっています。
UTF-8での漢字は3バイトが普通ですので、多バイト文字1文字を2バイトに決め打ちするのは問題です。
せめて、MB_LEN_MAX * 文字数とすべきではないでしょうか?

Re:配列の要素数(大きさ?)プラス雑談

Posted: 2010年5月16日(日) 13:55
by ムンバ
>>こういうのはあり得ませんね。
 ですよね。^^;

たかぎさん、再度ご解説、ありがとうございます!

>>そういう意図なのでしょうか?

 PearのCGIの変数に $ENV{'CONTENT_LENGTH'};
 という、文字などのバイト数を調べる変数があるのですが
 漢字で 1文字が、3バイトの文字があったのです。
 そこで、C言語ではどうなんだろ?と思って遊んでいるうちに疑問が浮かび
 こちらで質問させて頂きました。
 
 エンコーディングのご解説ありがとうございます。
 やはり、boxさんがおっしゃっている様に
 char str4[/url] = "鳩山さん";
 の様にした方が良さそうです。

そこで、サイズは sizeof演算子を使い、文字列はポインタを使って
サイズを調べてみました。

ちょっと見難いと思います。

#include <stdio.h>

int main(){

int s_size;

char *p_str_all[/url] = {"今", "の", "総理大臣", "は", "、", "鳩山さん", "です", "。", "\0"}; //文字表示の言葉

/*
  char str_all[36+2]; //38バイト
  char str_all[/url] = "今の総理大臣は、鳩山さんです。"; // 31バイト

  char no[/url] = "の"; // 3バイト
char ha[/url] = "は"; // 3バイト
char ten[/url] = "、"; // 3バイト
char maru[/url] = "。"; // 3バイト

char str1[/url] = "今"; // 3バイト
char str2[/url] = "総理大臣"; // 9バイト
char str3[/url] = "民主党"; // 7バイト
char str4[/url] = "鳩山さん"; // 9バイト
char str5[/url] = "です"; // 5バイト

sprintf(str_all, "%s%s%s%s%s%s%s%s%s%s", str1, no, str2, ha, ten, str3, no, str4, str5, maru);
表示結果:
今の総理大臣は、鳩山さんです。 // 39バイト
*/

int i;

for (i = 0; i < 8; i++){
printf("%s", p_str_all);
}
// 表示結果:
// 今の総理大臣は、鳩山さんです。 // 36バイト ←ポインタ使った時


printf("\n\n");

s_size = sizeof(p_str_all);
printf("バイト数:%dバイト\n\n", s_size);

return 0;
}

またまた遊んでみました。

  char str_all[/url] = "今の総理大臣は、鳩山さんです。"; // 31バイト

  char *p_str_all[/url] = {"今", "の", "総理大臣", "は", "、", "鳩山さん", "です", "。", "\0"}; // 36バイト

この、5バイトの差で悩んでます。

Re:配列の要素数(大きさ?)プラス雑談

Posted: 2010年5月16日(日) 15:05
by たかぎ
> PearのCGIの変数に $ENV{'CONTENT_LENGTH'};
> という、文字などのバイト数を調べる変数があるのですが
> 漢字で 1文字が、3バイトの文字があったのです。

Pearlですね。PEARはPHPのライブラリです。
CONTENT_LENGTHはCGIの環境変数ですが、1文字が3バイトになるのはUTF-8が使われる機会が多いということです。
ちなみにEUC-JPでも1文字が3バイトになることはあります。

> この、5バイトの差で悩んでます。

根本的なところで理解できていないように思います。
31バイトは、2バイト文字×15文字=30バイトとナル文字が1バイトで、計31買取になっています。
一方、36バイトというのは、4バイトのポインタが9個なので、4×9=36バイトになっています。
ですので、両者はまったく異なります。

Re:配列の要素数(大きさ?)プラス雑談

Posted: 2010年5月16日(日) 16:40
by nishi
WindowsはシフトJISだけではなく、Unicode(UTF-16)も存在します。

Re:配列の要素数(大きさ?)プラス雑談

Posted: 2010年5月16日(日) 16:55
by たかぎ
> WindowsはシフトJISだけではなく、Unicode(UTF-16)も存在します。

今はワイド文字の話はしていませんので、UTF-16は対象外です。

Re:配列の要素数(大きさ?)プラス雑談

Posted: 2010年5月16日(日) 19:23
by ムンバ
お二方とも、ご解説どうもありがとうございます。

正確には Perl ですね。失礼しました。(謝

>>Pealですね。PEARはPHPのライブラリです。
>>CONTENT_LENGTHはCGIの環境変数ですが、1文字が3バイトになるのはUTF-8が使われる機会が多いということで>>す。
>>ちなみにEUC-JPでも1文字が3バイトになることはあります。

 そういう事だったんですね。ためになります。

そうか!4バイトのポインタが9個で36バイトですね。
気が付きませんでした。

nishi さん、ありがとうございます。

たかぎさん、何度も貴重なお時間を割いて頂き本当にありがとうございました。
しっかり、頭に入りました。
また、へんちくりんな質問するかもしれませんが
その節は、宜しくお願い致します。
失礼します。<(_ _)>

Re:配列の要素数(大きさ?)プラス雑談

Posted: 2010年5月16日(日) 19:40
by たかぎ
> 正確には Perl ですね。

ついつられてPearlと書いてしまいましたが、Perlが正解ですね。

Re:配列の要素数(大きさ?)プラス雑談

Posted: 2010年5月16日(日) 19:52
by ムンバ
はいです。w
ありがとうございました。