🌻天国にいけるC++言語入門🌻 進化し続けるオブジェクト指向プログラミング ver3.2307
char型の配列にひらがなの文字列を格納してみます そのときひらがなの文字列はchar型の配列内に生成された配列変数にどのように格納されているのでしょうか?
char型の配列にひらがなの文字列を格納してみます そのときひらがなの文字列はchar型の配列内に生成された配列変数にどのように格納されているのでしょうか?
ソーラー「あの 全角文字のひらがなって
char型配列に格納することができるのかな?
だって
char型の配列によって作られる
配列内の文字の入れ物
配列変数って
例えば
hairetuのchar型の配列宣言
char hairetu[3];
によって作られる
char型の配列変数
は
hairetu[0]
hairetu[1]
hairetu[2]
となっているけど
この
hairetu[0]
hairetu[1]
hairetu[2]
はchar型なので1バイトまでしかデータを格納できないはずだよね
あんまり関係ないかもしれないけど
前のエピソードで次のような例があったよね。
#include <iostream>
using namespace std;
int main() {
char a='あ';
cout<<a<<"\n";
return 0;
}
このプログラムをビルド実行すると
警告 C4305 '初期化中': 'int' から 'char' へ切り詰めます。
警告 C4309 '初期化中': 定数値が切り捨てられました。
と表示されますが
コマンドプロンプト画面に
・
が表示されます
____________________________________________________
警告 C4309 '初期化中': 定数値が切り捨てられました。
警告 C4305 '初期化中': 'int' から 'char' へ切り詰めます。
は
"2バイト文字である'あ'から1バイト分だけデータをchar型に格納している"
ということを警告しています。
このことは後述されます。
solarplexussより
____________________________________________________
ソーラー「
このように なんか
ひらがなは
うまくchar型の変数aに格納できなかったよね」
てんC「はい そうでしたね。
それでは
実際に
char型の配列に
ひらがな ねこねこ の文字列を
格納してみましょう。ソーラーさん。😊
プログラムを以下のように構成してみました。
#include <iostream>
using namespace std;
int main() {
char hairetu[]="ねこねこ";
cout<< hairetu<<"\n";
return 0;
}
てんC「ビルドっ」
ソーラー「おっとっとっ」
ソーラー「てんC おっとっと
ていう おかしを
ビルドをきいておもいだしちゃったな」
ビルド実行結果
ねこねこ
ソーラー「おおぅ ひらがなもchar型の配列に格納できてるね」
てんC「ひらがなもchar型の配列に格納できるのですの
簡単でした。」
ソーラー「このとき
char型の配列変数宣言、初期化
char hairetu[]="ねこねこ";
によって生成される配列変数は
次のように
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
hairetu[5]
hairetu[6]
hairetu[7]
hairetu[8]
の9つになるんじゃないかな?
ひらがな1文字は2バイト文字だから
ねこねこは合計8バイトのデータ量をもつことになる。
8バイトのデータ量を格納するには
1バイトのデータを格納できるchar型の配列変数が8つ
hairetu[0]👈1バイトのデータ格納容量をもちます
hairetu[1]👈1バイトのデータ格納容量をもちます
hairetu[2]👈1バイトのデータ格納容量をもちます
hairetu[3]👈1バイトのデータ格納容量をもちます
hairetu[4]👈1バイトのデータ格納容量をもちます
hairetu[5]👈1バイトのデータ格納容量をもちます
hairetu[6]👈1バイトのデータ格納容量をもちます
hairetu[7]👈1バイトのデータ格納容量をもちます
いるはずだよね。
それに
ねこねこを
まとまった1つの文字列とコンピュータに認識させるのに
ヌル文字\0
も
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
hairetu[5]
hairetu[6]
hairetu[7]
に格納された
ねこねこにつづいて
char型の配列変数
hairetu[8]
に格納させる必要があるので
文字列 ねこねこ を配列に格納するには
合計9個のchar型の配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
hairetu[5]
hairetu[6]
hairetu[7]
hairetu[8]
が必要になると思うんだ。
さて
どのようにひらがなの文字列データ
"ねこねこ"
は
これらの
配列変数に格納されているのかな?
1バイト文字ずつしか
char型の配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
hairetu[5]
hairetu[6]
hairetu[7]
hairetu[8]
には格納できないよね。
2バイト文字のひらがなをどうやって格納しているのかな?
🌞
ソーラーはねこねこのデータ量
8バイト
それにねこねこのあとに
ねこねこを文字列とするためにつけられるヌル文字\0のデータ量
1バイト
合計9バイト
をchar型配列に格納しようとしているので
char型の配列には
1バイトの文字データを格納する
char型の配列変数が9バイト分
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
hairetu[5]
hairetu[6]
hairetu[7]
hairetu[8]
の9つ用意されると予想しています
🌞
てんC「それでは
char型の配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
hairetu[5]
hairetu[6]
hairetu[7]
hairetu[8]
にどのようにひらがなのデータが格納されているか
char型の配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
hairetu[5]
hairetu[6]
hairetu[7]
hairetu[8]
に格納されているデータを
直接
cout出力表示してみます。
プログラムを以下のように構成しました。
文字列データ"かくかく"をchar型の配列hairetuに格納しています。」
#include <iostream>
using namespace std;
int main() {
char hairetu[] = "かくかく";
cout << hairetu[0] << "\n";
cout << hairetu[1] << "\n";
cout << hairetu[2] << "\n";
cout << hairetu[3] << "\n";
cout << hairetu[4] << "\n";
cout << hairetu[5] << "\n";
cout << hairetu[6] << "\n";
cout << hairetu[7] << "\n";
cout << hairetu[8] << "\n";
return 0;
}
ソーラー「それでは ビルド実行すると・・・」
ビルド実行結果
・
ゥ
・
ュ
・
ゥ
・
ュ
(空白)
続行するには何かキーを押してください . . ._
ソーラー
「
〘か〙 が
・
ゥ
で
〘く〙 が
・
ュ
にあたるのかな?
コンパイル結果の
〘ュ〙
と
〘続行するには何かキーを押してください . . ._〙
の間が空白スペースになっているのは
\0がcout出力表示されると
空白が表示されるからだね。」
てんC「
ひらがな か の画像データ情報を呼び出すためのデータが
メモリ内で
次のように2バイト(16ビット)
0100101010101010で表されているとすると
char hairetu[]="かくかく";
によって生成されるchar型の配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
hairetu[5]
hairetu[6]
hairetu[7]
hairetu[8]
の
まずは
hairetu[0]に
0100101010101010の右から8ビット分(1バイト分)の
10101010が収められ
その次に
hairetu[1]に
0100101010101010の左から8ビット分(1バイト分)の
01001010がおさめられているとおもわれます。
つまり
画像データ か の
データ情報を呼び出すためのデータが
0100101010101010の
2バイトの情報量をもっていたとしても
hairetu[0]
hairetu[1]
を通して
1バイトずつ分割して
メモリに格納されているのではないでしょうか?
hairetu[0]だけに
画像データ か
を
格納しなくても
つまり
hairetu[0]だけを通して
画像データ か の
データ情報を呼び出すためのデータ
0100101010101010
を
メモリに格納しなくてもよいわけですね。
1バイトしか格納容量のないchar型 の変数a
に ひらがな か を格納するときとは違い
このように ひらがな か も
配列charの配列変数に分割して
格納することができるわけです。
そして
hairetu[0]のアクセスしているメモリには01001010
hairetu[1]のアクセスしているメモリには10101010
と分割して格納されたデータを
cout << hairetu[0] << "\n";
cout << hairetu[1] << "\n";
とcout出力表示すると
01001010
10101010
に対応した画像データ
・
ゥ
が表示されるのではないでしょうか?」
ソーラー「そんな感じがするね😊」
てんC「もう1つ
ひらがなの文字列 るんるんは どのように
char型の配列変数宣言
char hairetu[]="るんるん";
によって生成される配列変数
hairetu[0]
hairetu[1]
hairetu[2]
hairetu[3]
hairetu[4]
hairetu[5]
hairetu[6]
hairetu[7]
hairetu[8]
に格納されているか試してみます。
以下のようにプログラムを構成して
#include <iostream>
using namespace std;
int main() {
char hairetu[] = "るんるん";
cout << hairetu[0] << "\n";
cout << hairetu[1] << "\n";
cout << hairetu[2] << "\n";
cout << hairetu[3] << "\n";
cout << hairetu[4] << "\n";
cout << hairetu[5] << "\n";
cout << hairetu[6] << "\n";
cout << hairetu[7] << "\n";
cout << hairetu[8] << "\n";
return 0;
}
ソーラー「ビルドすると・・」
ビルド実行結果
空白
空白
空白
空白
空白
空白
空白
空白
空白
ソーラー「??どうなってるのかな これ?」
てんC「おそらく画像データ る の
データ情報が
1001101010101101(2バイト)で表現されていると
すると
そのままでは
1バイトしかデータ容量をもたないchar型の配列変数には
格納できないので
hairetu[0]に1001101010101101の右から1バイト(8ビット)分の10101101
を格納
hairetu[1]に1001101010101101の左から1バイト(8ビット)分の10011010
を格納
という具合に
1バイトずつ分割して
格納しているのではないでしょうか?
そして
cout << hairetu[0] << "\n";
cout << hairetu[1] << "\n";
を実行するとビルド実行結果が
空白
空白
と
同じ
空白
が表示されていますね。
hairetu[0]
hairetu[1]
をとおしてメモリに格納されているデータは
格納されている数値は
10011010
10101101
とそれぞれ違うのに
同じ空白が表示されるのは
ある数値データには半角英数字などの記号が割り当てられていますが
それ以外の数値
この場合の
10011010
10101101
のようなものには
すべて
空白
が割り当てられているからでないでしょうか
ソーラーさん😊」
ソーラー「おぉっ そうかもしれないね
トレビアーンだね」
まだまだ💖
このお話は仮説の段階となっています。
C言語では
char型の配列hairetuに
char hairetu[] = "るんるん";
と格納された文字列データ"るんるん"
を
printf("%c\n", hairetu[0]);
printf("%c\n", hairetu[1]);
printf("%c\n", hairetu[2]);
printf("%c\n", hairetu[3]);
printf("%c\n", hairetu[4]);
printf("%c\n", hairetu[5]);
printf("%c\n", hairetu[6]);
printf("%c\n", hairetu[7]);
printf("%c\n", hairetu[8]);
printf("%c\n", hairetu[9]);
をもちいて
printf出力表示すると
コンパイル結果
・
・
・
・
・
・
・
・
が表示されます。
空白が表示されるか
・
が表示されるかの違いがあります。
おそらく
10011010
10101101
に対応する文字データ
をコンパイラは参照するのですが
参照元を
C言語ではシフトJISコード
C++言語ではユニコード
に設定しているため
このような違いがでるのではないかと・・・・・
推測しています。
つまり
シフトJISコードでは
10011010
10101101
に対応する文字データは
・
で
ユニコードでは
10011010
10101101
に対応する文字データは
空白
になっているとただいま仮説を立てています
solarplexussより
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます