-
C言語の整数拡張(Integer Promotion)とは?仕組みをサンプルコードで解説
C言語には、int型よりも少ないバイト数で表現されるデータ型がいくつか存在します。代表的なものとしては、char型やshort型などが挙げられます。これらの小さなデータ型に対して演算を行うと、自動的にint型へと昇格(プロモート)されます。この動作は「整数拡張(Integer Promotion)」と呼ばれ、C言語の重要な仕様の一つです。整数拡張のサンプルプログラム以下は、C言語における整数拡張の動作を確認できるサンプルプログラムです。#include <stdio.h> int main() { char x = 68; char y = 34; prin
-
C/C++における関数レベルの静的変数はいつ初期化されるのか?
静的変数(static変数)は、staticキーワードを使用して定義できます。静的変数はプログラムの実行中ずっとメモリ上に存在し続け、その寿命はプログラム全体の実行期間に及びます。これは、関数が実行されている間だけメモリに存在し、関数の終了とともに破棄される自動変数(ローカル変数)とは大きく異なる点です。初期化のタイミング関数レベルの静的変数の場合、メモリ領域自体はプログラムのロード時に確保されますが、実際に作成され、初期化が行われるのは最初にその変数が使用されたときです。つまり、関数が何度呼び出されても、初期化処理が実行されるのは一度きりであり、以降の呼び出しでは前回の値がそのまま引き継がれ
-
C言語におけるポインタと配列の違いを徹底解説!基本からサンプルコードまで
はじめに C言語において「ポインタ」と「配列」は非常によく似た挙動を示すため、初心者が混同しやすい概念の一つです。しかし、両者はメモリの扱い方や性質がまったく異なります。本記事では、それぞれの特徴を具体例とともに解説し、違いを明確にしていきます。 ポインタとは ポインタとは、別の変数のアドレス(メモリ上の場所)を格納するための変数です。変数にメモリが割り当てられると、ポインタはその変数が配置されたメモリアドレスを指します。ポインタ変数を宣言する際には、単項演算子「*(間接参照演算子)」を使用します。 ポインタ宣言の構文 データ型 *変数名; ここで、「データ型」には int や char、
-
C言語で2次元配列を動的に確保する方法
C言語では、単一のポインタを使うことで2次元配列を動的に確保できます。具体的には、malloc関数で「行数 × 列数 × データ型サイズ」分の連続したメモリブロックを確保し、ポインタ演算によって各行列要素にアクセスします。 以下に、この方法を示すサンプルプログラムを紹介します。 サンプルコード #include <stdio.h> #include <stdlib.h> int main() { int row = 2, col = 3; int *arr = (int *)malloc(row * col * sizeof(int)); int
-
C言語で2次元配列を関数の引数(パラメーター)として渡す方法
C言語では、2次元配列を関数の引数(パラメーター)として簡単に渡すことができます。本記事では、配列の行数・列数をグローバル定数として定義した場合の方法を、サンプルプログラムとその実行結果を交えて解説します。2次元配列を引数として渡すサンプルプログラム以下のプログラムでは、4行3列の2次元配列を作成して各要素に初期値を設定した後、関数func()に渡し、すべての要素に5を加算しています。#include <stdio.h> const int R = 4; const int C = 3; void func(int a[R][C]) { &nbs
-
C言語で配列を作成できないデータ型は?void型配列がエラーになる理由を解説
C言語では、int型、char型、float型、double型など、ほとんどのデータ型を使って配列を作成することができます。しかし、void型だけは例外的で、void型による配列の作成は不可能です。無理に宣言しようとすると、コンパイル時にエラーが発生します。実際にどのようなエラーになるのか、以下のサンプルプログラムで確認してみましょう。サンプルコード#include <stdio.h> #include <stdlib.h> int main() { void arr1[4]; printf(A void array); return 0; }実
-
C/C++で長い文字列を複数行に分けて記述する方法
C言語やC++では、長い文字列リテラルを1行で書き続けるとコードが読みにくくなります。そんなときは、ダブルクォート( )で囲まれた文字列リテラルを複数並べることで、文字列の途中の任意の位置で改行し、複数行に分けて記述することができます。コンパイラは、隣接して並べられた文字列リテラルを自動的に連結して1つの文字列として扱うため、実行時には改行なしの1つの長い文字列になります。サンプルコード以下は、この方法を示すC言語のサンプルプログラムです。#include <stdio.h> int main() { char *str = This is the method
-
C/C++における配列の範囲外アクセスと未定義動作について
Javaのような言語では、配列の範囲外にアクセスすると java.lang.ArrayIndexOutOfBoundsException のような例外が発生し、エラーを検知できる仕組みがあります。しかし、C言語にはこのような機能は存在せず、配列の範囲外にアクセスすると未定義動作(undefined behavior)が発生する可能性があります。未定義動作とは、プログラムがクラッシュする、意図しない値を読み込む、一見正常に動作しているように見えるなど、動作が保証されない状態を指します。これは非常に危険なバグの原因となるため、注意が必要です。以下に、C言語で配列の範囲外アクセスがどのような結果をも
-
なぜC/C++のstrncpy()は安全でないとされるのか?原因と安全な代替策を解説
strncpy()は、コピー元(ソース)の文字列から指定した文字数だけ、コピー先(デスティネーション)へ文字列を複製するために使われる標準ライブラリ関数です。一見便利な関数ですが、実際の開発現場では「安全でない関数」とみなされることが多いのです。本記事では、その理由と注意点、さらに安全な代替手段まで詳しく解説します。 strncpy()の基本構文 strncpy()の書式は以下の通りです。 char *strncpy(char *destination, const char *source, size_t n); 各引数の意味は次のようになっています。 destination:コピ
-
C/C++で配列のインデックスが0から始まる理由を解説
配列インデックスがゼロから始まる仕組みC言語やC++において、配列の要素へのアクセスは arr[i] = *(arr + i) という形で解釈されます。ここで arr は配列の先頭要素(インデックス0の要素)のアドレスを表します。つまり、*(arr + i) とは「配列の先頭要素から i だけ離れた位置にある要素」を意味します。ループの最初では i の値が 0 であるため、*(arr + 0) は配列の最初の要素を指すことになります。このポインタ演算の仕組みこそが、配列のインデックスが 1 ではなく 0 から始まる理由です。サンプルプログラム以下のC++プログラムは、この動作を実際に確認できる
-
条件文を使わずに偶数・奇数を判定して表示するC言語プログラム
この記事では、比較演算子(<、<=、!=、>、>=、==)などの条件文を一切使わずに、数値が偶数か奇数かを判定して表示する方法を解説します。 通常、偶数・奇数の判定は条件文を使えば簡単に行えます。数値を2で割り、余りが0であれば偶数、そうでなければ奇数と判定できます。また、数値と1のビットごとのAND演算を行い、結果が0なら偶数、1なら奇数と判定する方法も一般的です。 しかし今回は条件文が使えないため、少し工夫が必要です。ここでは、条件文なしで偶数・奇数を判定する2つの方法を紹介します。 方法1:配列のインデックスを利用する まず、文字列の配列を作成します。インデック
-
ループを使わずに1から100までの数字を出力するCプログラムの書き方
はじめに本記事では、for文やwhile文といったループ構文を一切使用せずに、1から100までの連続した数字を出力するCプログラムの書き方を解説します。再帰を使ったアプローチこの問題は「再帰」を利用することで解決できます。具体的には、自分自身を再帰的に呼び出す関数を作成します。再帰関数には一般的に2つの重要な要素があります。それは「ベースケース」と「再帰呼び出し」です。今回の関数では、引数 n が 1 より大きい場合にのみ、n - 1 を引数として自分自身を再度呼び出します。これにより、n が 1 に到達するまで再帰呼び出しが繰り返されます。その後、再帰が戻る過程で各段階の n の値が順番に出
-
セミコロンなしで「Hello World」を出力するCプログラムの書き方
本記事では、セミコロンを一切使わずに「Hello World」というテキストを出力するCプログラムの書き方を解説します。 通常であれば、main()関数内に printf(Hello World); と記述するだけで、簡単にテキストを画面へ出力できます。しかし、この方法では行末にセミコロンが必要になってしまいます。 セミコロンを回避するテクニック セミコロンを避けるためには、ちょっとしたトリックを活用します。ポイントは、printf() 文を if 文の条件式の中に記述することです。 printf() 関数は、出力した文字列の長さ(文字数)を戻り値として返します。「Hello World」は1
-
Ctrl+Cを押しても終了しないCプログラムの作成方法
はじめに本記事では、Ctrl+Cキーを押しても終了しないC言語プログラムの作成方法を解説します。通常、Ctrl+Cを押すとキーボード割り込みが発生し、実行中のプロセスは強制終了されます。しかし、C言語のシグナルハンドリングの仕組みを利用すれば、Ctrl+Cが押されたタイミングで独自の処理を実行し、プログラムの動作を継続させることが可能です。シグナルとはCtrl+Cが押されると、SIGINT(割り込みシグナル)が生成されます。C言語では、このシグナルを受け取った際の挙動を自由にカスタマイズできます。主なシグナルとその意味は以下の表の通りです。シグナル名説明SIGABRT異常終了を示しますSIGF
-
フォーマット指定子を使わずに文字を出力するCプログラムの書き方
この記事では、フォーマット指定子を一切使わずに文字を出力する方法を解説します。C言語におけるフォーマット指定子とは、%d、%f、%c などのことで、printf() 関数と組み合わせて文字や数値を画面に表示するために使われます。通常、文字を出力するには %c を使用しますが、ここでは %c を使わない別の方法を紹介します。その鍵となるのが、ASCIIコードの値を16進数形式で直接記述するというテクニックです。ASCII値を16進数で直接指定する仕組みC言語では、文字列リテラルの中に「\x」に続けて16進数を記述すると、その値に対応する文字として解釈されます。例えば、大文字の「A」のASCIIコ
-
【C言語】IPアドレスの妥当性を検証するプログラムの作成方法
この記事では、C言語を使ってIPアドレスの妥当性を検証する方法を解説します。入力された文字列が正しいIPv4アドレスの形式に合致しているかどうかを、プログラムで自動的に判定します。IPv4アドレスの形式IPv4アドレスは「ドット・デシマル記法」と呼ばれる形式で表現されます。これは、0から255までの範囲にある10進数4つを、3つのドット(.)で区切って表記するものです。有効なIPアドレスの例:192.168.4.1IPアドレスを検証する手順ドット「.」を区切り文字として、文字列(IPアドレス)をトークンに分割する部分文字列に数値以外の文字が1つでも含まれていれば、無効(false)を返す各トー
-
C言語でPGM形式の画像ファイルを書き出す方法
PGM形式とはPGM(Portable Gray Map:ポータブルグレイマップ)は、グレースケール画像を扱うためのシンプルな画像フォーマットです。C言語で保持している2次元配列をPNGやJPEGなどの一般的な画像形式として保存するには、データを所定のフォーマットにエンコードするための複雑な処理を大量に実装する必要があります。そこで役立つのがNetpbm形式です。Netpbmはオープンソースのグラフィックスプログラム群で、主にLinuxやUnixプラットフォームで利用されていますが、Microsoft Windows環境でも動作します。この形式を利用すれば、2次元配列のデータを簡単かつ移植性の
-
C言語で現在時刻を表示するデジタル時計プログラムの作り方
C言語を使えば、シンプルなコードで現在の時刻を表示するデジタル時計を作ることができます。時刻を扱う際には、標準ライブラリの time.h ヘッダーファイルを利用します。このヘッダーには、日付や時刻に関連する処理を行うための関数やデータ型が定義されています。 time.h の4つの重要な構成要素 size_t:符号なし整数型です。sizeof() 演算子の結果として返される型でもあります。 clock_t:プロセッサが消費した時間(プロセッサ時間)を格納するために使用されます。 time_t:カレンダー上の日時(暦時間)を格納するために使用されます。 struct tm:日付と時刻の情報全体を
-
【C言語】中空のピラミッドとダイヤモンド模様を出力するプログラム
C言語では、塗りつぶし型(ソリッド)のピラミッドパターンは比較的簡単に生成できますが、中空(輪郭のみ)のパターンにするには少し工夫が必要です。この記事では、中空ピラミッドと中空ダイヤモンドの2種類のパターンを生成する方法を、サンプルコードと実行結果とあわせてわかりやすく解説します。中空ピラミッドのパターン中空ピラミッドでは、最初の行に星(*)を1つだけ表示し、最後の行(n行目)にはn個の星を連続して表示します。それ以外の行では、行の先頭と末尾にちょうど2つの星を配置し、その間はすべて空白で埋めます。サンプルコード#include <stdio.h> int main() {
-
C言語でホスト名とIPアドレスを取得して表示するプログラム
はじめに この記事では、ローカルシステムのホスト名とIPアドレスを簡単な方法で確認する方法を解説します。実際にC言語でホスト名とIPアドレスを取得して表示するプログラムを作成してみましょう。 本プログラムでは、以下の関数を使用します。それぞれの関数には異なる役割があるため、まず各関数とその役割を確認しておきましょう。 関数説明 gethostname()ローカルコンピュータの標準的なホスト名を取得します。 gethostbyname()ホストデータベースから、指定したホスト名に対応するホスト情報を検索します。 inet_ntoa()IPv4のネットワークアドレスを、ドット区切りの10進