プロが教える店舗&オフィスのセキュリティ対策術

C の文法書を読んでいると、

汎整数型拡張: int より小さな汎整数型が式中に現れる場合は、暗黙的に int 型に変換される。

算術変換: 二項演算子で二つのオペランドの型が違う場合は、演算前により大きな方の型に暗黙的に変換される。

とあります。

例えば

int 型 = unsigned short 型 - unsigned char 型;

はどのように暗黙的な型変換が行われるのでしょう。

int 型 = (int)unsigned short 型 - (int)unsigned char 型;

でしょうか。あるいは、

int 型 = (int) ( unsigned short 型 - (unsigned short)unsigned char 型);

でしょうか。

A 回答 (6件)

>ただ私の読んでいる本では、算術型変換の説明に


> unsigned char と char の演算では unsigned char に変換される
>という説明まで載っているので、

その記述はおそらくうっかりミスだと思います。
書名を教えてください。

>int が 8 ビットの場合まで想定して書かれているのでしょうかね。

int型は規格で、-32767~+32767の範囲を表現できることが義務づけられているので、
最低16ビットです。
(一方で、char型が16ビット以上という環境は有り得るそうですが)

正確な用語では、
「汎整数拡張」は
「通常の算術型変換」の一部ということです。

つまり、違う型の混じった計算は

(1)char, shortなどに対して、まず汎整数拡張が行われてint型に変換される。
(2)次に、算術型変換(サイズが大きい方の型に合わせる)が行われる。
(広い意味では(1)(2)を含めて算術型変換と言う)

となります。最初に考えていたこととたぶん一緒だと思います。
    • good
    • 0
この回答へのお礼

再度回答ありがとうございます。よく分かりました。

> その記述はおそらくうっかりミスだと思います。
書名を教えてください。

特殊な本で、一般の人は入手できないので書名は出さないことにします。

お礼日時:2005/02/11 16:44

整数演算の場合、以下のようなルールがあります



一方のオペランドが unsigned long 型でれば、もう一方のオペランドが unsigned long 型に変換されます。

上の条件を満たさないとき、一方のオペランドが long 型、もう一方のオペランドが unsigned int 型であれば、両方のオペランドが unsigned long 型に変換されます。


 上の 2つの条件を満たさないとき、一方のオペランドが long 型であれば、もう一方のオペランドが long 型に変換されます。


 上の 3 つの条件を満たさないとき、一方のオペランドが unsigned int 型であれば、もう一方のオペランドが unsigned int 型に変換されます。


 上の条件をすべて満たさないときは、両方のオペランドが int 型に変換されます。


∴ 今回の事例では 全て int に拡張されてから演算されます。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

お礼日時:2005/02/11 10:55

汎整数拡張が行われるので、



>int 型 = (int)unsigned short 型 - (int)unsigned char 型;

が正しいです。

実験してみます。足し算の方がわかりやすいと思うので
足し算にしました。
-------------
#include <stdio.h>

int main(void)
{
unsigned short a = 65530;
unsigned char b = 255;
int c;
unsigned short d;

c = a + b;
d = a + b;

printf("c = %d, d = %d\n", c, d);

return 0;
}
-------------

これを実行すると、
>c = 65785, d = 249
となります。
もし、
>int 型 = (int) ( unsigned short 型 - (unsigned short)unsigned char 型);
のようにunsigned shortのまま計算されるとすれば、
二つの値は同じになるはずです。

算術型変換は、汎整数拡張の後に行われます。
(intより大きな型の場合に行われます)
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

> 算術型変換は、汎整数拡張の後に行われます。
(intより大きな型の場合に行われます)

というルールがあるのなら話は明確ですね。ただ私の読んでいる本では、算術型変換の説明に unsigned char と char の演算では unsigned char に変換されるという説明まで載っているので、「intより大きな型の場合に行われます」というのがちょっと理解できないのですが。

int が 8 ビットの場合まで想定して書かれているのでしょうかね。

お礼日時:2005/02/11 10:53

基本的にはサイズの大きい型にキャストされます。


この場合
int a;
unsigned short b;
unsigned char c;
でa=b-cとするなら
最初にb - cの計算が行われるわけですが
まずb - (unsigned short)c
でこの結果をaにいれるわけですから
a = (int)(b - (unsigned short)c);

つまり
int 型 = (int) ( unsigned short 型 - (unsigned short)unsigned char 型);
ですね。
やはり明示的にキャストしや方が分かりやすいと思います。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

そうですか、そうすると「汎整数型拡張」というルールは使われないということでしょうか。

お礼日時:2005/02/10 21:51

#1です。

これも自信ないですが、
long=(long)short - long
ということではないでしょうか?

代入先がintなら
int=(int)((long)short - long)
という風になるのかもしれません。私はこの手の型が違う計算は明示的にキャストして使っていることもありまったく自信がないです。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

お礼日時:2005/02/10 21:52

自信はまったくないですが、アセンブラで考えるとeaxなどのレジスタに値を代入してからsubなどで演算しますよね。

ということは。。。
int 型 = (int)unsigned short 型 - (int)unsigned char 型;
となるのではないでしょうか?
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

確かにそのようにも思えるのですが、「算術変換」はどのような場合には適用されるのでしょうか。

お礼日時:2005/02/10 16:09

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!