C言語は他の言語と同様に標準文法や文字集合を使用します。この章では, 文法と文字集合から構成される固有の要素を次の各節で説明します。
Cコンパイラは,ソース・ファイルからの文字ストリームとしてソース・ コードを解釈します。これらの文字は,区切り記号,演算子,識別子,キーワード, 文字リテラルまたは定数などのトークンと呼ばれる要素に分類されます。 トークンはC言語における最小の構文要素です。コンパイラは, 指定された文字列から可能な限り最長のトークンを形成します。 つまり,空白が見つかった場合,または次の文字をトークンの一部にできない場合にトークンは終了します。
空白は,空白文字,改行文字,タブ文字,フォーム・フィード文字または垂直タブ文字のいずれかです。 コメントも空白とみなされます。第1.1節にすべての空白文字の一覧を示します。 空白はトークンの区切り記号(二重引用符で囲まれた文字列内は除く) として使用されます。ただし,それ以外の文字ストリームでは無視され, 主に読みやすさのために使用されます。また,空白は前処理命令で意味を持つ場合もあります( 第8章を参照してください) 。
たとえば,次のソース・コード行を例にとります。
static int x=0; /* Could also be written "static int x = 0;" */
コンパイラは,この行を次のようなトークン(1行ごとに1つ)に分けます。
static int x = 0 ;
コンパイラが入力文字列を処理するとき,トークンを識別し,エラー条件を検索します。 コンパイラは,エラーについて次の3つの種類を識別できます。
コンパイラが文字ストリームから正しいトークンを形成できない場合( 不正な文字が使用されている場合など)に起こる。
正しいトークンを形成できるが,コンパイラがトークンから正しい文を作成できない場合に起こる。 たとえば,次の行は不正な区切り文字で初期化子並びを囲んでいる。
char x[3] = (1,2,3);
文法的には正しいが,別のC言語規則に違反している。たとえば,次の行は浮動小数点値をポインタ型に割り当てようとしている。
int *x = 5.7;
論理エラーはコンパイラでは識別されません。
C言語で重要な概念はコンパイル単位という考え方です。このコンパイル単位とは, コンパイラでコンパイルする1つまたは複数のファイルを表します。
受入れ可能な最小のコンパイル単位は,1つの外部定義です。ANSI C規格は, コンパイル単位に関していくつかの基本的な概念を定義しています。 コンパイル単位についての詳細は,第2.2 節で説明します。
宣言を持たないコンパイル単位は,厳密なANSI規格モードを除くすべてのモードで受け入れられますが, コンパイラ警告メッセージが出されます。
文字集合は,ソース・プログラムで使用可能か,またはプログラムの実行時に解釈可能な有効文字を定義します。 ソース文字集合 は,ソース・テキストに使用できる文字集合です。実行文字集合 は,プログラムの実行時に使用できる文字集合です。ソース文字集合は, 実行文字集合と必ずしも一致している必要はありません。たとえば, ソース・コード作成のために使用する装置上で,実行文字集合が使用できない場合などです。
文字集合は異なるものがいくつか存在します。たとえば,ある文字集合の文字はASCII
定義に基づいており,別の文字集合は日本語の漢字を組み込んでいます。
コンパイラにとっては,使用している各文字集合の相違は関係ありません。
つまり,各文字は固有の値を持っているため,Cコンパイラは各文字を異なる整数値として扱います。ASCII
文字集合は255
文字より少なく,これらの文字は8ビット以下で表すことができます。
ただし,拡張文字集合の中には多くの文字が存在するので,文字の表記に8
ビットよりも多くのビットが必要な場合があります。これらの大きい文字を格納するために,
wchar_t
(ワイド文字)と呼ばれる特定の型が作成されています。
ワイド文字についての詳細は,第1.9.3.1項で説明します。
ANSIと互換性のあるCコンパイラのほとんどが,ソース文字集合と実行文字集合の両方に対して次のASCII 文字を受け入れます。各ASCII文字は数値と対応します。 付録 CにASCII文字とその数値を記載しています。
a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9
! # % ^ & * ( ) - _ = + ~ ' " : ; ? / | \ { } [ ] , . < > $
コンパイラの厳密なANSIモード・オプションを指定した場合に
$
を使用すると,警告メッセージが表示される。
空白 | ' ' |
水平タブ | '\t'
|
フォーム・フィード | '\f' |
垂直タブ | '\v' |
改行文字 | '\n' |
文字定数と文字列リテラルの場合には,実行文字集合からの文字を文字または数値エスケープ・ シーケンスで表すこともできます。これらのエスケープ・ シーケンスについては,第1.9.3.3項および第1.9.3.4項で説明します。
また,ASCII実行文字には次の制御文字も含まれます。
'\n'
と表記)
'\a'
)
'\b'
)
'\r'
)
'\0'
)
ヌル文字はすべてのビットが0にセットされているバイト文字またはワイド文字であり, 文字列の終わりを示すために使用します。文字列についての詳細は, 第1.8節で説明します。
改行文字は,読みやすさの向上やプリプロセッサの適切な操作のために, ソース文字ストリームを別の行に分割します。
コンパイラが,端末やウィンドウの幅よりも長い行を1つの論理行として解釈することが必要な場合があります。
継続する行の終わりにバックスラッシュ文字(
\
)を付けることによって,1
つの論理行を2行以上にわたって入力することを示します。バックスラッシュの直後には,
改行文字を続けなければなりません。バックスラッシュは,
現在の論理行が次の行に継続されることを意味します。次にその例を示します。
#define ERROR_TEXT "Your entry was outside the range of \ 0 to 100."
コンパイラは,処理中にこの行が1つの論理行になるように,バックスラッシュ文字と後続の改行文字を削除します。 次にその例を示します。
#define ERROR_TEXT "Your entry was outside the range of 0 to 100."
長い文字列は,バックスラッシュと改行の行継続機能を使用して複数行にわたって継続できます。 しかし,文字列の継続は次の行の最初の位置から開始しなければなりません。 このため,プログラムのインデントの構成を破壊しなければならない場合があります。ANSI C 規格では,この問題を避けるために別の文字列継続機能を採用しています。 すなわち,空白のみで分割されている2 つの文字列リテラルは,1つの論理文字列リテラルを形成するという継続機能です。 次にその例を示します。
printf ("Your entry was outside the range of " "0 to 100.\n");
論理行の最大長は32,767文字です。
C言語で有効な区切り文字のうち,その一部しか持たない文字集合を使用してC プログラムを記述する際に,ANSI Cではソース・ファイル中に9つの 3文字表記を使用することができます。この3文字表記は,コンパイルの最初の段階で単一文字に置き換えられます( コンパイルの段階については, 第2.16節を参照してください) 。表 1-1に,有効な3文字表記とその等価文字を示します。
3文字表記 | 等価文字 |
---|---|
??= | #
|
??( |
[ |
??
/ | \ |
??) | ] |
??' | ^
|
??< |
{ |
??!
| | |
??> | } |
??- | ~
|
この表以外の3文字表記は認識されません。1つの疑問符(
?
)では3文字表記は開始されないため,コンパイルにより等価文字に置換されることもありません。
たとえば,次のソース行を例にとります。
printf ("Any questions???/n");
??/
表記が置換されると,この行は次のように表されます。
printf ("Any questions?\n");
2文字表記の処理は,ISO C 94モード(OpenVMSシステムでは/STANDARD=ISOC94) でコンパイルする場合にサポートされます。
2文字表記は,3文字表記と同様に単一文字に翻訳される文字の組み合わせですが,3 文字表記が内部の文字列リテラルを置き換えるのに対し,2文字表記は置き換えません。 表 1-2に,有効な2 文字表記とその等価文字を示します。
2文字表記 | 等価文字 |
---|---|
<: | [ |
:> | ] |
<% | { |
%> | } |
%: | # |
%:%: | ## |
識別子は,次の項目の名前を表す文字シーケンスです。
識別子には,次の規則が適用されます。
$文字を使用すると,厳密なANSIモードではコンパイラから警告メッセージが表示される。
Test1
識別子は test1
識別子とは異なる。
struct employee { int number; char sex; } emp;
この例の場合,識別子は
employee
,number
,sex
,
および emp
です。また,
struct
,int
,および
char
はキーワードです。
外部結合のない識別子の有効文字は,最大で32,767文字です。外部結合のある識別子の有効文字は, Tru64 UNIXシステムでは1023 文字,OpenVMSプラットフォームでは31文字です(結合についての詳細は, 第2.8節を参照してください) 。OpenVMS上の外部識別子の場合には,大文字と小文字は区別されません。
有効文字内で異なる識別子は,それぞれ異なる識別子です。複数の識別子が非有効文字内でのみ異なる場合には, それらは同じ識別子とみなされます。
ユニバーサル・キャラクタ名を使用すると,その他の文字を指定することができます。 ユニバーサル・キャラクタは, 識別子,文字定数,文字列リテラルに使用することができ, 基本文字セットにない文字を指定するために使用します。
ユニバーサル・キャラクタ名は,
\
uまたは\
Uで始まり,
4桁または8桁の16進数が続きます。
ユニバーサル・キャラクタ名 \Unnnnnnnnは, 8桁の短識別子(ISO/IEC 10646で規定)がnnnnnnnnである文字を示します。 同様に,ユニバーサル・キャラクタ名 \unnnnは, 4桁の短識別子がnnnn (8桁の短識別子が0000nnnn)である文字を示します。
ユニバーサル・キャラクタ名では,短識別子が00A0未満で, 0024 ($),0040 (@), または0060 (`)以外の文字や, D800〜DFFFの文字を指定することはできません。
有効なユニバーサル・キャラクタ名の一覧は,付録Fを参照してください。
文字定数,文字列リテラル,またはコメント内を除き,/*
という文字の組はコメントの開始を示します。
また,コメントは /*
という文字の組で終了します。
このようなコメントの内容は,マルチバイト文字を識別したり,
コメントの終了を示す */
を見つける目的でのみ調べられます。
または,//
という文字の組は,コメントの始まりを示します。
このコメントには,次の改行文字までのすべてのマルチバイト文字
(その改行文字を除く)が含まれます。
このようなコメントの内容は,マルチバイト文字を識別したり,
終了の改行文字を見つける目的でのみ調べられます。
コメントはネストできません。
一度コメントを開始すると,コンパイラは最初の
*/
をコメントの終わりとして処理します。
コードのセクションをコメントにする場合,/*
と */
のシーケンスは使用しないでください。
/*
と */
のシーケンスは,コメントを含まないコード・セクションにのみ有効です。
次の例の場合には,#if
と
#endif
の前処理命令を使用してください。
#if 0 /* This code is excluded from execution because ... */ code_to_be_excluded (); #endif
#if
および #endif
の前処理命令についての詳細は,第8章を参照してください。
コメントは,2つのソース・ファイルにまたがって指定することはできません。 ただし,1つのソース・ファイルにおいてはどんな長さであっても構いません。 コメントは,コンパイラとプリプロセッサの両方において空白として解釈されます。
例:
"a//b" // four-character string literal #include "//e" // undefined behavior // */ // comment, not syntax error f = g/**//h; // equivalent to f = g / h; //\ i(); // part of a two-line comment /\ / j(); // part of a two-line comment #define glue(x,y) x##y glue(/,/) k(); // syntax error, not comment /*//*/ l(); // equivalent to l(); m = n//**/o + p; // equivalent to m = n + p;
C言語にはいくつかのキーワードが定義されており,各キーワードはコンパイラに対して特別な意味を持ちます。 キーワードは,文構成要素を識別して基本型と記憶域クラスを指定します。 キーワードを識別子として使用することはできず, 宣言することもできません。
表 1-3はC言語のキーワードの一覧です。
auto | double | int | struct |
break | else | long | switch |
case | enum | register | typedef |
char | extern | return | union |
const | float | short | unsigned |
continue | for | signed | void |
default | goto | sizeof | volatile |
do | if | static | while |
_Bool | _Complex (Alpha 専用) | inline | restrict |
_Imaginary |
コンパイラは,表 1-3に示したキーワード以外にも, 2つのアンダスコア(__),またはアンダスコア1文字と大文字1文字の順で始まる識別子を すべて予約しています。 ユーザ変数名の先頭は,このシーケンスにならないようにしてください。
キーワードは,次の目的のために使用します。
auto
,extern
,register
,
static
記憶域クラスを変数または関数に割り当てる。
_Bool
,char
,_Complex
(Alpha 専用),const
,double
,
enum
,float
,int
,
long
,
short
,signed
,struct
,
union
,unsigned
,void
,
volatile
型を構成するか,または修飾する。
break
,case
,continue
,
default
,do
,else
switch
,while
文の一部として使用する。
typedef
新しく命名した型を定義する。
sizeof
,__typeof__
演算を行う。
次のVAX Cキーワードも,コンパイラに認識されること[1] があります。
_align globaldef globalref globalvalue noshare readonly variant_struct variant_union
次のC99規格のキーワードも,コンパイラに認識されること[2] があります。
inline restrict
キーワードを余分なマクロ名として使用しないでください。ただし,基本データ型の省略時の大きさを変更する場合は例外です。 次にその例を示します。
#define int short
int
キーワードを short
として再定義します。これにより,int
データ型で宣言されるすべてのデータ・
オブジェクトが
short
オブジェクトとして格納されます。
-vaxc
または -accept vaxc_keywords
を指定した場合に認識されます。
[2] OpenVMSシステムでは,
コンパイラのコマンド行で/STANDARD=RELAXED_ANSI(省略時の値),
/STANDARD=C99,または
/ACCEPT=C99_KEYWORDSを指定した場合に認識されます。
Tru64 UNIXシステムでは,コンパイラのコマンド行で
-std
(省略時の値),-c99,または
-accept c99_keywords
を指定した場合に認識されます。
演算子は1つ,または複数のオペランドでの演算を示すトークンであり, ある結果(値,指名子,副作用,またはこれらの組み合わせ) を返してきます。演算子は式または定数(式の1形式)です。1つのオペランドを持つ演算子は 単項演算子,2つのオペランドを持つ演算子は 2項演算子です。次にその例を示します。
x = -b; /* Unary minus operator */ y = a - c; /* Binary minus operator */
3つのオペランドを持つ演算子は3項演算子と呼びます。
演算子にはすべて優先順位が付けられています。優先順位とは,1 つの文の中でどの演算子を先に評価するかを決定する順位付けです。 各演算子の役割および演算子の優先順位の規則については,第6章を参照してください。
C言語の演算子には,複数の文字で構成されるものと1文字で構成されるものがあります。C 言語の1文字演算子は次のとおりです。
! % ^ & * - + = ~ | . < > / ? : , [ ] ( ) #
C言語の複数文字演算子は次のとおりです。
++ -- -> << >> <= >= == != *= /= %= += -= <<= >>= &= ^= |= ## && ||
#および##の演算子は前処理マクロ定義でのみ使用できます。あらかじめ定義されたマクロと前処理命令についての詳細は, 第8章を参照してください。
もう1つの sizeof
演算子はデータ型のサイズを決定します。
sizeof
演算子についての詳細は,第6章を参照してください。
旧形式の複合代入演算子( =+
,=-
,=*
,=/
,=%
,
=<<
,
=>>
,
=&
,
=^
,
および =|
)は,ANSI C規格ではサポートされません。
これらの演算子をプログラム中で使用した場合の演算結果は保証できません。
次にその例を示します。
x =-3;
この構文では x
に
-3
が代入され,x-3
は代入されません。
旧形式の複合代入演算子を見つけると,エラー検査のコンパイル・オプションが警告メッセージを表示します。
C言語の文字のいくつかは区切り記号として使用され,構文および意味上で独自の機能を持っています。 区切り記号は演算子でも識別子でもありません。 表 1-4はC言語の区切り記号の一覧です。
区切り記号 | 用 途 | 例 |
---|---|---|
< > | ヘッダ名 | <limits.h>
|
[ ] | 配列区切り文字 | char a[7]; |
{ } | 初期化子並び,関数本体, または複文区切り文字 | char x[4] = {'H', 'i',
'!', '\0' }; |
( ) | 関数の仮引数並び区切り文字,または式のグループ分け | int f (x,y) |
* | ポインタ宣言 | int
*x; |
, | 実引数並びセパレータ | char x[4] = { 'H', 'i',
'!', '\0'}; |
: | 文ラベル | labela: if (x == 0) x +=
1; |
= | 宣言初期化子 | char x[4] = { "Hi!" }; |
; | 文の終了 | x
+= 1; |
... | 可変個の実引数並び | int f ( int y, ...)
|
# | 前処理命令 | #include <limits.h> |
' ' | 文字定数 | char x =
'x'; |
" " | 文字列リテラルまたはヘッダ名 | char x[] = "Hi!";
|
次の区切り記号は,組み合わせて使用する必要があります。
< >
[ ]
( )
' '
" "
{ }
文字の中には,区切り記号や演算子または演算子の一部のいずれとしても使用できるものがあります。 このような文字は,文脈中の発生箇所によって意味が決まります。 区切り記号は通常,表 1-4に示しているようにC構成要素のそれぞれの型を区切るものです。
文字列リテラルは,二重引用符で囲まれた, 0個以上のマルチバイト文字の列です("xyz"など)。 文字列リテラルには,任意の有効文字 (空白文字と文字エスケープ・シーケンスを含む)を含めることができます。 ワイド文字列リテラルは, L という文字が前に付くことを除けば,同じです。 いったん文字列に文字列リテラルを格納した後に, その文字列を変更した場合の動作は規定されていません。
次の例において,ABC
は文字列リテラルです。
これは1つの文字配列に割り当てられ,この文字配列には文字列リテラルの各文字が1
つずつ配列要素として格納されます。文字配列に文字列リテラルを格納することにより,
その配列の文字を修正できるようになります。
char x[] = "ABC";
通常は char
(文字列リテラルが
L
で始まる場合は wchar_
t
)型の配列として格納され,静的記憶域存続期間を持ちます。
次の宣言は,文字配列を宣言して文字列
"Hello!"
を保持しています。
char s[] = "Hello!";
s
文字配列は二重引用符内に指定した文字で初期化され,
ヌル文字 '\0'
で終了します。ヌル文字は各文字列の終わりを示し,
コンパイラにより文字列リテラルの終わりに自動的に追加されます。
行の終わりに1つのヌル文字が追加された隣接の文字列リテラルは自動的に連結され,
行継続文字(行の終わりのバックスラッシュ)
をつける必要はなくなります。
通常の文字列リテラルとワイド文字列リテラルは,連結させることができ, その場合,通常の文字列が拡張されてワイド文字列になり, 結果としてワイド文字列が生成されます。
次に,有効な文字列リテラルの例を示します。
"" /* Here's a string with only the null character */ "You can have many characters in a string." "\"You can mix characters and escape sequences.\"\n" "Long lines of text can be continued on the next line \ by using the backslash character at the end of a line." "Or, long lines of text can be continued by using " "ANSI's concatenation of adjacent string literals." "\'\n" /* Only escape sequences are in this string */
文字列リテラルの長さ(ヌル文字は含まない)を調べるには,
strlen
関数を使用します。文字列処理で使用可能なその他のライブラリ・
ルーチンについての詳細は,第9章を参照してください。
C言語には次の4種類の定数があります。
63
,0
,42L
など)
1.2
,0.00
,77E+2
など)
0x1P-1
や 0x.1P3
など)
'A'
,'0'
,L'\n'
など)
enum boolean { NO, YES };
など。
この場合は NO
と
YES
が列挙定数。)
上記の4つの定数について,次に説明します。
どの定数の値も,指定する型が表現可能な値の範囲内であることが必要です。 定数は,その型の種類に関係なく変更しないリテラル値またはシンボル値です。 また,定数は第2.14節に定義されているように右辺値です。
整数定数はすべての数を表すために使用します。整数定数は10 進基数,8進基数,または16進基数で指定することができます。またオプションによって, 基数を指定する接頭語と型を指定する接尾語を含めることもできます。 整数定数には,ピリオドまたは指数部を含めることはできません。
整数定数を指定する場合には,次の規則に従ってください。
X
(または x
)文字を続ける。
X
または x
の後には,1つ以上の16進文字(0〜9の数字とA〜Fの大文字または小文字)
を続ける。16進定数の値は基数16で計算される(A〜Fの文字が10
〜15のそれぞれの値に相当する)。
値に L
,l
, LL
(Alpha 専用), ll
(Alpha 専用),U
,または
u
が接尾語として付かない場合は,
整数定数の型は特に指定しない限り定数値を保持できる最小の型になります。
C99規格では,表現するために少なくとも64ビットを必要とする値の範囲を
持つ標準の整数型として,long long int
型
(符号付きと符号なしの両方) を導入しました。
Alphaシステム上の Compaq C では,
long long
型を言語拡張として以前のリリースで
実装していましたが,
コンパイラは整数定数の型を決定するときにはC89規則に従っていました。
この規則では,接尾語なしの10進整数に対し,
signed long
で表すには大きすぎるが unsigned long
に
収まる値の場合には unsigned long
型が割り当てられ,
unsigned long
で表すには大きすぎる値の場合だけ
long long
型が割り当てられます。
(注意: long long
データ型がサポートされるのは,
Alphaシステムだけです。)
long long
型を標準化する際に,
C99規格ではこれらの規則が調整され,
さらに長い型に拡張できるようになりました。
特に,接尾語なしの10進整数定数には,
その値を保持できる最小の符号付き整数型が割り当てられます
(最小の型は,int
のままです)。
signed long long
の最大値よりも大きい値の場合,
次に大きい符号付き整数型が処理系で定義されていれば,
この型が割り当てられます。
このような型がない場合,C99では動作を未定義としています。
ただし,Compaq Cでは,
unsigned long long
型を次に使用します。
10進定数に符号なしの型を指定する方法で移植性があるのは,
uかUを含む接尾語を使用する方法だけです。
Compaq Cは,VAXCモード,COMMONモード, およびStrict ANSI89モード(MIAを含む)ではC89規則を引き続き使用しますが, その他のすべてのモードでは新しいC99規則を使用します。 表 1-5に, 整数定数の型を決定する規則を示します。 整数定数の型は,対応するリスト中で,その値を表現できる最初の型になります。
接尾語 | 10進定数 | 8進定数または16進定数 |
---|---|---|
なし |
|
|
uまたはU |
|
|
lまたはL |
|
|
uまたはUと lまたはLの両方 |
|
|
llまたはLL |
|
|
uまたはUと llまたはLLの両方 |
|
|
long long int
の前にunsigned long int
が割り当てられます。
たとえば,定数 59
には int
データ型が割り当てられます。
定数 59L
には long
データ型が割り当てられます。
定数 59UL
には unsigned long int
データ型が割り当てられます。
整数定数値は常に0または正の整数です。先頭のマイナスは定数の一部ではなく, 単項演算子として解釈されます。値が最大整数値を超えた場合( オーバフローを起こした場合)には,コンパイラは警告メッセージを出し, その整数型の最大表現可能な値を使用します。接尾語の付いていない整数定数は, 明示的な指定なしでその定数を最小の整数型で表せるため, 複数の異なる型が割り当てられることがあります。
整数定数の型を決定する新しいC99規則を使用すると,
以前のバージョンのコンパイラで符号なしの型が割り当てられていた定数が,
符号付きの型として解釈されることがあります。
この違いにより,プログラムの動作に多少影響がある可能性があります。
新しいメッセージ
浮動小数点定数には有効数字部があり,
この後に指数部と,その型を指定する接尾語(オプション)を
続けることができます(例: 32.45E2
)。
有効数字部の構成要素としては,整数部を表す数字列,その後にピリオド
(.
),その後に小数部を表す数字列があります。
指数部の構成要素としては,e,E,p,またはP,その後に数字列 (オプションで符号付き)からなる指数があります。
有効数字部の整数部と小数部のいずれかが存在しなければなりません。 10進浮動小数点定数の場合,ピリオドと指数部のいずれかが存在しなければなりません。
浮動小数点定数の有効数字部は,10進または16進の有理数として 解釈されます。 指数部の数字列は,10進整数として解釈されます。 10進浮動小数点定数の場合,指数部は10の累乗を示し, これにより有効数字部がスケーリングされます。 16進浮動小数点定数の場合,指数部は2の累乗を示し, これにより有効数字部がスケーリングされます。 10進浮動小数点定数,およびFLT_RADIXが2の累乗でない 16進浮動小数点定数の場合,プラットフォーム依存の選択方法により, 結果は表現可能な最も近い値か, 表現可能な最も近い値に隣接する表現可能な値 (大きい側の値または小さい側の値)になります。 FLT_RADIXが2の累乗の16進浮動小数点定数の場合,結果は正確に丸められます。
浮動小数点定数値は負でない数でなければなりません。 先頭のマイナスは定数部には含められず,単項演算子と解釈されます。
浮動小数点定数には,次の型があります。
double
型。
値が double
型で表現できる最大値を超えた場合,コンパイラはオーバフローの警告を出力します。
(結果は,double
型に納まるように切り詰められます。)
float
型。
long double
型。
16進浮動小数点定数について簡単に説明します。 C99規格で,浮動小数点定数の16進形式が導入されました。 この形式の定数によって,浮動小数点値が, 仮数部の最下位ビットまで正確に記述できるようになりました。 この形式では,表現にビット・バターンは指定しません。 代りに,通常の10進浮動小数点定数と同じように解釈されます。 ただし,有効数字部は16進数で書き,指数部は有効数字部を乗算する 2の累乗を示す10進整数として表現されます。 有効数字部と指数部は,"E"ではなく"P"で区切ります。 このため,たとえば1/2は,0x1P-1または0x.1P3と書くことができます。
C99規格では,この形式の値用に,printf
/scanf
の指定子も追加しています。
ただし,この機能は,OpenVMS Version 7.3以降のOpenVMS実行時ライブラリでサポートされます。
表 1-6に,有効な表記オプションの例を示します。
表 記 | 値 | 型 |
---|---|---|
.0 | 0.000000 | double |
0. | 0.000000 | double |
2. | 2.000000 | double |
2.5 | 2.500000 | double |
2e1 | 20.00000 | double |
2E1 | 20.00000 | double |
0x1P-1 | 0.500000 | double |
0x.1P3 | 0.500000 | double |
2.E+1 | 20.00000 | double |
2e+1 | 20.00000 | double |
2e-1 | 0.200000 | double |
2.5e4 | 25000.00 | double |
2.5E+4 | 25000.00 | double |
2.5F | 2.500000 | float |
2.5L | 2.500000 | long double |
文字定数は,ソース文字集合の任意の文字を一重引用符で囲んだものです。
文字定数は int
型のオブジェクトで表されます。
次にその例を示します。
char alpha = 'A';
第1.9.3.3項で説明するように改行文字, 一重引用符,二重引用符,およびバックスラッシュなどの文字は, エスケープ・シーケンスを使用して文字定数に含めることができます。 また,第1.9.3.4項で説明するように, すべての有効文字を数値エスケープ・シーケンスを使用して定数に含めることもできます。
単一文字を含む文字定数の値は,現在の文字集合におけるその文字の数値です。
次に説明するように,一重引用符内に複数の文字を含む文字定数はコンパイラが決定する値を持ちます。8
進または16進のエスケープ・
シーケンスで表される文字定数値は,エスケープ・シーケンスの8進値または16
進値と同じです。ワイド文字定数の値は,mbtowc
ライブラリ関数が決定します(
第1.9.3.1項を参照してください)。
1つの文字定数は,最大4文字という制限があります。一重引用符で4文字以上の文字を囲むと(
例: 'ABCDE'
),オーバフロー警告が出ます。
文字定数の順番を決定するバイトはプラットフォームにより異なりますので, ご注意ください。
C言語はワイド文字を使用して拡張文字集合を提供します。
ワイド文字とは,
char
型には格納できない大きい文字のことです。
wchar_t
型は通常,257文字以上の可能な文字を必要とする文字集合の文字定数を表すために使用します。
この理由は,8ビットでは最大で256
までの異なる値しか表すことができないからです。
拡張文字集合の文字定数は,先頭に L
を付けて記述し,ワイド文字定数と呼ばれます。
ワイド文字定数は wchar_t
整数型であり,
<stddef.h>
ヘッダ・ファイルに定義されています。ワイド文字定数は,
通常の文字エスケープ・シーケンスのように8進文字または16
進文字のエスケープ・シーケンスで表すことができますが,先頭に
L
を付ける必要があります。
ワイド文字で構成される文字列を形成することもできます。コンパイラは文字列が
wchar_t
型の配列であるかのように記憶域を割り当て,
ワイド・ヌル文字 '\0'
を文字列の終わりに付けます。
この配列は文字列の文字およびワイド・ヌル文字を格納できる長さであり,
指定した文字で初期化されます。
次の例は,有効なワイド文字定数と文字列リテラルを示しています。
wchar_t wc = L'A'; wchar_t wmc = L'ABCD'; wchar_t *wstring = L"Hello!"; wchar_t *x = L"Wide"; wchar_t z[] = L"wide string";
Compaq Cコンパイラは,32ビットの記憶域に
unsigned long
オブジェクト
(OpenVMS)またはunsigned int
オブジェクト
(Tru64 UNIX)としてwchar_
t
オブジェクトを格納します。ワイド文字の終わりのヌル文字は32
ビットの長さです。
非ASCII文字を通常の8ビットの char
サイズで表すために,
シフト依存のコード化された方式を使用した拡張文字集合を使用することができます。
このコード化によって,多バイト文字
が生成されます。ANSI C規格では,wchar_t
ワイド文字型を提供するとともに,
このコード化された方式をサポートしています。
Compaq CではANSI規格に準拠して,次の文脈で多バイト文字を認識します。
多バイト文字のコードの入出力を適切に行ったり,既存の文字列処理ルーチンとの矛盾を回避するには, 多バイト文字を使用する際に次の規則に従う必要があります。
多バイト文字をワイド文字定数とワイド文字列リテラルに変換すると,シフト状態のコード化を処理する際に, プログラミング上の問題が少なくなります。 多バイト文字をワイド文字に変換するために,いくつかのCライブラリ関数を使用できます。 詳細については,第9章を参照してください。
標準端末に表示できない文字,または文字定数や文字列リテラルに使用されている場合に特定の意味を持つ文字は,
文字エスケープ・
シーケンスとして入力することによって,ソース文字として入力できます。
バックスラッシュ( \
)は,各文字エスケープ・シーケンスを開始します。各エスケープ・
シーケンスは,char
または
wchar_t
オブジェクトに格納されます。表 1-7
は,ANSI定義のエスケープ・
シーケンスの一覧です。
文字 | エスケープ・シーケンス |
---|---|
警告(ベル) | \a
|
バックスペース | \b |
フォーム・フィード | \f |
改行 | \n |
キャリッジ・ リターン | \r |
水平タブ | \t |
垂直タブ | \v
|
バックスラッシュ | \\ |
一重引用符 | \' |
二重引用符 | \" |
疑問符 | \? |
これ以外の文字エスケープ・シーケンスは無効です。ソース・コード内にこれ以外のシーケンスを見つけると, コンパイラは警告を出し,バックスラッシュ文字は無視されます。
次に,文字エスケープ・シーケンスを使用した例を示します。
printf ("\t\aReady\?\n");
これを実行すると警告ベルが鳴り,次のプロンプトが表示されます。
Ready?
コンパイラはすべての文字を整数表現として扱うため,ソース・コードの任意の文字をそれに相当する数値で表現することができます。
これを,
数値エスケープ・シーケンスと呼びます。この文字は,
バックスラッシュ( \
)を入力し,
それに続けて現在の文字集合に相当する8進または16進の整数を記述します(ASCII
等価テーブルについては,付録 C
を参照してください)。たとえば,ASCII文字集合を使用する場合,
文字の A
は
\101
(8進表現)または \x41
(16進表現)と表現することができます。数値エスケープ・シーケンスでは8
進の値が省略時の値ですから,この例では前に
0
を付ける必要はありません。バックスラッシュの後の小文字の
x
は16進表現を示します。たとえば,
\x5A
は文字 Z
と同値です。
次に,数値エスケープ・シーケンスの例を示します。
#define NULL '\0' /* Defines logical null character */ char x[] = {'\110','\145','\154','\154','\157','\41','\0'}; /* Initializes x with "Hello!" */
エスケープ・シーケンスは,8進数の場合は3つの数字を展開するか,
または最初の文字以外の8進数以外文字が見つかるまで展開します。
たとえば,文字列
"\089"
は \0
,8
,9
,
および \0
の4文字と解釈されます。
16進エスケープ・シーケンスの場合,エスケープ・シーケンスの文字数に制限はありません。
ただし,16進の値が通常の文字定数の
unsigned char
型で表すことのできる最大値,
またはワイド文字定数の wchar_t
型で表すことのできる最大値を超える場合の結果は保証できません。
たとえば,
'\x777'
は不正な例です。
また,3文字を超える文字数を持つ16進エスケープ・シーケンスは,エラー検査のコンパイル・ オプションを使用すると警告が出されます。
16進エスケープ・シーケンスの後に16進数を指定するために,文字列の連結を使用することができます。
次の例では,a
は両方の場合で同じ値に初期化されます。
char a[] = "\xff" "f"; char a[] = {'\xff', 'f', '\0'};
実行するマシンが異なる文字集合を使用している場合,数値エスケープ・
シーケンスを使用して作成されたプログラムは移植できません。算術演算を整数文字値で実行すると,
移植時にまた別の問題が発生します。これは,
マシンごとに複数文字定数(例: 'ABC'
)の表現が異なるからです。
列挙型は,1つ以上の列挙定数を指定して許容値を定義します。
列挙定数は int
型を持ちます。
列挙型の宣言と使用についての詳細は,第3.6節を参照してください。
ヘッダ・ファイルとは,コンパイル時にソース・ファイルに取り込まれるテキスト・
ファイルです。コンパイル時にヘッダ・ファイルを取り込むには,
#include
前処理命令をソース・ファイルに使用します。
命令についての詳細は,第8
章を参照してください。#include
前処理命令は,内容とは関係なくヘッダ・
ファイル全体に置き換わります。
別ファイルを取り込むために,ヘッダ・ファイルに他の
#include
前処理命令を含めることができます。
#include
命令は任意の深さでネストできます。
ヘッダ・ファイルには任意の有効なCソース・コードを取り込むことができます。
ヘッダ・ファイルは,外部変数宣言,マクロ定義,型定義,および関数宣言を取り込むために使用します。
stdio.h
ヘッダ・
ファイルにCライブラリ入出力関数が宣言されているように,論理的に関連する関数のグループは1
つのヘッダ・ファイル内に一緒に宣言されます。
ヘッダ・ファイルには,習慣として .h
という接尾語(例: stdio.h
)を付けます。
ヘッダ・ファイルにこれらの区切り文字を使用できることが定義されていないので,
ヘッダ・ファイル名として
'
,\
,"
,または
\*
の文字を使用することはできません。
プログラムで参照する場合には,次の例に示すようにヘッダ・ファイル名は山括弧または二重引用符で囲みます。
#include <math.h> /* or */ #include "local.h"
2つの書式の相違については,第8章で説明します。 指定されたファイルを検索するためにコンパイラが使用するアルゴリズムについては, 第B.37節で説明します。ANSI 規格ヘッダ・ファイルの各ライブラリ・ルーチンについては,第9章で説明します。
ANSI C規格では,C言語の使用について環境上の制限をいくつか挙げています。 この制限は,Cコンパイラの規格合致の処理系のために最小限の規格を定義しようとしたものです。 たとえば,識別子における有効文字数は,ANSI C 規格が必要とする最小限のセットにより処理系が定義するものです。
また,ANSI C規格には,汎整数型と浮動小数点型の特性を制限する数値制限も含まれています。 ほとんどの場合,このような制限はC言語またはコンパイラの使用には影響を及ぼしません。 しかし,通常とは異なる大きいプログラムまたは通常とは異なる構成のプログラムの場合に, 特定の制限に到達する可能性があります。ANSI 規格には最小限の制限があるので, Compaq Cでの実際の制限についてはプラットフォームに固有の Compaq Cマニュアルをご覧ください。
ANSI C規格で示されているように,Compaq Cの処理系ではすでに翻訳上の多くの制限が取り除かれ, アプリケーションをより自由に使用することができます。 Compaq Cの制限は次のとおりです。
数値制限は,整数型と浮動小数点型のサイズと特性を定義します。
数値制限については,limits.h
および
float.h
ヘッダ・ファイルに記述されています。制限は次のとおりです。
char
型の各文字は8ビットで表現される。
wchar_t
型の各文字は32ビットで表現される。
char
型のマシン表現と有効値は
signed char
型の場合と同様。コンパイル・コマンド行オプションは,
この同値を unsigned char
に変更する。
int
型および
signed int
型のマシン表現と有効値は
long int
型の場合と同様。
unsigned int
のマシン表現と有効値は unsigned long
int
型の場合と同様。
long int
型と
unsigned long int
型は64ビットであり,
int
型とunsigned int
型は32ビットである。
long double
型のマシン表現と有効値は
double
型の場合と同様。
実行文字集合の文字は,画面またはファイルの現在印字位置に出力されます。 現在印字位置は,次の出力文字が現れる場所としてANSI C 規格で定義されています。文字が出力されると,現在印字位置が現在行の次の位置( 左または右)に進みます。
Compaq Cコンパイラは,出力行を超えて左から右へ現在印字位置を移動させます。