変数と演算子
○変数の型
HSPの変数型は、整数型と、文字列型があったわけでした。
今後、実数型もサポートされるようですが。
C言語の変数型は、色々あるんです。基本的には、「int」を使ってればいいんですが。
整数タイプ
型名 | メモリサイズ | 表現可能な範囲 |
int | 32bit | -2147483648 〜 2147483647 |
unsigned int | 32bit | 0 〜 4294967295 |
char | 8bit | -128 〜 127 |
unsigned char | 8bit | 0 〜 256 |
short | 16bit | -32768 〜 32767 |
unsigned short | 16bit | 0 〜 65535 |
long | 32bit | -2147483648 〜 2147483647 |
unsigned long | 32bit | 0 〜 4294967295 |
実数タイプ
double | 64bit | 精度のいい実数 |
float | 32bit | 精度の悪い実数 |
おおよそこんな感じです。環境によって、メモリサイズ等が変化することも
ありますが、Windowsではたぶん全部これです。
細かいことを知りたい方は、それなりの本やサイトを当たってください。
○宣言
Cで変数を使うためには、使用する前に宣言をしておく必要があります。
宣言は
(変数型) (変数名);
のように、行います。
int main(){
int i;
i = 5;
return 0;
}
実行すると、変数iの内容が5になりましたね。
分かりませんか?
何も出力されませんが、きっとなっている筈です。
なっていると思えば、それでいいのです。
ただし、一度宣言した変数を、再び宣言することはできません。
○配列変数
int a[22360679];
と、宣言すると、int型の配列が22360679個確保できます。
添字はこの場合0〜22360678になり、3つめの要素にアクセスする時は
a[3]のようにします。
○文字列
C言語には、文字列を収納するための変数型はありません。
ただ、概念的には、C言語での文字列の取り扱いはHSPの文字列変数と
似ているところがあります。
HSPの文字列変数は、デフォルトで64byte、sdim命令を使うとサイズの変更が
出来るというように、文字列用のメモリを確保するという感覚がありました。
同様の感覚でGoしますと、C言語の場合は、
char str[64]; /* strは変数名 */
のように変数宣言をすることで、文字列用のメモリを64バイト確保することができます。
言うまでもなく、これはchar型の配列変数strの宣言であります。
C言語では基本的に、文字列はchar型の配列で実現します。
ただ、もう少し厳密に言うと、連続したメモリ領域を使って文字列情報を保存して
おくわけで、配列変数でなければならないというわけではありません。
さらに、実用上の注意です。
C言語では
str = "mojiretu" ×
このような方法で、配列変数strに対して文字列を一括代入することはできません。
目的の処理を行うには、標準ライブラリ関数の
strcpy(str,"mojiretu");
strcpyを使えば可能です。
(Win32APIには、同じ用法のlstrcpyがあります。)
C言語では
str += "mojiretu" ×
このような方法で、strに対して文字列の付加を行うことはできません。
目的の処理を行うには、標準ライブラリ関数の
strcat(str,"mojiretu");
strcatを使えば可能です。
(Win32APIには、同じ用法のlstrcatがあります。)
もちろんC言語では
str = "moji"+"retu" ×
このような文字列の結合も出来ません。
同じ目的を達成するには、sprintf関数が有効ですが、説明は省略します。
(Win32APIには、同じ用法のwsprintfがあります。)
以上、文字列処理についてのうわっつらな情報を並べてみました。
ポインタの章で、もう一度詳しく触れます。
○グローバル変数
HSP@ver2.5では、モジュール領域を除けば、変数はすべてグローバル変数です。が
C言語では。
関数の外で宣言された変数
int val_global;
int main(){
return 0;
}
変数val_globalは、グローバル変数になります。
グローバル変数は、ソースコード内のどこからでもアクセスすることが出来ます。
関数内で宣言された変数
int main(){
int l;
return 0;
}
変数lは、ローカル変数になります。ローカル変数は、宣言された関数内でのみ
アクセスすることが出来ます。
変数名が競合しない場合、例えば別の関数同士なら、
名前が同じ変数を使っても構いません。
この場合、たとえ同じ名前でも、それぞれは別の変数として取り扱われます。
○基本的な演算子
+ たしざん
- ひきざん
* かけざん
/ わりざん
小2対象ですか?
% じょうよざん
整数を整数で割った余りを返します。HSPの「\」演算子と同じです。
HSPにどっぷり漬かっている方は、多分ここが一番尾をひきます。
というか、私はひきまくりました。
++ インクリメント
-- デクリメント
後置、前置などがありますが、詳しい説明は省略します。
例えば、変数aの値が3の時、
a++;
とすると、aの値が1つ増えて4になります。
a--;
とすると、aの値が1つ減って2になります。
<< 左シフト
>> 右シフト
& ビットAND
| ビットOR
^ ビットXOR
~ 右要素のビット反転
わかる人は使ってください。
○条件判断に使う演算子
HSP歴の長い人は注意してください。
HSPはif文で条件判断を行う際、変数aとbが等しいことを判断するのに
「=」が利用できますが、Cの場合は「==」を使う必要があります。
間違えて「=」を使ってしまった場合でも、↓で紹介する代入演算子と
判断されて、エラーが出ずに誤った処理を行ってしまいます。
if(piano == hiketa){
printf("きみに伝えることだろう");
}
また、「!」も別の意味で使われます。「!=」を使ってください。
== 左右が等しければ真
!= 左右が異なれば真
< 右が大きければ真
> 左が大きければ真
<= 右が左以上ならば真
>= 左が右以上ならば真
○代入演算子
= 左の変数に右の値を代入する。式としては代入された値を返す。
HSPでは、代入文で代入を行いますが、Cでは代入式で代入を行います。
式で代入を行える場合、代入の処理を配置できる場所が非常に柔軟になります。
例えば、Cの場合は
*(p = q) = (a = b = 8) + 4
このような処理を書くこともできます。「=」の処理はすべて代入です。
また、状況によっては、
if(a = b){
…
}
いかにも比較を行いそうな場所で敢えて代入処理を行う可能性もあります。
これは、aにbの値を代入し、なおかつその値が真である場合はブロック内の
処理を行うというものです。
というわけで、HSPのように代入の行われるべき位置を特定することが出来ないため
代入と比較の演算子は明確に区別する必要があるわけです。
だからね、間違えてもエラーがでないんよ。
怪しい部分は警告してくれるコンパイラもあるみたいだけどね。
○他の代入系演算子
+=,-=,*=,/=,%=,<<=,>>=,&=,|=,^=
計算と代入を同時に行います。
a += 5;
この文は、変数aに5を足します。
aがもともと2だったら、この処理の結果aは7になります。
a *= 5;
aがもともと2だったら、この処理の結果aは10になります。
a /= 5;
aがもともと2だったら、この処理の結果aは0になります。
もういいっちゅうねん。
○論理系演算子
これがHSPになくて、少し困ることがあります。
&& かつ
|| または
! 否定(単項演算子)
使い方としては、条件文で
if((month == 12)&&(day == 31)){
printf("くれ。");
}
(monthが12)なおかつ(dayが31)の時に、「くれ。」が出力される、ゆうことです。
「&&」演算子の機能をチャート式に説明しますと、
1.左の式を評価し、値が 真→2.にGo! 偽→4.にGo!
2.右の式を評価し、値が 真→3.にGo! 偽→4.にGo!
3.全体の値として真を返す
4.全体の値として偽を返す
むしろわかりにくいですか。
ちなみに、左右の式が0または1であることが保証されていれば、いちおう
「&」でも対応できますから、HSPではそうやって条件判断をしていたわけです。
「||」の説明はスキップ。
「!」は、右の式の真偽を逆転します。
if(!(TRUE)){
printf("ここには来ない〜(;_;)");
}
判定は非真、要するに偽になります。
○演算子の優先順位
HSPでは式は左から評価されますが、
1+2*3-4 (= 5 @HSP)
Cでは演算子によって優先順位があります。
1+2*3-4 (= 3 @C)
で、Cの攻略本などに優先順位の表が載ってるので、それを見てください。
基本的には、優先順位の高いほうから
単項系>乗除>加減>ビットシフト>比較>ビット演算>論理>代入
で、なんか微妙っぽいところは括弧を付けとく。でいいんじゃないかと。