C言語: キャスト、ポインター配列、`std::array` を使った `char**` から `const char *` への変換
C言語で const char ポインターの配列を期待する関数に char** を渡す方法
キャストを使用する
最も単純な方法は、char**
をconst char *
の配列にキャストすることです。
void func(const char *str_arr[]) {
// ...
}
int main() {
char *str[] = { "Hello", "World" };
func((const char **)str); // キャストを使用
return 0;
}
この方法は簡単ですが、いくつかの注意点があります。
- キャストは、型の安全性に関する警告を引き起こす可能性があります。
- キャストは、
str
がconst
ではない場合、誤った動作を引き起こす可能性があります。
ポインターの配列を作成する
char**
をconst char *
の配列に変換する別の方法は、ポインターの配列を作成することです。
void func(const char *str_arr[]) {
// ...
}
int main() {
char *str[] = { "Hello", "World" };
const char *str_const_arr[2];
for (int i = 0; i < 2; i++) {
str_const_arr[i] = str[i];
}
func(str_const_arr);
return 0;
}
この方法は、キャストを使用するよりも安全ですが、コードが冗長になる可能性があります。
std::arrayを使用する
C++11以降を使用している場合は、std::array
を使用して、const char *
の配列を簡単に作成できます。
void func(const char *str_arr[]) {
// ...
}
int main() {
std::array<const char *, 2> str_arr = { "Hello", "World" };
func(str_arr.data());
return 0;
}
この方法は、最も簡潔で安全な方法ですが、C++11以降のコンパイラが必要となります。
#include <stdio.h>
void func(const char *str_arr[]) {
for (int i = 0; str_arr[i] != NULL; i++) {
printf("%s\n", str_arr[i]);
}
}
int main() {
// char** を const char * の配列にキャストする
char *str[] = { "Hello", "World" };
func((const char **)str);
// ポインターの配列を作成する
const char *str_const_arr[2] = { "Hello", "World" };
func(str_const_arr);
// std::array を使用する
#ifdef __cplusplus
std::array<const char *, 2> str_arr = { "Hello", "World" };
func(str_arr.data());
#endif
return 0;
}
このコードは、func
という関数を定義します。この関数は、const char *
の配列を受け取り、その要素をすべて出力します。
main
関数では、3つの方法でchar**
をconst char *
の配列に渡します。
どの方法を使用しても、func
関数は正しく動作します。
実行結果
このコードを実行すると、以下の出力が得られます。
Hello
World
Hello
World
Hello
World
C言語で char**
を const char *
の配列を期待する関数に渡す他の方法
ポインターを直接渡す
C言語では、配列の名前は、その配列の最初の要素へのポインターと同じです。そのため、char**
変数を直接関数に渡すこともできます。
void func(const char *str_arr[]) {
// ...
}
int main() {
char *str[] = { "Hello", "World" };
func(str); // ポインターを直接渡す
return 0;
}
この方法は、上記のどの方法よりも簡潔ですが、関数側で配列の長さを取得できないという欠点があります。
マクロを使用する
マクロを使用して、char**
変数を const char *
の配列に変換することもできます。
#define STR_ARR(arr) (const char **)arr
void func(const char *str_arr[]) {
// ...
}
int main() {
char *str[] = { "Hello", "World" };
func(STR_ARR(str)); // マクロを使用
return 0;
}
この方法は、コードをより簡潔にすることができますが、マクロの使いすぎはコードの可読性を低下させる可能性があります。
構造体を使用する
typedef struct {
const char **str_arr;
size_t len;
} StrArr;
void func(const StrArr *str_arr) {
// ...
}
int main() {
char *str[] = { "Hello", "World" };
StrArr str_arr = { str, 2 };
func(&str_arr); // 構造体を使用
return 0;
}
arrays c pointers