okiami1983のブログ

クオリティーが低い記事はあとで書き直します。。

C言語メモ

C言語は未規定の動作や未定義の動作があって、とても危険な言語です。。

 

ポインタ

constやvolatile属性のポインタ変数でアクセスする領域に対して、属性を外した別のポインタ変数を使ってアクセスするのはだめ。

  • 参照先の値を変更しないポインタ変数にはconstレジスタアクセスするポインタ変数にはvolatile属性をつけます。
  • 関数に値を渡すときなど、うっかり仮引数の属性を付け忘れることがあります。
  • 属性を外してしまうと、領域に対して不適切なアクセスが発生しているにもかかわらず、コンパイルでチェックされないようです。

 

 

算術型変換

演算に先立ちオペランドの評価をおこなう。「暗黙の型変換」と呼ばれる変数の型変換がオペランドの型に応じて勝手に行われ、両方のオペランドの型を統一したうえで演算される。演算結果も当然統一した型になる。

一方のオペランド浮動小数点型の場合はもう片方のオペランドも勝手に浮動小数点型に変換して演算する。そうでない場合(整数型の場合)もオペランドに応じて型変換がおこなわれたあとで演算が行われる。

一方のオペランド浮動小数点型の場合

long double, double, floatの順で演算の型が決められる。例えば、片方の型がlong doubleだった場合はもう片方の型および演算結果がlong doubleに統一される。

どちらのオペランドも整数型の場合

まず、汎整数拡張によってint型未満のサイズはint型に変換される。汎整数拡張では、「元の値を表現できる場合は符号付き、表現できなければ符号なしに変換する」というルールで変換が行われる。そのあと、long型とint型でより大きいサイズに合わせるように型変換が行われる。int型のサイズが異なる影響をうけて、32bitシステムと16bitシステムで動作が若干異なる。

32bitのケース。
  1. ushort, short, uchar, charは汎整数拡張によりint型となる。
  2. longベースの演算になるケース
    片方のオペランドにlongを使う演算で、もう片方がlong, int(ushort, short, uchar, char)の場合。
  3. ulongベースの演算になるケース
    片方のオペランドにulongを使う場合。または、片方のオペランドにlongを使い、もう片方がuintの場合。
  4. intベースの演算になるケース
    オペランドにuintを含まない場合。
  5. uintベースの演算になるケース
    オペランドにuintが含まれる場合。
16bitのケース。
  1. short, uchar, charは汎整数拡張によりint型になる。
  2. ushortは汎整数拡張によりuint型になる。
  3. longベースの演算になるケース
    片方のオペランドにlongを使う演算で、もう片方がlong, uint(ushort), int(short, uchar, char)の場合。
  4. ulongベースの演算になるケース
    片方のオペランドにulongを使う場合。
  5. intベースの演算になるケース
    オペランドにuintを含まない場合。
  6. uintベースの演算になるケース
    オペランドにuintを含む場合。

 

少しずつ足していきます。

 

参考

 

CERT C コーディングスタンダード

 

組込み開発者におくるMISRA‐C―組込みプログラミングの高信頼化ガイド

組込み開発者におくるMISRA‐C―組込みプログラミングの高信頼化ガイド

 

 

エキスパートCプログラミング―知られざるCの深層 (Ascii books)

エキスパートCプログラミング―知られざるCの深層 (Ascii books)

 

 

実習C言語 (アスキー・ラーニングシステム)

実習C言語 (アスキー・ラーニングシステム)

 
  •  演算時の型変換が詳しい

 

Cプログラミング専門課程

Cプログラミング専門課程

 

 

 

 

最近はC言語がトレンドでないのか、大きな書店でも入門者用の本ばかりになってしまいましたね。。