C の文法書を読んでいると、
汎整数型拡張: int より小さな汎整数型が式中に現れる場合は、暗黙的に int 型に変換される。
算術変換: 二項演算子で二つのオペランドの型が違う場合は、演算前により大きな方の型に暗黙的に変換される。
とあります。
例えば
int 型 = unsigned short 型 - unsigned char 型;
はどのように暗黙的な型変換が行われるのでしょう。
int 型 = (int)unsigned short 型 - (int)unsigned char 型;
でしょうか。あるいは、
int 型 = (int) ( unsigned short 型 - (unsigned short)unsigned char 型);
でしょうか。
No.6ベストアンサー
- 回答日時:
>ただ私の読んでいる本では、算術型変換の説明に
> unsigned char と char の演算では unsigned char に変換される
>という説明まで載っているので、
その記述はおそらくうっかりミスだと思います。
書名を教えてください。
>int が 8 ビットの場合まで想定して書かれているのでしょうかね。
int型は規格で、-32767~+32767の範囲を表現できることが義務づけられているので、
最低16ビットです。
(一方で、char型が16ビット以上という環境は有り得るそうですが)
正確な用語では、
「汎整数拡張」は
「通常の算術型変換」の一部ということです。
つまり、違う型の混じった計算は
(1)char, shortなどに対して、まず汎整数拡張が行われてint型に変換される。
(2)次に、算術型変換(サイズが大きい方の型に合わせる)が行われる。
(広い意味では(1)(2)を含めて算術型変換と言う)
となります。最初に考えていたこととたぶん一緒だと思います。
再度回答ありがとうございます。よく分かりました。
> その記述はおそらくうっかりミスだと思います。
書名を教えてください。
特殊な本で、一般の人は入手できないので書名は出さないことにします。
No.5
- 回答日時:
整数演算の場合、以下のようなルールがあります
一方のオペランドが unsigned long 型でれば、もう一方のオペランドが unsigned long 型に変換されます。
上の条件を満たさないとき、一方のオペランドが long 型、もう一方のオペランドが unsigned int 型であれば、両方のオペランドが unsigned long 型に変換されます。
上の 2つの条件を満たさないとき、一方のオペランドが long 型であれば、もう一方のオペランドが long 型に変換されます。
上の 3 つの条件を満たさないとき、一方のオペランドが unsigned int 型であれば、もう一方のオペランドが unsigned int 型に変換されます。
上の条件をすべて満たさないときは、両方のオペランドが int 型に変換されます。
∴ 今回の事例では 全て int に拡張されてから演算されます。
No.4
- 回答日時:
汎整数拡張が行われるので、
>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より大きな型の場合に行われます)
回答ありがとうございます。
> 算術型変換は、汎整数拡張の後に行われます。
(intより大きな型の場合に行われます)
というルールがあるのなら話は明確ですね。ただ私の読んでいる本では、算術型変換の説明に unsigned char と char の演算では unsigned char に変換されるという説明まで載っているので、「intより大きな型の場合に行われます」というのがちょっと理解できないのですが。
int が 8 ビットの場合まで想定して書かれているのでしょうかね。
No.3
- 回答日時:
基本的にはサイズの大きい型にキャストされます。
この場合
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 型);
ですね。
やはり明示的にキャストしや方が分かりやすいと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語 共用体について コマンドライン引数で値を2つ入力したときに、argv[2]の値をUNI u1 4 2022/04/25 20:34
- C言語・C++・C# プログラムが書けません。 4 2023/01/22 22:57
- C言語・C++・C# C言語初心者 ポインタについて、お助けください、、 2 2023/03/15 23:50
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- C言語・C++・C# c言語 int temp = 0; if(isdigit(arr[i])){ temp=arr[i] 2 2022/03/27 01:44
- C言語・C++・C# C++初心者です stirng 2 2022/09/20 20:43
- C言語・C++・C# C言語初心者 構造体 課題について 1 2023/03/10 19:30
- C言語・C++・C# ポインタの型変換、どうやるんでしたっけ? 2 2022/03/28 11:00
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
比較回数と交換回数表示について
-
nCmの関数
-
複数桁10進数の*桁目だけを抽出...
-
#define _CRT_SECURE_NO_WARNIN...
-
C言語 配列と関数の練習問題
-
c言語
-
std::set<int> で、ある値が何...
-
卒業研究でよく分からないとこ...
-
C言語 エラーの原因がわからな...
-
DLLをGetProcAddress()で実行で...
-
【C++】関数ポインタの使い方
-
read関数をノンブロッキングで...
-
C言語における対称行列の作り方...
-
構造体の勉強中です 合計点の高...
-
C言語です。
-
C言語での引数の省略方法
-
困ってます…nCrを求めるC言語...
-
C++でvectorにテキストファイル...
-
プログラミング
-
素数 再帰関数
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語での引数の省略方法
-
#define _CRT_SECURE_NO_WARNIN...
-
「指定されたキャストは有効で...
-
C言語 配列と関数の練習問題
-
複数桁10進数の*桁目だけを抽出...
-
(int *)の意味
-
if と配列の組み合わせ
-
ラップ関数とはどんなものですか?
-
卒業研究でよく分からないとこ...
-
【C++】関数ポインタの使い方
-
c言語
-
足して100になるような乱数のア...
-
C言語初心者です、、、お助けく...
-
数字列を3桁ごとにカンマで区切...
-
C言語 エラーの原因がわからな...
-
実数の整数部,小数部の取得
-
課題でつまってます・・・
-
商と剰余を同時に求める(C言語)
-
C言語の配列をC++のvectorに高...
-
std::set<int> で、ある値が何...
おすすめ情報