-
C/C++プログラムのソースコードからプリプロセッサコードを生成する方法
この記事では、C言語やC++のソースコードから、プリプロセス済み(プリプロセッサ)コードを生成して確認する方法を解説します。g++コンパイラを使用してプリプロセス後のコードを出力するには、「-E」オプションを付けてコンパイルします。このオプションを指定すると、コンパイルやアセンブルは行われず、プリプロセッサが処理した結果だけが標準出力に出力されます。プリプロセッサは、コード内に含まれるすべての「#」で始まるディレクティブ(#include や #define など)を処理し、さらにマクロ関数もすべて展開します。そのため、ヘッダファイルの中身まで含めた膨大なコードが出力されることもあります。構文
-
C/C++における前置インクリメント(++x)と後置インクリメント(x++)の違いを徹底解説
CやC++には、変数の値を1つ増やす「インクリメント演算子」が2種類あります。それが前置インクリメント(++x)と後置インクリメント(x++)です。どちらも変数の値を+1するという点では同じですが、動作のタイミングに重要な違いがあります。 前置インクリメントと後置インクリメントの基本的な違い 前置インクリメント(++x)は、まず変数の値を1つ増やしてから、その新しい値を他の変数に代入します。 一方、後置インクリメント(x++)は、先に現在の値を他の変数に代入し、その後に値を1つ増やします。 この「増やすタイミング」の違いにより、代入結果が大きく変わるため、コードを書く際には注意が必要です。 サ
-
【C言語】整数値と文字値はメモリにどう格納されるのか
これまでのプログラムの中で、整数型や文字型の変数を何度も使ってきました。しかし、その値が実際にメモリ上へどのように格納されているのかを意識したことは少ないかもしれません。この記事では、C言語における整数値・文字値のメモリ上での扱いについて詳しく解説します。 文字値も実は整数として格納される C言語では、文字値も内部的には整数として扱われます。char型は1バイト(8ビット)のサイズしか持たないため、格納できるのは通常 -128〜127 の範囲の値だけです。この範囲を超える値を代入すると、上位のビットが切り捨てられ、予想外の結果になります。 例1:char型に270を代入した場合 以下のコー
-
C言語における変数の暗黙的な初期化 ― 0と1はどこから来るのか?
C言語では、変数を使用する前に必ず宣言しなければならないのが基本ルールです。しかし実際には、宣言や明示的な代入を行っていないのに、変数に0や1が自動的に格納されていることがあります。 この現象は「暗黙的な初期化」と呼ばれます。C言語の仕様では、グローバル変数やstatic変数は、明示的に初期化しなくてもプログラム起動時に自動的に0で初期化されるためです。 サンプルコード①:グローバル変数の暗黙的な初期化 #include <stdio.h> #include <stdlib.h> x, y, array[3]; // 型指定なしで宣言されたグローバル変数(暗黙的に初期
-
C・C++で関数のアドレスを取得する方法
CやC++では、変数はメモリ上に格納されるため、そのメモリアドレスを取得することができます。実は関数も同様にメモリ上に格納されており、それぞれ固有のアドレスを持っています。関数のアドレスを取得する方法は非常にシンプルで、関数名を括弧「()」を付けずに記述するだけです。関数名を単体で書くと、それは関数ポインタとして評価され、関数が配置されているメモリ上の先頭アドレスを表します。サンプルコード以下のプログラムでは、my_function と main の2つの関数のアドレスを %p 書式指定子を使って出力しています。#include <stdio.h> void my_functio
-
C言語でintに複数の文字を代入すると?マルチキャラクタ定数の動作を解説
C言語やC++では、char型のデータは内部的にASCIIコードの数値として格納されています。そのため、1文字を整数(%d)として出力すると、対応するASCIIコードが表示されます。ところが、シングルクォートの中に複数の文字を記述して出力しようとすると、一見すると奇妙な大きな数値が表示されることがあります。これは「マルチキャラクタ定数」と呼ばれる挙動によるものです。以下のプログラムでその様子を確認してみましょう。サンプルプログラム#include <stdio.h> int main() { printf(%d\n, A); printf(%d\n, AA);
-
C言語のmbtowc関数とは?マルチバイト文字をワイド文字に変換する方法
C標準ライブラリの関数 int mbtowc(wchar_t *pwc, const char *str, size_t n) は、マルチバイト文字シーケンス(複数バイトで構成される文字列)を1つのワイド文字(wchar_t型)に変換します。プロトタイプ宣言int mbtowc(wchar_t *pwc, const char *str, size_t n);パラメータpwc − 変換結果のワイド文字を格納する wchar_t 型オブジェクトへのポインタです。str − 変換対象となるマルチバイト文字の先頭バイトへのポインタです。n − 文字の長さを判定するために読み込む最大バイト数です。戻り
-
C言語の可変長引数(stdarg.h)の使い方をわかりやすく解説
プログラミングをしていると、引数の数をあらかじめ固定せず、呼び出しのたびに異なる個数の引数(パラメータ)を受け取れる関数を作りたい場面に出くわすことがあります。C/C++言語では、このニーズに応える仕組みが標準で用意されており、要件に合わせて可変個の引数を受け取る関数を定義できます。以下に、そのような関数の定義例を示します。 int func(int, ... ) { . . . } int main() { func(1, 2, 3); func(1, 2, 3, 4); } ここで注目すべきは、関数 func() の最後の引数が省略記号(エリプシス
-
浮動小数点数を丸める1行だけのC関数の書き方
はじめにC言語では、標準ライブラリの round() 関数に頼らなくても、たった1行のコードで浮動小数点数を四捨五入できる自作関数を書くことができます。本記事では、そのシンプルかつ効果的な実装方法を解説します。丸め処理の基本的な考え方この問題を解決するために、以下の手順に従います。対象となる浮動小数点数を受け取る数値が正の場合は 0.5 を加算する数値が負の場合は 0.5 を減算するキャスト(型変換)によって浮動小数点値を整数に変換するなぜこの方法が機能するのかC言語において、float 型や double 型を int 型へキャストすると、小数部分はゼロ方向へ切り捨てられます。この性質を利用
-
main()関数からprintf()の出力を変更する方法を解説
この記事では、main()関数からprintf()関数の出力を変更する方法について解説します。具体的には、特定の形式のprintf()呼び出しを、指定した別の値に置き換える関数を定義する手法を紹介します。このタスクを実現するために、#defineマクロを使用します。ポイントは、このマクロを関数の中で定義することです。#define行を関数の外に直接記述することも可能ですが、その場合はプログラム全体で常にprintf()が置き換えられてしまいます。main()から制御できるようにするには、まず専用の関数を呼び出す必要があります。コード例#include <stdio.h> void
-
C言語で関数の実行時間を測定する方法
この記事では、C言語でプログラムや関数の処理にかかる時間を計測する方法について解説します。時間の測定には、time.hヘッダーファイルに定義されているclock()関数を使用します。基本的な考え方経過時間を求めるには、以下の手順に従います。処理の開始直前にclock()を呼び出して開始時刻を取得する処理の終了直後に再度clock()を呼び出して終了時刻を取得する両者の差分を計算する差分をCLOCKS_PER_SEC(1秒あたりのクロックティック数)で割ることで、実際に消費されたプロセッサ時間を秒単位で求めるclock()の戻り値はclock_t型であるため、秒単位に変換する際はdouble型へ
-
C言語のsetjmp()とlongjmp()を徹底解説!例外処理と非ループ処理の実装方法
この記事では、C言語におけるsetjmp()とlongjmp()について詳しく解説します。これら2つの関数はsetjmp.hヘッダーファイルに定義されており、それぞれ以下のような構文で使用します。setjmp(jmp_buf buf) : 現在の実行位置をbufに保存し、最初の呼び出し時には0を返す。longjmp(jmp_buf buf, i) : bufが指し示す位置へ制御を戻し、iを返す。これらの関数は、C言語で例外処理を実現するために活用されます。JavaやC++などの言語にあるtry-catch構文と同様の役割を果たし、setjmp()はtryブロックのように、longjmp()はt
-
【C言語】trunc()・truncf()・truncl()で浮動小数点数を切り捨てる方法
この記事では、C言語の数学関数である trunc()、truncf()、truncl() の3つの関数について解説します。これらの関数は、浮動小数点値の小数部分を切り捨て、整数部分だけを取り出すために使用されます。いずれも <math.h> ヘッダーをインクルードして利用します。trunc() 関数trunc() 関数は、double 型の値を切り捨てるための関数です。引数として渡された値の小数部分を削除し、整数部分のみを double 型で返します。構文は以下のとおりです。double trunc(double argument)使用例#include <stdio.h&g
-
C言語でfloat・double型の2つの数値の剰余(モジュロ)を求める方法
C言語では、float や double といった浮動小数点型の2つの数値に対して、剰余(モジュロ)を求めることができます。剰余とは、割り算を行った際の「余り」を計算する演算のことです。 整数型であれば % 演算子が使えますが、浮動小数点数には適用できません。そこで活躍するのが、<math.h> ヘッダーで定義されている remainder() 関数です。この関数は、分子÷分母の浮動小数点剰余を計算するために用意されています。 remainder() 関数の仕組み remainder(x, y) の戻り値は、次の式で表されます。 remainder(x, y) = x − rquo
-
C言語でホスト名とIPアドレスを取得して表示する方法
この記事では、C言語を使ってローカルシステムのホスト名とIPアドレスを簡単に取得・表示する方法を解説します。ホスト名とIPアドレスを調べるためのCプログラムを実際に書きながら、その仕組みを学んでいきましょう。本プログラムでは、以下の関数を使用します。それぞれの関数には異なる役割があるため、まずは各関数の概要を確認しておきましょう。使用する主な関数関数名説明gethostname()ローカルコンピュータの標準的なホスト名を取得します。gethostbyname()ホストデータベースから、指定したホスト名に対応するホスト情報を検索します。inet_ntoa()IPv4のインターネットネットワークア
-
【C言語】ループ・再帰・マクロ展開なしで数値を100回出力する方法
本記事では、C言語で数値を100回出力する方法を解説します。ただし、ここにはいくつかの制約があります。ループ文、再帰呼び出し、マクロ展開は一切使用できないという条件です。 解決策:setjmp() と longjmp() を活用する この制約をクリアするために利用するのが、setjmp.h ヘッダーで提供されている setjmp() 関数と longjmp() 関数です。 setjmp() は、呼び出された時点のプログラムの状態(ジャンプ位置)を jmp_buf 型のバッファに保存します。一方、longjmp() は、その保存された位置へプログラムの制御を戻す役割を持ちます。この2つの関数を組
-
C/C++でint型配列のサイズ(要素数)を取得する方法
C言語やC++で整数型(int型)配列のサイズを取得する方法について解説します。ここでいう「サイズ」とは、配列に含まれる要素の数を数えることを意味します。sizeof()演算子を使った基本的な方法配列の要素数を取得するには、sizeof() 演算子を使用します。sizeof() の引数に配列名を渡すと、その配列が占有しているメモリブロック全体の合計サイズ(バイト数)が返されます。したがって、この合計サイズを「各要素1つ分のサイズ」で割り算することで、配列内の要素数を求めることができます。計算式は以下の通りです。要素数 = sizeof(配列名) / sizeof(配列名[0])サンプルコード実
-
C/C++でint型をASCII文字に変換する方法
C言語やC++では、文字は内部的にASCIIコードとして格納されています。そのため、int型の数値をASCII値に変換したい場合は、文字「0」のASCII値(10進数で48)を整数に加算するだけで簡単に実現できます。この仕組みを利用すると、0〜9までの1桁の数字を対応するASCIIコードへ変換できます。以下に、int型の数値をASCII値へ変換するサンプルプログラムを示します。サンプルコード#include<stdio.h> int intToAscii(int number) { return 0 + number; } main() { printf(The A
-
C言語のprintfにおける%pフォーマット指定子の使い方と役割
C言語には、%dや%sなど、さまざまなフォーマット指定子が用意されています。その中でも今回は、ポインタ型のデータを出力するためのフォーマット指定子「%p」について解説します。%pとは何か%pは、printf関数においてポインタ(メモリアドレス)の値を表示するために使用される変換指定子です。通常、アドレスは16進数形式で出力されます。具体的な動作を、以下のサンプルコードで確認してみましょう。サンプルコード#include <stdio.h> int main(void) { int x = 50; int *ptr = &x; /* 変数xのアドレスをpt
-
C/C++における%pと%xの違いを解説!ポインタと16進数の出力の使い分け
CやC++のプログラミングにおいて、printf関数で使用できる書式指定子「%p」と「%x」には、それぞれ異なる役割があります。この記事では、両者の違いについて具体例を交えながら詳しく解説します。 %pと%xの基本的な違い 「%p」は主にポインタ(メモリアドレス)の値を出力するために使用される書式指定子です。一方、「%x」は値を16進数形式で出力するためのものです。 なお、ポインタの値は「%u」(符号なし10進数)や「%x」を使って表示することも技術的には可能ですが、処理系によっては正しく表示されない場合があります。そのため、ポインタを扱う際には「%p」を使用することが推奨されています。