【C言語】第4章第7回:ダブルポインタとその応用
ダブルポインタは、ポインタを指すポインタのことです。この章では、ダブルポインタの基本から応用までを、具体例を交えながら解説します。
1. ダブルポインタとは?
ダブルポインタは、ポインタへのアドレスを格納するポインタです。次のように宣言します:
data_type **pointer_name;
1.1 メモリ階層をイメージする
ダブルポインタを使うと、次のようなメモリ階層を操作できます:
- 最上位:ダブルポインタ(ポインタのアドレス)
- 中間:シングルポインタ(変数のアドレス)
- 最下位:変数そのもの(値)
例:ダブルポインタの基本構造
#include <stdio.h>
int main() {
int number = 42;
int *ptr = &number; // ポインタptrはnumberを指す
int **dptr = &ptr; // ダブルポインタdptrはptrを指す
printf("Value of number: %d\n", number);
printf("Address of number: %p\n", (void*)&number);
printf("Value of ptr: %p\n", (void*)ptr);
printf("Value at *ptr: %d\n", *ptr);
printf("Value of dptr: %p\n", (void*)dptr);
printf("Value at *dptr: %p\n", (void*)*dptr);
printf("Value at **dptr: %d\n", **dptr);
return 0;
}
解説:
int **dptr = &ptr;
: ダブルポインタdptr
は、ポインタptr
を指します。**dptr
: ダブルポインタが最終的に指す値(number
の値)。
2. ダブルポインタを使う利点
ダブルポインタを使用することで、以下のような操作が可能になります:
- 関数内でポインタを操作・変更する。
- 動的メモリの管理を効率化する。
- 多次元配列を操作する。
2.1 ポインタを関数で変更する
例:関数内でポインタの参照先を変更
#include <stdio.h>
void updatePointer(int **dptr) {
static int newNumber = 99;
*dptr = &newNumber; // ポインタの参照先を変更
}
int main() {
int number = 42;
int *ptr = &number;
printf("Before update: %d\n", *ptr);
updatePointer(&ptr);
printf("After update: %d\n", *ptr);
return 0;
}
解説:
int **dptr
: ダブルポインタを使用して、関数内でポインタの参照先を変更します。- 新しい変数
newNumber
のアドレスをptr
に割り当てることで、呼び出し元での値が変化します。
3. ダブルポインタと動的メモリ管理
ダブルポインタを使うと、動的にメモリを割り当てるポインタを関数内で操作できます。
例:動的メモリの割り当てと解放
#include <stdio.h>
#include <stdlib.h>
void allocateArray(int **arr, int size) {
*arr = (int *)malloc(size * sizeof(int));
for (int i = 0; i < size; i++) {
(*arr)[i] = i + 1;
}
}
int main() {
int *array = NULL;
int size = 5;
allocateArray(&array, size);
printf("Array: ");
for (int i = 0; i < size; i++) {
printf("%d ", array[i]);
}
printf("\n");
free(array);
return 0;
}
解説:
- ダブルポインタ
int **arr
を使用して、関数内で動的メモリを割り当てます。 - 配列の内容を初期化し、呼び出し元で利用可能にします。
4. 練習問題
以下の課題に挑戦して、ダブルポインタのスキルを磨きましょう。
- ダブルポインタを使って2次元配列を動的に割り当て、すべての要素を初期化するプログラムを作成してください。
- 関数内でポインタの参照先を変更し、変更内容を呼び出し元に反映するプログラムを作成してください。
- ダブルポインタを使って文字列を操作し、すべての文字を大文字に変換するプログラムを作成してください。
5. 練習問題の解答と解説
問1の解答
#include <stdio.h>
#include <stdlib.h>
void allocate2DArray(int ***arr, int rows, int cols) {
*arr = (int **)malloc(rows * sizeof(int *));
for (int i = 0; i < rows; i++) {
(*arr)[i] = (int *)malloc(cols * sizeof(int));
for (int j = 0; j < cols; j++) {
(*arr)[i][j] = i * cols + j;
}
}
}
int main() {
int **matrix = NULL;
int rows = 3, cols = 4;
allocate2DArray(&matrix, rows, cols);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
for (int i = 0; i < rows; i++) {
free(matrix[i]);
}
free(matrix);
return 0;
}
6. まとめ
ダブルポインタは、関数内でのポインタ操作、多次元配列の操作、動的メモリ管理などに広く活用されます。次のステップとして、実際のプログラムに応用してみましょう。