ホームページ >バックエンド開発 >C#.Net チュートリアル >C言語式における暗黙的な型変換
まず、「C Expert Programming」から抜粋した次のプログラムを見てください:
#include <stdio.h> int array[] = {23,34,12,17,204,99,16}; #define TOTAL_ELEMENTS (sizeof(array)/sizeof(array[0])) int main(void) { int d=-1,x; /*........*/ if(d <= TOTALTOTAL_ELEMENTS - 2) x = array[d+1]; /*........*/ return 0; }
そのようなプログラムがある場合、代入ステートメント x=array[d+ 1] のため、x の値が何であるかは決してわかりません。 ]; はまったく実行されません。どういう理由ですか?デバッグの結果、判定用のif文まで実行した後、次の文の実行を直接スキップしていることが分かりました。型のサイズを計算するときの sizeof の戻り値が unsigned int 型であり、d が signed int であるため、ステートメントで両方のサイズをテストすると、d は自動的に unsigned int にアップグレードされ、-1 が変換されます。 unsigned int に変換します。大きい正の整数であるため、式の値は常に false となり、後続の代入ステートメントは実行されません。これは型変換によって発生するバグです。注意しないと、プロジェクト全体またはプロジェクトに予期せぬ影響を与える可能性があります。このバグは直接デバッグするのが困難です。
式における型変換
型変換には、強制的な型変換と暗黙的な変換が含まれます。まず、従来の C (K&R C) における暗黙的な型変換のルールを理解しましょう:
まず、char 型または short int 型のオペランドは int 型に変換され、float 型は double 型に変換されます。一方のオペランドが double 型の場合、もう一方のオペランドも double に変換され、計算結果も double になります。一方のオペランドが long 型の場合、もう一方のオペランドも long 型に変換され、計算結果は次のようになります。また、long; if 一方のオペランドが符号なしの場合、もう一方のオペランドも符号なしに変換され、計算結果は符号なしになります。
ただし、新しい標準ではいくつかの変更が加えられています:
1. 整数のアップグレード: すべての char、short int、および bit フィールドは、最初に自動的に int または unsigned int に変換されます。 int がソース型のすべての値を表現できる場合は int に変換され、それ以外の場合は unsigned int に変換されます。
2. 式の値を計算するとき、通常、低型 (表現できるデータの範囲が狭いデータ型) が最初に高型に変換されてから計算に参加します。ただし、ここで注意すべき点は、式の中に float 型がある場合、計算前に必ずしも double 型に変換されるわけではないということです。以下のコードがある場合:
float f1,f2; double d; f1 = d*f2;
単精度で計算した場合、最終結果は倍精度計算と同じになるため、f2は変換されない可能性があります。これは従来の C とは異なりますが、現在これをサポートしているコンパイラはほとんどありません (VC はサポートしていません)。
式に unsigned 型と signed 型のオペランドがある場合、一方のオペランドが unsigned long int の場合、もう一方のオペランドも unsigned long int に変換されます。一方のオペランドが long int の場合、もう一方のオペランドは unsigned int です。 long int が unsigned int の表現範囲を表現できる場合は、もう一方のオペランドが long int に変換され、それ以外の場合、一方のオペランドが unsigned int で、もう一方のオペランドが int の場合は、もう一方のオペランドが変換されます。 unsigned int に。
例を見てみましょう:
int が 16 ビット、long int が 32 ビットであると仮定します。
つまり、-1L 1UL の場合、-1L の型は signed long int であり、1UL の型は unsigned long int であるため、-1L は unsigned long int に変換されます。