序文
今日は、Xiaoyang がC 言語についてお話しします。C 言語では、型変換メソッドはと(必須型変換)隐式类型转换规则
に分けられ、暗黙的な型変換はプログラマの介入なしにコンパイラによって自動的に実行されます。 Xiaoyang Classroom で話しているのは、暗黙的な型変換についてです。暗黙的な型変換は、次の 2 つの状況に分けられます。隐式类型转换
显式类型转换
整型提升和算术转换
1. 暗黙的な型変換の規則
C 言語では、自動型変換は次の規則に従います。
- 演算に関わるオペランドの型が異なる場合は、同じ型に変換してから演算を行ってください。
- 精度が低下しないように、データ長が増加する方向に変換が行われます。例えば、int型とlong型を演算する場合、int型の値をlong型に変換してから演算を行います。
a. 2 つの型のバイト数が異なる場合は、バイト数が大きい型に変換します
b. 2 つの型のバイト数が同じで、一方が符号付き、もう一方が符号なしの場合、符号なし型に変換する - すべての浮動小数点計算は倍精度で実行されます。float 単精度計算のみを含む式であっても、計算前に double に変換する必要があります。
- char型とshort型が演算に参加する場合は、まずint型に変換する必要があります。
- 代入演算において、代入番号の両側の数量のデータ型が異なる場合、代入番号の右側の数量の型を左側の数量の型に変換します。右側のデータ型の長さが左側のデータ型よりも長い場合、データの一部が失われ、精度が低下します。また、失われた部分は四捨五入されます。
2. 整数の改善
C の整数算術演算は常に、少なくともデフォルトの整数型の精度で実行されます。この精度を得るために、式内の文字および短整数のオペランドは使用前に通常の整数型に変換されます。この変換は整数プロモーションと呼ばれます。
原理
有符号补符号位,无符号位无脑补0
1. 負の数の整数昇格
高位补充符号位,即补1
char a=-1;
变量a的二进制位(补码)中只有8个比特位:
11111111
因为char是有符号的char
所以整型提升的时候,补符号位,即补1
提升结果:
11111111 11111111 11111111 11111111
2. 正の数の整数昇格
高位补充符号位,即补0
char a=1;
变量a的二进制位(补码)中只有8个比特位:
00000001
因为char是无符号的char
所以整型提升的时候,补符号位,即补0
提升结果:
00000000 00000000 00000000 00000001
3. 符号なし整数の昇格
无符号整型提升,高位补0(无符号只有正数)
3. 整数昇格の例
例1:
#include <stdio.h>
int main()
{
char a = 5, b = 127;
char c = a + b;
int d = a + b;
printf("c=%d\n", c);
printf("d= %d", d);
return 0;
}
操作結果:
c=-124
d=132
分析します:
char a=5
0000 0101 --> a=5
char b=127
0111 1111 --> b=127
因为参与了运算,并且char类型的精度小于int类型,所以这里进行整型提升:
00000000 00000000 00000000 00000101 --> a=5
00000000 00000000 00000000 01111111 --> b=127
00000000 00000000 00000000 10000100 --> c=132
//1:>
将结果存入类型为char的变量c中,c只能存储8位,所以保留结果最后8位
1000 0100 --> c=132
由于char类型也是有正负的,且计算结果是以补码形式,转化为原码
补码:1000 0100
反码:1000 0011
原码:1111 1100 --> -124
原码值为-124
//2:>
运算还是先整型提升再运算,二进制同上,最后结果存放到int类型的b中,所以直接就是132
例2:
#include<stdio.h>
int main()
{
char a = 0xb6;
short b = 0xb600;
int c = 0xb6000000;
if (a == 0xb6)
printf("a");
if (b == 0xb600)
printf("b");
if (c == 0xb6000000)
printf("c");
return 0;
}
操作結果:
c
分析します:
a=0xb6
整型提升前:10110110
整型提升后:11111111 11111111 11111111 10110110 可以直接看出这是一个负数的补码
b=0xb600
整型提升前:10110110 00000000
整型提升后:11111111 11111111 10110110 00000000 可以直接看出这也是一个负数的补码
c=0xb6000000
无需整型提升,故结果为真
例3:
#include<stdio.h>
int main()
{
char c = 1;
printf("c=%u\n", sizeof(c));//%u按无符号整形unsigned int打印
printf("c=%u\n", sizeof(+c));
printf("c=%u\n", sizeof(-c));
return 0;
}
操作結果:
c=1
c=4
c=4
分析します:
sizeof(c),c没有参与运算,故就是求char类型大小
sizeof(+c),sizeof(-c),c参与运算,整型提升为int,故就是求int类型大小
4. 算術転送
演算子のオペランドの型が異なる場合、以下の通常の算術変換のように、一方のオペランドを他方のオペランドの型に変換しない限り、演算を実行できません。
//从高到低
long double
double
float
unsigned long int
long int
unsigned int
int
注:
同じ演算でオペランドの型が異なる場合は、順位の低いものを順位の高いものに変換する必要があります。
算術変換は合理的である必要があります。そうしないと、潜在的な問題が発生します。
例1:
float f=3.14;
int num=f;//隐式转换,精度丢失
例2:
#include<stdio.h>
int main()
{
unsigned char a = 0;
unsigned char b = 255;
unsigned char c = 255;
a = b + c;
printf("a = %d\n", a);
return 0;
}
操作結果:
a = 254
分析します:
b和c的值都需要提升为整型,再执行加法运算
b\c:>
整型提升前:11111111
整型提升后:11111111 11111111 11111111 11111111
11111111 11111111 11111111 11111111 --> b
11111111 11111111 11111111 11111111 --> c
111111111 11111111 11111111 11111110 --> a
结果保留最后的8位
11111110 --> 补码
由于是无符号char类型,那么原反补一样
原码也是11111110 即为254
要約する
変換理由:
ハードウェア: CPU レジスタのビットが統一されており、メモリ上のデータをレジスタに入れる際に暗黙的な変換が行われる ソフトウェア :
C言語の演算子が複数のオペランドを演算する場合、それらの一貫性を保証する必要があるタイプ
五、演算子の特性
1. オペレーター
複雑な式の評価に影響を与える要因は 3 つあります。
操作符的优先级
。複数の演算子と複数のオペランドがある場合に、どの部分が最初に実行されるかを決定します。操作符的结合性
。優先順位が同じ場合、複数または単一の演算子は左から右、または右から左に実行されます。是否控制求值顺序
。いくつかの特定の式が評価されており、異なる条件に応じて異なる評価プロセスが生成されます。
隣接する 2 つの演算子のうちどちらが最初に実行されますか? 優先順位によって異なります。両方の優先度が同じ場合、それは結合性によって決まります。
2. 演算子の優先順位
演算子の優先順位、上から下、強調
オペレーター | 組み合わせ | 評価の順序を制御するかどうか |
---|---|---|
() | 該当なし | いいえ |
、 | LR | いいえ |
-> | LR | いいえ |
++ | LR | いいえ |
– | LR | いいえ |
++ | RL | いいえ |
– | RL | いいえ |
* | RL | いいえ |
3. 質問表現
式1
a*b + c*d + e*f
注: コード 1 を計算する場合、乗算の優先順位は + の優先順位よりも高いため、乗算の計算が + よりも前であることのみが保証されますが、優先順位によって 3 番目の * が最初の + よりも早く実行されるかどうかは決まりません。 。
したがって、コンピュータによる式の順序は次のようになります。
a*b
c*d
a*b + c*d
e*f
a*b + c*d + e*f
或者:
a*b
c*d
e*f
a*b + c*d
a*b + c*d + e*f
式2
不正な表現 1
int main()
{
int i = 10;
i = i-- - --i * (i = -3) * i++ + ++i;
printf("i = %d\n", i);
return 0;
}
不正な表現 2
int fun()
{
static int count = 1;
return ++count; }
int main()
{
int answer;
answer = fun() - fun() * fun();
printf( "%d\n", answer);//输出多少?
return 0; }
これら 2 つの表現、鉄ジューサーは、なぜこれが違法なのかを慎重に検討する必要があります。方法がわからない場合は、子羊を個人的に信頼することができます。
要約:
作成した式が演算子の属性を介した唯一の計算パスを決定できない場合は、この式に問題があるはずです。
さて、 Xiaoyang が今日共有したC 言語の暗黙の型変換ルールは以上です。コメント欄にメッセージを残してください~~