細々と半年ほど柴田望洋氏の「明解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を探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
TCL言語で文字列検索方法を教え...
-
C#でstringをポインタとして渡す
-
_tcscpy_s(wcscpy_s)の第二引数...
-
C++で入力した文字列から数字を...
-
プログラムによく出てくるst...
-
C言語の課題で困っています;
-
ソースコードの間違い (C言語)
-
nullと""、\\0とEOFの違いにつ...
-
コールバック関数
-
操作するラベルを動的に変化さ...
-
バイナリファイル中の日本語文...
-
%dなどの違い
-
[Excel VBA]デフォルトプロパティ
-
PIC18F26K22でsscanf関数を使い...
-
構造体→文字列→構造体 をする方法
-
char型配列の最大要素数
-
こんなことって可能なのですか...
-
アルファベットをカウント、
-
C言語についてです学籍番号、名...
-
VB6.0でのバイナリデータの扱い...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C++で入力した文字列から数字を...
-
nullと""、\\0とEOFの違いにつ...
-
プログラムによく出てくるst...
-
%dなどの違い
-
WSH(VBS)でJSONの文字列を読み...
-
TCL言語で文字列検索方法を教え...
-
C#でstringをポインタとして渡す
-
16進数を2文字ずつ配列に格納し...
-
_tcscpy_s(wcscpy_s)の第二引数...
-
C++で文字列の右端から特定の文...
-
シリアル通信で0x00を送信した...
-
VBA-DLLの引数受け渡しについて
-
数字の入った配列をファイルへ...
-
c#で他のアプリの文字入力フォ...
-
構造体→文字列→構造体 をする方法
-
Shift_JIS(16進)を文字に変換す...
-
バイナリファイル中の日本語文...
-
C言語の課題で困っています;
-
[C++]WCHARの1文字目しか表示で...
-
VB6.0でのバイナリデータの扱い...
おすすめ情報