[解決済み] char * (char配列)の実長と全長を求めるには?
質問
の場合
char []
でその長さを簡単に求めることができる。
char a[] = "aaaaa";
int length = sizeof(a)/sizeof(char); // length=6
しかし、このようなことはできません。
char *
によるものです。
char *a = new char[10];
int length = sizeof(a)/sizeof(char);
というのも、そうなんです。
a
はポインターで、次のようなものです。
length
は常に
4
(システムによって異なる)。
質問なんですが、どうやったら
char *
を後から追加することはできますか?
という疑問を持たれるかもしれませんが、そのようなことはありません。
10
作ったばかりだからです。なぜなら、この長さを求めるステップは、作成してからずいぶん時間が経ってからになるかもしれないし、この数字を確認するために、ずいぶん前に戻ってきたくはないからです。さらに、本当の長さも知りたい。
より具体的に言うと
-
どうすればその実体を知ることができるのか
length=5
? -
その合計を取得する方法
length=10
?
を以下の例で説明します。
char *a = new char[10];
strcpy(a, "hello");
解決方法は?
無理です。とにかく100%の精度は無理です。ポインターは
は長さ/大きさを持たず、それ自身の
. それがすることは、charを保持するメモリ上の特定の場所を指すだけです。もしその文字が文字列の一部であるなら、その文字列を保持するために
strlen
を使えば、現在指されている文字に続く文字が何であるかを判断することができますが、だからといって
配列
の場合、それほど大きなサイズになります。
基本的には
A
ポインタ
は
配列
というように
必要
は、配列のサイズを知っている必要があります。ポインタは1つの値を指すので、配列がなくてもポインタは存在できます。ポインタが指すメモリがどこにあるのかも気にしない(読み込み専用、ヒープ、スタック...関係ない)。ポインターは自分以外の長さを持たない。ポインターはただ...
これを考えてみましょう。
char beep = '\a';
void alert_user(const char *msg, char *signal); //for some reason
alert_user("Hear my super-awsome noise!", &beep); //passing pointer to single char!
void alert_user(const char *msg, char *signal)
{
printf("%s%c\n", msg, *signal);
}
ポインターは1文字でも、配列の先頭、末尾、中間でも構いません。
文字列は構造体だと考えてください。ヒープ上に1つの構造体を割り当てることがあります。これも、配列のないポインタを作成します。
ポインタだけでは、それが指している配列の大きさを判断することは不可能です。最も近いのは
calloc
で、そのポインタから連続する"㊧"の数を数えるんです。もちろん、その配列のキーに何かを代入・再代入してしまうとうまくいきませんし、メモリが単に
外
を保持している場合、その配列の
\0
もあります。ですから、この方法を使うことは信頼性が低く、危険で、一般的に愚かなことなのです。やめてください。しないでください。しないでください。
もう一つの例え話。
ポインターは道路標識のようなもので、次の場所を指していると考えてください。
タウンX
. 看板はその町がどんなところか知らないし、そこに誰が住んでいるかも知らないし、気にしない(気にしうる)。この看板の仕事は、あなたに次の場所を教えることです。
タウンX
. その町がどのくらい遠いかはわかるが、どのくらい大きいかはわからない。その情報は道路標識には無関係と判断されます。それは町そのものを見ればわかることで、その方向を示す道路標識ではわからないのです
だから、ポインターを使うと......できるのは
char a_str[] = "hello";//{h,e,l,l,o,\0}
char *arr_ptr = &a_str[0];
printf("Get length of string -> %d\n", strlen(arr_ptr));
しかし、これはもちろん、配列/文字列が \0- 末端である場合にのみ機能します。
余談ですが
int length = sizeof(a)/sizeof(char);//sizeof char is guaranteed 1, so sizeof(a) is enough
は実際には
size_t
(の戻り値型)。
sizeof
から
int
と書くのがベストです。
size_t length = sizeof(a)/sizeof(*a);//best use ptr's type -> good habit
以降
size_t
は符号なし型であり、もし
sizeof
はより大きな値を返します。
length
は、予想外のことが起こるかもしれない...。
関連
-
[解決済み】C-stringを使用すると警告が表示される。"ローカル変数に関連するスタックメモリのアドレスが返される"
-
[解決済み】エラー。switchステートメントでcaseラベルにジャンプする
-
[解決済み】C++の余分な資格エラー
-
[解決済み] [Solved] インクルードファイルが開けません。'stdio.h' - Visual Studio Community 2017 - C++ Error
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] JavaScript で配列に値が含まれているかどうかを確認するにはどうすればよいですか?
-
[解決済み] 配列に特定のインデックスで項目を挿入する方法 (JavaScript)
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] Javaで配列を宣言し、初期化する方法は?
-
[解決済み】配列に何かを追加する方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】getline()が何らかの入力の後に使用されると動作しない 【重複あり
-
[解決済み】識別子 "string "は未定義?
-
[解決済み] error: 'ostream' does not name a type.
-
[解決済み】テンプレートの引数1が無効です(Code::Blocks Win Vista) - テンプレートは使いません。
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み] 式はクラス型を持つ必要があります。
-
[解決済み】オブジェクト引数のない非静的メンバ関数の呼び出し コンパイラーエラー
-
[解決済み] [Solved] インクルードファイルが開けません。'stdio.h' - Visual Studio Community 2017 - C++ Error
-
[解決済み】CMakeエラー at CMakeLists.txt:30 (project)。CMAKE_C_COMPILER が見つかりませんでした。
-
[解決済み】警告 - 符号付き整数式と符号なし整数式の比較