7: 2007-03-22 (木) 23:44:32 |
現: 2024-01-06 (土) 22:37:40 ゲスト[htonJexNzZc] |
| | | |
| | | |
- | 1バイトは2進数で00000000〜11111111。10進数に直すと0〜255までとなる。逆に言えば、たった255しか表現できない困った単位ともいえる。 | + | 1バイトは2進数で00000000〜11111111。10進数に直すと0〜255までとなる。逆に言えば、たった256種類しか表現できない困った単位ともいえる。 |
| | | |
| でもこれじゃ不便なので、複数のバイトで1個という単位の変数が生まれた。 | | でもこれじゃ不便なので、複数のバイトで1個という単位の変数が生まれた。 |
| |long型|4バイト|かなり大きな整数|-214783648〜214783647|0x00000000〜0xFFFFFFFF|| | | |long型|4バイト|かなり大きな整数|-214783648〜214783647|0x00000000〜0xFFFFFFFF|| |
| |int型|4バイト|かなり大きな整数|-214783648〜214783647|0x00000000〜0xFFFFFFFF|どうも通常は動作している環境って単位みたい。つまり16bitCPUなら16bit、32bitCPUなら32bitとか(Cコンパイラに依存?)| | | |int型|4バイト|かなり大きな整数|-214783648〜214783647|0x00000000〜0xFFFFFFFF|どうも通常は動作している環境って単位みたい。つまり16bitCPUなら16bit、32bitCPUなら32bitとか(Cコンパイラに依存?)| |
- | |float型|4バイト|少数を扱える|少数を扱いたい場合使うらしい||| | + | |float型|4バイト|少数を扱える|小数を扱いたい場合使うらしい||| |
- | |double型|8バイト|より桁数が多い少数|||| | + | |double型|8バイト|より桁数が多い小数|||| |
| |ポインタ型|4バイト|アドレス変数|アドレスを記憶する||| | | |ポインタ型|4バイト|アドレス変数|アドレスを記憶する||| |
| | | |
| float b; | | float b; |
| char *c; | | char *c; |
| + | |
| a=0x00FF00FF; | | a=0x00FF00FF; |
| b=0x00FF00FF; | | b=0x00FF00FF; |
| c=0x00FF00FF; | | c=0x00FF00FF; |
| + | |
| /*この状態で各変数の実際の場所を覗いてみるときっとまったく同じだと思われる*/ | | /*この状態で各変数の実際の場所を覗いてみるときっとまったく同じだと思われる*/ |
| | | |
| float d; | | float d; |
| double e; | | double e; |
| + | |
| aaa = aa + a; /*同じint同士。足し算も代入もOK。*/ | | aaa = aa + a; /*同じint同士。足し算も代入もOK。*/ |
| + | |
| a = b - aa; /*おいおい! bとaaは型が違うだろ同じ4バイトでも!*/ | | a = b - aa; /*おいおい! bとaaは型が違うだろ同じ4バイトでも!*/ |
| + | |
| aaa = e; /*うわ!aaaとeじゃ型が違うしそもそもバイト数も・・・*/ | | aaa = e; /*うわ!aaaとeじゃ型が違うしそもそもバイト数も・・・*/ |
| + | |
| aa = e + d -b; /*もうなにがなんだか・・・*/ | | aa = e + d -b; /*もうなにがなんだか・・・*/ |
| | | |
| int b; | | int b; |
| int c: | | int c: |
| + | |
| a = 18; | | a = 18; |
| b = 38632; | | b = 38632; |
| + | |
| c = a + b; | | c = a + b; |
| | | |
| int b,ab; | | int b,ab; |
| int c: | | int c: |
| + | |
| a = 18; | | a = 18; |
| b = 38632; | | b = 38632; |
| + | |
| ab = (int)a; /*こうすると、char型aの値(18)はそのままに、int型に変換してくれる*/ | | ab = (int)a; /*こうすると、char型aの値(18)はそのままに、int型に変換してくれる*/ |
| + | |
| c = ab + b; /*当然int同士の足し算。そして結果をint型に代入なので、問題なし!*/ | | c = ab + b; /*当然int同士の足し算。そして結果をint型に代入なので、問題なし!*/ |
| | | |
| int b; | | int b; |
| int c: | | int c: |
| + | |
| a = 18; | | a = 18; |
| b = 38632; | | b = 38632; |
| char a; | | char a; |
| int i; | | int i; |
- | | + | |
| + | |
| for(i = 0x0010; i = 0x0014; i = i+1) | | for(i = 0x0010; i = 0x0014; i = i+1) |
| { | | { |
| p = i; | | p = i; |
| printf("データは %d 16進数だと %x だよーん!\n",*p); | | printf("データは %d 16進数だと %x だよーん!\n",*p); |
| + | |
| } | | } |
| | | |
| char a; | | char a; |
| int i; | | int i; |
- | | + | |
| + | |
| for(i = 0x0010; i = 0x0014; i = i+1) | | for(i = 0x0010; i = 0x0014; i = i+1) |
| { | | { |
| p = (char *)i; /* ←ここに注目!*/ | | p = (char *)i; /* ←ここに注目!*/ |
| printf("データは %d 16進数だと %x だよーん!\n",*p); | | printf("データは %d 16進数だと %x だよーん!\n",*p); |
| + | |
| } | | } |
| | | |
| char z; | | char z; |
| char c; | | char c; |
| + | |
| z = 0x44; | | z = 0x44; |
| c = 0x22; | | c = 0x22; |
| + | |
| c = c + z; | | c = c + z; |
| + | |
| printf("data is %x\n",c); | | printf("data is %x\n",c); |
| | | |
| | | |
| int i; | | int i; |
| + | |
| char z; | | char z; |
| char c; | | char c; |
| + | |
| z = 0x44; | | z = 0x44; |
| c = 0x22; | | c = 0x22; |
| + | |
| i = c + z; | | i = c + z; |
| + | |
| printf("data is %x\n",i); | | printf("data is %x\n",i); |
| | | |
| char c; | | char c; |
| int i; | | int i; |
| + | |
| c = 0xf3; | | c = 0xf3; |
| i = 0x12; | | i = 0x12; |
| + | |
| c = c + i; | | c = c + i; |
| + | |
| printf("data is 0x%X\n",c); | | printf("data is 0x%X\n",c); |
| | | |
| | | |
| *現実の型キャスト(ポインタ) [#j3516d0b] | | *現実の型キャスト(ポインタ) [#j3516d0b] |
| + | これは「現実」とは言っても、ほぼ概念通りと考えてもらってかまわないと思います。 |
| + | |
| + | アドレス変数(ポインタ)は特別にして唯一無比の型なので、とにかくこれに代入しようとした場合はほぼ''かならず型キャストして代入する''で問題ないでしょう。 |
| + | |
| + | -COLOR(blue){少ない桁数の変数から型キャストした場合どうなるのか?} |
| + | |
| + | こういうのは実験しちゃうのが早いですよ? |
| + | |
| + | int main(void){ |
| + | |
| + | char *p; |
| + | char c; |
| + | |
| + | c = 0x33; |
| + | p = c; |
| + | |
| + | printf("data is 0x%X\n",p); |
| + | |
| + | } |
| + | |
| + | さて、これをコンパイルすると・・・ |
| + | ~おっと!いけない!型キャストを忘れていました。 |
| + | |
| + | int main(void){ |
| + | |
| + | char *p; |
| + | char c; |
| + | |
| + | c = 0x33; |
| + | p = (char *)c; |
| + | |
| + | printf("data is 0x%X\n",p); |
| + | |
| + | } |
| + | |
| + | ・・・実は、これもエラーが出ます。「キャストはいいけどサイズが合わんぞ。サイズくらい合わせろよ!」ってとこでしょうか? |
| + | |
| + | しかし警告エラーは無視してコンパイルし、これを実行すると、答えは0x33と表示されます。おそらくこういう場合、足りないケタ数は0で埋められてしまうようです。 |
| + | |
| + | では、char型の変数の値をアドレス変数に当て込むにはどういう手法が正しいのでしょうか? |
| + | |
| + | 正しい呼び名はわかりませんが、おそらくこういう「二段キャスト」でよいはずです。 |
| + | |
| + | p = (char *)(int)c; |
| + | |
| + | COLOR(blue){上記。理解のため無理にchar型を使っていますが、やっぱり理想は、せめてint型にしてから、あるいはアドレス変数への代入が予想されるような値は最初からint型で定義して使うというのが本流なのでしょう。きっと。} |