細々と半年ほど柴田望洋氏の「明解C言語 入門編」でC言語の勉強をしております。
最近構造体について勉強しはじめ、プログラム実行時の日付を出力するプログラムがテキストに載っていて、以下がその関数です。
void put_date(void)
{
time_t current;
struct tm *local;
char wday_name[][3] = { "日", "月", "火", "水", "木", "金", "土" }; /*-- [][3]?? --*/
time(¤t);
local = localtime(¤t);
printf("%4d年%02d月%02d日(%s)", local->tm_year + 1900, local->tm_mon + 1, local->tm_mday, wday_name[local->tm_wday]);
}
これの曜日を格納する配列wday_name[][3]は、どうしてこのような宣言をするのでしょうか?
wday_name[][7]にすると何か間違っているのですか? 自分で後者の方で実行してみたところ、特に動作に違いは見られませんでした。
どうぞよろしくお願い致します。
No.1ベストアンサー
- 回答日時:
wday_name[][3]
としているのは各曜日をあらわす文字が3つで足りるからです。
漢字1文字でchar2つ分、それに文字列の終わりを示すNULL文字を追加して合計3つです。
wday_name[][7]としても違いが無いのは、7つ分確保して残りの4つ分を利用していないからです。
この宣言を省略せずに書けば、
wday_name[7][3]
となります。この場合charが3つ分の領域をもつ配列を7個分確保していることとなります。
素早い回答どうもありがとうございます。
なるほど、3というのは配列の大きさを定義しているのですね。7にしても動作が同じなのは当然ですね。
逆に2以下にした時はちゃんと動作しなかったのもこれで納得がいきました。
No.5
- 回答日時:
質問に対する直接の回答は既に出ていますので、ちょっと異なる視点から書いてみます。
曜日を表す各文字("日"など)が何バイトになるかは処理系に依存します。ですから、より厳密に記述するには、wday_name[][3]ではなく、wday_name[][MB_LEN_MAX+1]としなければなりません。
MB_LEN_MAXは多バイト文字の最大バイト数であり、終端のナル文字のために+1しています。バイト数自体はMB_CUR_MAXでもよいのですが、MB_CUR_MAXは定数式にはならないので配列の要素数には使えません。
なるほど、こちらの方が処理系に依存せずより良いプログラムになりますね。
文字が何バイトになるのかは処理系によって違うというのは驚きました。
No.4
- 回答日時:
wday_name[][3]の[3]は、1つの曜日を格納するサイズです。
これは、漢字1文字=2バイト+終端NULLの1バイトで、計3バイトとなります。最初の[]は、[7]とかいてもよいですが、要素を宣言された分、コンパイラが確保しますので、[]と記述しても[7][3]と同じ事になります。たぶん、貴方は、[3]を[7]にしたのは、曜日の数が7だであるからそうしたのでしょうが、[7]にすべきは、
最初の[]であって、2番目の[]ではありません。
もし、[][7]とすると、この場合は、[7][7]と同じ事になります。最初の[7]が要素の数(曜日の数)、2番目の[7]は、最低[3]以上であればよいので、[7]でも正しく動きます。もちろん、[][256]で、問題なく動きます。
はい、どうやら逆に理解をしていたようです。
wday_name[][3]を見た時、「格納する曜日が7つあるのになんで3なんだろう?」と頭をひねっていました。
わかりやすい解説をどうもありがとうございました。
No.3
- 回答日時:
>char wday_name[][3]
この定義は配列の配列。
先頭の[]は、初期化時において配列要素数をコンパイラに数えさせる記述。
後ろの[3]は、本来の型(char)の要素数。
おそらくマルチバイト環境下で曜日を示す漢字(例えば"日")を
格納するのに十分なサイズがchar*2なのでしょう。
2 + 1(0x00) = 3。
つまり、あなたの定義wday_name[][7]は、
3バイトで十分なものを7バイト確保する定義となったに過ぎません。
余分に確保しただけなので動作は変わらないはず。
間違いではないが、無駄。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- CGI perlで書いたcgiでsqliteの使い方を教えてください 2 2023/05/08 21:29
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- C言語・C++・C# スタックフレームの消滅 6 2023/05/20 12:33
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- サーバー WindowsでApache が起動しない 1 2022/11/29 12:21
- その他(プログラミング・Web制作) python flask から fastapiへの移行時のエラー対処 1 2023/02/05 12:26
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# C言語初心者 構造体 課題について 1 2023/03/10 19:30
- 英語 複数が想定される名詞を、「不定冠詞+名詞単数形」で表す可否等について 11 2022/10/21 13:38
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・好きな「お肉」は?
- ・あなたは何にトキメキますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・ハマっている「お菓子」を教えて!
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
%dなどの違い
-
プログラムによく出てくるst...
-
C++で入力した文字列から数字を...
-
WSH(VBS)でJSONの文字列を読み...
-
nullと""、\\0とEOFの違いにつ...
-
16進数を2文字ずつ配列に格納し...
-
VBA-DLLの引数受け渡しについて
-
Shift_JIS(16進)を文字に変換す...
-
シリアル通信で0x00を送信した...
-
C言語 配列の長さの上限
-
関数から配列を返すには?
-
C言語のポインタに直接アドレス...
-
VBAのプログラムで、DIAG = 1# ...
-
「#undef」と「#define」の使い...
-
Integer変数をカラにしたいので...
-
構造体のextern方法
-
セグメントエラー
-
CStringからchar*への型変換に...
-
C言語の課題が出たのですが自力...
-
配列を含む構造体の初期値について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プログラムによく出てくるst...
-
nullと""、\\0とEOFの違いにつ...
-
C++で入力した文字列から数字を...
-
WSH(VBS)でJSONの文字列を読み...
-
C#でstringをポインタとして渡す
-
TCL言語で文字列検索方法を教え...
-
%dなどの違い
-
VB6.0でのバイナリデータの扱い...
-
16進数を2文字ずつ配列に格納し...
-
[C++]WCHARの1文字目しか表示で...
-
char型配列の最大要素数
-
_tcscpy_s(wcscpy_s)の第二引数...
-
シリアル通信で0x00を送信した...
-
Shift_JIS(16進)を文字に変換す...
-
sprintf関数について教えて下さ...
-
バイナリファイル中の日本語文...
-
構造体→文字列→構造体 をする方法
-
引用符と二重引用符
-
C言語の勉強しています。すみま...
-
文字列にある特定文字の数
おすすめ情報