C言語コードを日本語化した時の出来事 [プログラム一般]
次のプログラムコードはC言語で、19の次の素数を求めるプログラムで、例によってサンプルからの抜粋です。これ本当はLinuxで試していたのですが、unary演算子を日本語で置き替えたところで、エラーになってしまいました。コードはこれ二つ:訳語.h
#define 次を用意する int
#define メイン main
//#define 真 true
//#define 偽 false
#define 最初の数 startingPoint
#define 候補 candidate
#define 計算を終えた値 last
#define 整数 i
#define 平方根を取る sqrt
#define 該当するかどうか isPrime
#define プリント printf
#define より等しいか小さい <=
#define かつ &&
#define に次をプラスする +=
#define オブジェクトが等しいとき ==
#define 減算する --
#define 左に右を代入する =
#define 左より右が小さいとき <
#define 右の値を左の値で減じて行った時減じきれない値 %
次の素数.c
#include <stdio.h>
#include <math.h>
#include "訳語.h"
次を用意する メイン( )
{
次を用意する 最初の数, 次の候補, 計算を終えた値, 指定数i;
次を用意する 該当するかどうか;
// 19の次の素数を計算するプログラム
最初の数 左に右を代入する 19;
// ()の条件の時は{ }を行う。該当しない場合は順次先送り
if ( 最初の数 左より右が小さいとき 2 )
{
次の候補 左に右を代入する 2;
}
else if ( 最初の数 オブジェクトが等しいとき 2 )
{
次の候補 左に右を代入する 3;
}
else
{
次の候補 左に右を代入する 最初の数;
if (次の候補 右の値を左の値で減じて行った時減じきれない値 2 オブジェクトが等しいとき 0) /* Test only odd numbers */
次の候補 減算する;
do
{
該当するかどうか 左に右を代入する 1; /* Assume glorious success */
次の候補 に次をプラスする 2; /* Bump to the next number to test */
計算を終えた値 左に右を代入する 平方根を取る( 次の候補 ); /* We'll check to see if 次の候補 */
/* has any factors, from 2 to 計算を終えた値 */
/* Loop through odd numbers only */
for ( 指定数i 左に右を代入する 3; (指定数i より等しいか小さい 計算を終えた値) かつ 該当するかどうか; 指定数i に次をプラスする 2 )
{
if ( (次の候補 右の値を左の値で減じて行った時減じきれない値 指定数i) オブジェクトが等しいとき 0 )
該当するかどうか 左に右を代入する 0;
}
} while ( ! 該当するかどうか );
}
プリント( " %dの次の素数は %d. 満足かい?\n", 最初の数, 次の候補 );
return 0;
}
結果は:
$ cc -o 次の素数 次の素数.c
$ ./次の素
19の次の素数は 23. 満足かい? です。
今回もテストケースとしてやったまでですが、日本文としては、結構読めると思っています。がしかし、これでは丸っきり伝わらないところも出て来て、かえってダメかもの部分も有ります。
それはそれとして、気付かなかったのですが、同じgccだとばっかり思っていたのに、LinixとMacではOS依存のところがあるせいか、若干違って来るんですね。まあ、演算子を日本語にするメリットはまずないでしょうけれど、敢えてやろうとすればMacではできるということで、入門時の説明では使えるかもしれません。ただこれだと演算子の優先順位が全然見えません。表で表せばこの順番通りなはずです。
|
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
02 |
|
! |
“ |
# |
$ |
% |
& |
‘ |
( |
) |
* |
+ |
, |
- |
. |
/ |
03 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
: |
; |
< |
= |
> |
? |
04 |
@ |
A |
B |
C |
D |
E |
F |
G |
H |
I |
J |
K |
L |
M |
N |
O |
05 |
P |
Q |
R |
S |
T |
U |
V |
W |
X |
Y |
Z |
[ |
\ |
] |
^ |
_ |
06 |
‘ |
a |
b |
c |
d |
e |
f |
g |
h |
i |
j |
k |
l |
m |
n |
o |
07 |
p |
q |
r |
s |
t |
u |
v |
w |
x |
y |
z |
{ |
| |
} |
~ |
|
コンパイラーはこの順位を辿って式を、文を評価していきますから、これが見えなくなると言うことは、この方法は悪い例だと分かります。最もそれを踏まえた上での話なら別ですけど。私自身はこの並びを見るとよく出来てるなあと思うのですが、皆さんはどうでしょうか。で、もう一つ気付くことは、日本語とは不思議なもので、てにをはと言った助詞と言うものが有って、これが結構演算子と似た役割をしているのです。なので、演算子を上のように訳しても不自然さがあまり出ません。英語だと substitutionRightToLeft とかなるんでしょうか。でもこれって文ではないですよね。違いは歴然です。ま、興味が無い人にはどうでもいいんでしょうけれど。
コードに日本語の月名を列挙してみた. [プログラム一般]
前の続きで計算機にscanf()を入れようと思ったのですが、最後までPDFファイルを読むと、これはiPhone用のサンプルに使用する目的で、ありました。そこまで立ち入ると知識が乏しいので、やめて、似たようなものに月名を使ったサンプルがありましたので、こちらを日本語化してみました。コードはいじっているので、その通りではありませんが、scanf の日本語に、「入力を読み込む」を当ててみました。で、何故これを載せたかったかですが、日本語には月名に古来からの個人的には美しい名前があります。これを直接プログラムコードから呼びたかったわけです。コードはこれ:
#import <Foundation/Foundation.h>
#include <訳語.h>
// その月の日本語名と日数を表示する
int main (int argc, char *argv[])
{
自動解放プールを使用
{
列挙 月 { 睦月=1, 如月, 弥生, 卯月, 皐月, 水無月, 文月, 葉月,
長月, 神無月, 霜月, 師走 };
列挙 月 ある月;
int 日数;
ログ (@"月の番号を入力してください: ");
入力を読み込む ("%i", &ある月);
次の時切り替え (ある月)
{
次の時 1:ログ(@"睦月"); 日数=31; 中断;
次の時 3:ログ(@"弥生"); 日数=31; 中断;
次の時 5:ログ(@"皐月"); 日数=31; 中断;
次の時 7:ログ(@"文月"); 日数=31; 中断;
次の時 8:ログ(@"葉月"); 日数=31; 中断;
次の時 10:ログ(@"神無月"); 日数=31; 中断;
次の時 12:ログ(@"師走"); 日数=31; 中断;
次の時 4:ログ(@"卯月"); 日数=30; 中断;
次の時 6:ログ(@"水無月"); 日数=30; 中断;
次の時 9:ログ(@"長月"); 日数=30; 中断;
次の時 11:ログ(@"霜月"); 日数=30; 中断;
次の時 2:ログ(@"如月"); 日数=28; 中断;
default:
ログ (@"月の数字では有りません"); 日数=0; 中断;
}
次の条件の時 ( 日数 !=0 )
ログ (@"その月の日数は %iです。",日数);
次の条件の時 ( ある月==如月 )
ログ (@"...か 29 閏年であれば");
}
return 0;
}
で、このコードでは、さして月名を日本語にする必要が無いように思えますが、応用次第では、使い道はあると思っています。最後の方の、「ある月==如月は」英語では使えないはずです。で、define 定義はどこへ行ったのか、と思われる方もいるかと思いますが、いろいろ試して一々引っ張りだすのも面倒だと思い、訳語.h で/usr/include/ の中にdragdropで、ぶっ込みました。認証でパスワードだけです。再起動もログアウトも必要ありませんが、#ifndef … #endif は付け足しています。こうなれば、ライブラリ、プラグインと自分なりの関数を用意したくなるところですが、大した良いアイディアが浮かんできません。まだそこまでの余裕は生まれないと言うのが実状です。まあ、焦らずぼちぼち行きますか!
Objective-Cでの計算機プログラム日本語化の場合 [プログラム一般]
これは、o’reilyのページからfree Download したObjective-Cのサンプルコードなのですが、計算機のコードで結構スタンダードに知られているコードだと思います。これを、見辛くない程度に日本語化してみました。コードは、$ clang -o 計算機 計算機.m -framework Foundation でコンパイル済みで、結果は、50 とその通りです。
// 計算機クラスの実装
#define 自動解放プールを利用する @autoreleasepool
#define ログ NSLog
#define リリース release
#define クリア clear
#import <Foundation/Foundation.h>
@interface 計算機: NSObject
{
double 累積器;
}
// 累積器 メソッド
-(void) 累積器をセット: (double) 値;
-(void) クリア;
-(double) 累積器;
// 計算 メソッド
-(void) 足し算: (double) 値;
-(void) 引き算: (double) 値;
-(void) かけ算: (double) 値;
-(void) 割り算: (double) 値;
@end
@implementation 計算機
-(void) 累積器をセット: (double) 値
{
累積器 = 値;
}
-(void) クリア
{
累積器 = 0;
}
-(double) 累積器
{
return 累積器;
}
-(void) 足し算: (double) 値
{
累積器 += 値;
}
-(void) 引き算: (double) 値
{
累積器 -= 値;
}
-(void) かけ算: (double) 値
{
累積器 *= 値;
}
-(void) 割り算: (double) 値
{
累積器 /= 値;
}
@end
int main (int argc, char *argv[])
{
自動解放プールを利用する
{
計算機 *卓上計算 = [[計算機 alloc] init];
[卓上計算 累積器をセット: 100.0];
[卓上計算 足し算: 200.];
[卓上計算 割り算: 15.0];
[卓上計算 引き算: 10.0];
[卓上計算 かけ算: 5];
ログ (@"結果は %g", [卓上計算 累積器]);
[卓上計算 リリース];
}
return 0;
}
どうでしょうか、私的には英語で見るよりかなり見やすいのですが、まあ人それぞれなんだと思います。普通であれば入力をして計算をしてもらう使い方ですが、如何せんObjective-C自体に入力関数は有りません。ですから、C の scanf を使うわけですけど、これは後追加で、取り敢えず今回は投稿だけ。
C++サンプルオーバーロードの場合 [プログラム一般]
これは例によってサンプルを自分なりにアレンジしたものなのですが、このサンプルの主題はオーバーロードとなっていて、そのコードの一部です。よりシンプルにしました。
#include <iostream>
using namespace std;
void ディスプレイ( long ロングパラメータ );
void ディスプレイ( char *テキスト);
int main()
{
return 0;
}
void ディスプレイ( long ロングパラメータ )
{
cout << "ロングは: " << ロングパラメータ << "\n";
}
void ディスプレイ( char *テキスト)
{
cout << "テキストは: " << テキスト << "\n";
}
これをターミナルからコンパイルして実行すると、何事も無く一行改行されて、終了します。中身はまだ空っぽです。ディスプレイ関数で表示できるものに、long型とchar型の2種類用意してあります。これで、メインの中にこれら2種類の値を宣言して、ディスプレイ関数で呼び出せばその内容を表示すると言う仕組みで、それをオーバーロードということらしいです。さて何をオーバーロードさせるかと言うと、最初に宣言してあるロングパラメータとテキストです。これは、私が日本語で勝手に付けた名前です。ですので、この名前を使わないで別の名前を使わないとオーバーロードしたことにはなりません。こう追加で宣言しました。
long ロング初期値 = 12345678L;
char *新規テキスト = "エラーになる予定";
ディスプレイ( ロング初期値 );
ディスプレイ( 新規テキスト );
これを、$ clang++ -o テスト1 テスト1.cpp でやると、こんな警告が出ますが、実行ファイルは出来ました。
テスト1.cpp:11:29: warning: conversion from string literal to 'char *' is deprecated
[-Wdeprecated-writable-strings]
char *新規テキスト = "エラーになる予定";
^
1 warning generated.
この警告はあまり気にする必要がないようです。驚いたのはcoutの方で、プロトタイプで指定した値しか受け付けないと思っていたのに、最初はmainの上下の宣言が一致していれば良いようです。つまり、オーバーロード、またはオーバーライト上書きしているようです。では、<< テキスト << 新規テキストに変えるとどうなるでしょうか。やってみました。
テスト1.cpp:24:34: error: use of undeclared identifier '新規テキスト'; did you mean
'テキスト'?
cout << "テキストは: " << 新規テキスト << "\n";
^~~~~~~~~~~~
テキスト
これはさすがに、エラーでした。つまり、外部の関数はもういじれないようです。では、メインの中身はどれくらいいじれるでしょうか、ロングとは整数ですから演算子が使えるかどうか確かめてみます。
long 次のロングの値 = 150L;
long ロング = ロング初期値 + 次のロングの値;
を追加してコンパイルして実行すると、こう結果が返ってきました。
ロングは: 12345678
ロングは: 150
ロングは: 12345828
テキストは: エラーになる予定
期待通りの結果が返ってきましたが、知らない人がこの3行だけ見れば、ロングに三つの値が有るだけで、曖昧です。なので、名前を変えます。と言いたいところですが、外部の関数はもういじれないんだっけ?ここは、思案どころです。表示が順番通りであれば、「ロングは:」の部分は変数にしたいところですが、C C++にそう行った方法があったかどうか思い出せません。なので、外部関数を見直しました。二つを一纏めにして、メイン内で3回呼び出す方法です。コードとしてはこれ:
#include <iostream>
using namespace std;
void ディスプレイ(char *テキスト, long ロングパラメータ );
int main()
{
long ロング初期値 = 12345678L;
long 次のロングの値 = 150L;
long 合計のロング = ロング初期値 + 次のロングの値;
char *新規テキスト1 = "ロング初期値";
char *新規テキスト2 = "次のロングの値";
char *新規テキスト3 = "合計のロング";
ディスプレイ(新規テキスト1, ロング初期値);
ディスプレイ(新規テキスト2, 次のロングの値);
ディスプレイ(新規テキスト3, ロング初期値 + 次のロングの値 + 合計のロング);
// これは二つの値を足した二倍の数値
return 0;
}
void ディスプレイ(char *テキスト, long ロングパラメータ)
{
cout << テキスト << ロングパラメータ << "\n";
}
この結果は期待通り、
ロング初期値12345678
次のロングの値150
合計のロング24691656
と出ました。こんなことでも、結構迷いました。もっと奇麗な方法が有るのか知れませんが、今のは単に数値だから比較的思いついた発想です。では、char同士は同様に足し算できるかどうか、この場合テキスト同士足し算できるかどうか確かめました。
error: invalid operands to binary expression +は使えないようです。もし繋げたいのであれば、第二パラメータをcharに変えてやれば、繋がりました。また、ヘッダーファイルなんかでたびたび使われる「…」もどういう意味なのかこれで使って試してみました。意味としては、この先は何か定義されていても無視して結構です的なことのように思えました。
まあ日本語に変えただけで、今迄やろうとも思わなかったアイデアが生まれることもあるんですねえ!
コードを日本語化すると見えてくるもの [プログラム一般]
今回もデーブさんのサンプルコードでの説明になるのですが、日本語に置き換えると見えてくるものが有るという話です。日本語に置き換えたC++のコードはこれです。
#include <iostream>
//--------------------------------------- このクラスでは
class このクラスでは
{
public:
const short 最大名前の長さ;
short &名目数値;
short 数値;
このクラスでは( short 固定値 );
};
このクラスでは::このクラスでは( short 固定値 )
: 最大名前の長さ( 固定値 ), 名目数値( 数値 )
{
数値 = 最大名前の長さ;
std::cout << "最初の数値 = "
<< 数値 << "\n";
名目数値 += 10;
std::cout << "名目数値に変えた後の数値 = "
<< 数値 << "\n";
}
//--------------------------------------- main()
int main()
{
このクラスでは オブジェクトとして( 10 );
}
これをターミナルから実行するとこう返ってきます。
最初の数値 = 10
名目数値に変えた後の数値 = 20
で、結果だけ求めるのであれば C でも作れるのですが、C++ではクラスでの操作ができますから、これを有効活用するのがC++を使う目的になるわけです。ではやってみましょう。「このクラスでは」ではインスタンスを作れます。では値を20としたインスタンスを追加してみました。「このクラスでは オブジェクトとして( 20 ); 」こうすれば期待通り20と30が表示するかと思いきや、コンパイラーは文句を言ってきました。再定義だと。と言うことは同じ名前だとデプリケートと判断できるのであれば、別名にすれば良いわけですから、次のオブジェクトとして( 30 )を追加しました。期待通り30と40が返ってきました。
これ以上追加しても同じことなので止めるとして、これをもうちょっと機能を追加したいとかいった時、絶えず心の中で英語を繰り返さなければなりません。その手の問題に何の抵抗もない人であれば、それで良いかもしれませんが、普通の人であればもうこのサンプルはいいやって感じになるんじゃないでしょうか。日本に住んで暮らしていれば、聞こえて来る情報、会話は日本語なはずです。プログラム言語に没頭するということは、ややもすると、日本人を忘れることにもなると思います。中にはせっかくプログラミングをするのですから英語で、と言う人もいますが、英語には日本語とは逆順表記の文法も有り、根本的に矛盾するところが有ります。それが疲れるのだと思っています。まして大量のデータを扱うとなれば、尚更です。
まあ、よく周りの名の知れたソフトを見てみれば、大概外国の商品ではないですか、日本は丸っ切り無いとは言いませんが、200MBを超えるソフトとなると、ん~?でどちらかと言うと、それを日本語化するところだけ、やっている感じがするのですが。
話はそれますが、私はMacを使っているのですが、一つ疑問が湧いてくることに、Apple Japanって何をやっているところなのかなあ?と思うことが有ります。ホームページを見れば、本家のホームページをただ日本語化したようなページだし、最近はもし、アメリカのホームページから日本語入力できる機器が注文できるのであれば、キーボードも何もUS製でいいやと思っています。ようは今迄通り使えればどこから買おうが関係無しです。つまり、アップルジャパンとはアップルの日本支店だけの機能しか持っていないんじゃないかと。まあそれほどメジャー扱いでは無いにしてもです。これが、日本人が大いに関わったOSだというなら話は別ですけど、そんな話は聞いたことが有りません。まあ愚痴はこれくらいで、これからのプログラミングは日本人ならそれらしい日本語で!で行きたいかなあ、なんて。
列挙型の日本語化はどうか [プログラム一般]
小出しで申し訳ないのですが、今度はenumを列挙として日本語に変えた場合、どのくらい日本語が使えるかを試してみました。コードは単純なものですが、確かめるには十分です。そのコード:
#include <stdio.h>
#define 列挙 enum
#define プリント printf
列挙 キーテーブル{左, 右, 上, 下};
int main()
{
列挙 キーテーブル キー;
//キー = キーチェック();
キー = 左;
プリント("左 = %d\n", キー);
キー = 右;
プリント("右 = %d\n", キー);
キー = 上;
プリント("上 = %d\n", キー);
キー = 下;
プリント("下 = %d\n", キー);
return 0;
}
これを、Xcodeでビルドしても良いのですが、大げさなのでターミナルからコマンドライン
$ clang 列挙.c -o 列挙
でコンパイルすると警告無しでOKでした。結果は:
左 = 0
右 = 1
上 = 2
下 = 3 でした。ネットにあるサンプルをただ利用させてもらったものです。見ての通り、日本語に置き換えたのは、enum と printf しか有りません。この手の定数はいっぱい有るので、定義し直せば、幾らでも出てきます。直さない方が良い場合も有りますが。また、試していませんがstructも大丈夫そうです。
それで、Xcodeなのですが、この場合何と言ってもアプリケーションを作る時どうなのかです。これ、試しているのですが、コード迄はBuild Succeedと出てくるのですが、何と言ってもインターフェースビルダーのリンクでデバッガーに落ちてしまって、メッセージを確認はするものの、原因は日本語に直した部分ですから、分かりそうなもののどこが悪いのか探せません。まあ言ってしまえば、ものすごく疲れます。頼れるものが何もないのです。まだ、紹介できる段階ではないので出来ませんが、遠回りな方法を辿らなければならなくなったとしても、私の狙いは今のところそれだけですから、挑戦は続きそうです。
コードの日本語化をC++に拡張しようとした時の出来事 [プログラム一般]
今日は今迄C言語だけでテストしてきましたが、C++でも同様にできることを確認しましたので、報告迄です。ただし、これはMacだけしかできないようです。clangコマンドをインストールできるOSであれば、clang++もインストールできそうな気がしますが、記憶では今のところclang++をインストールできるのはMacだけです。
(*追記:Linuxで調べたところ、clangがインストールできれば、clang++は使えるようでした。と言うことはOSに依存しないようです。)なので、これはマックユーザだけのメッセージになりそうですが、いずれはすべて大丈夫になると思いますので、参考迄に。
今回もC++の最初の入門コードの形になるのですが、今回はメイン関数内では一切abc…を使っていません。そのように仕組みました。コードはこれ:
#include<iostream>
#define 使う using
#define ネーム空間 namespace
#define を std
#define 整数領域 int
#define メイン main
#define シーアウト cout
#define 改行 endl
#define 戻り値 return
使う ネーム空間 を;
整数領域 メイン()
{
を::シーアウト << "こんにちは、C++の世界へようこそ!" << 改行;
戻り値 0;
}
コンパイルはターミナルから $ clang++ ようこそC++.cpp -o ようこそC++
で、これもノーエラー、ノー警告です。まあズに乗ってネットからもっと参考になるサンプルがないかなあと思って、グーグルで調べると、ウインドウズようなのですがCですから共有できるだろうと思ったのが大間違い、どっとハマってしまいました。コードはこのようなものです。
/************************/
/* コンピュータ名取得 */
/************************/
#include <stdio.h>
#include <windows.h>
void main( )
{
char cpnm[MAX_COMPUTERNAME_LENGTH+1];
DWORD len;
len=MAX_COMPUTERNAME_LENGTH+1;
GetComputerName(cpnm,&len);
printf("\nこのコンピュータの名前は %s です\n",cpnm);
}
このコードには<windows.h>がありますが、それならMacにもあるだろうと高を括ってしまったわけです。ありませんでした。なので、せっかく試してみたのにできなかったことが悔しかったので、削除したwineのCodeWarriorを再びインストールし直して試してみました。コンパイルはできたのですが、警告が21も出て来て、しかもメッセージは文字化けしていて、まともに見る気もしません。この実行結果は日本語は文字化けでしたが、名前は出てきました。
「Frc-2」?アルファベットではありますが、意味が???で、このIDEは結果をテキストとして保存することができるので、その内容をテキストエディットで見ると、「このコンピュータの名前は Pro-2 です」となっていて、これだと内容通りです。2は何の2なのか分かりませんが、それなりに拾っています。win95のプログラムソフトですから、そんなもんだと思います。しかし、気付いたのはコードを例によって全部日本語に置き換えた後だったので、がっかりでした。まあそれはそれとしても、このページは文科省公認のページなんだとか?よくわかりませんが、こういう人達はWindows以外は認めない主義なのでしょうか?確かにWindowsが揺るぎない安定したOSなら話は分かりますが、こんな注意書きみたいなものも有るのです、「このexeファイルをトロイの木馬と判断するウイルスソフトがあるので云々…」ええ?Windowsって未だにウイルスソフトを入れないとダメなの?うそ〜?って言いたくなりますが、確かにwine上でも不可思議な動きをするので対応するだけで頭を抱えること屢々です。例えば、ターミナルではctrl+cでプロセスを終了させたつもりが、しばらくして何もしていないのに、かってにまた動き出すのです。ええ?タイマー?再自動起動?理解できません。コードエディターに日本語を入力する時も、入力は英語なのに入力できないかと思いきや、日本語では当然ダメだと思いきや、それの間違った変換できないアルファベットだけは打てたりと様々です。
で、話を戻しますがこれ、windows特有のコード部分ならまだ話が分かるのですが、コードの使い方なのでしょうか、Macでは結構警告が出ます。警告は次期バージョンがアップデートした時エラーに変わることも有るので、これを公開するのには注意が必要なはずですが、但し書きも有りません。それが、検索のトップに出て来るとはこれ如何に?
勘弁して〜!
縦書する時の注意点 [プログラム一般]
縦書の部分は、実は横書きで、こう書いていたのです。
最近ずっと縦書で投稿しているのですが、ブログで縦書にするとはっきり分かるところがあります。それは、自分が書いているところと自動で挿入される部分とはっきり別れるところです。つまり好むと好まないとに関わらず表示される部分とにです。ネットではやはり横書きの方が読みやすいのかも知れません。しかし、筆者が育った環境は主に縦書であり、私の購読書は縦書が殆どで、やはり縦書のほうが読み易い事は事実なのです。
まあ、こだわる必要はないんだろうし、何方かというと、縦書の方が読みやすいと思う人に読まれれば良いかなと思っています。
それで、縦書をしていて気付いたことがあるのですが、それはアルファベット表記にした時です。横書きだと例えば、I am a boy. と書いてhtmlで、つまりブラウザで見てもその通り表示されるのに対して、縦書の場合は、Iamaboy.となってスペースが表示されません。htmlでは横書きなので確かにスペースはあるのです。なので、スペースを表示する方が自然のように思いますけれども、何故なのか、ハッキリしたところが分かりません。ところがです、横書きの場合でもスペースを2回打っても表示されるのは一個だけです。これがストリングとキャラの違いなのでしょうか。私も各言語の参考書を曲がりなりにも全部持っているのですが、この手の説明に出くわしたことがありません。これも私自身の中では、西洋の神秘とでも言いましょうか謎なのですが、htmlについては、もう一つ謎があります。暗黙の了解なのでしょうがhtmlの元はjavaでjavaの参考書で足りない説明というと、何故構文の中に”#””<>”を使うことを禁じているのかです。その手の解説説明にも出くわしたことがありません。私は自己解釈でhtmlでそれを使うとコールバックが起こって、Cやjavaのオブジェクトコードに入り込んで、クラッシュしてしうからだと判断しています。つまり、ジャバは初めからブラウザを意図して作られた言語だったんだと思っています。当時は今のようなブラウザも田舎にはインターネットも無かったですから、はっきりと断定はしていませんでしたけど。まあ、たまにフィードバックしないと、頭の中が機械と同じ暴走しそうな気がして、整理しています。