こんにちは。
C言語を勉強しているのですが、どうしても分からないことがあるので質問しました。
まず下記のソースを見てください。
#include <stdio.h>
int main()
{
char* moji;
moji = "right Test \n";
printf(" moji = %s\n", moji);
moji = "dot 255 left up down \n";
printf(" moji = %s\n", moji);
getchar();
return 0;
}
char* mojiがメモリを取らずに代入できているのですがこういった事が可能なのは何故でしょうか?
その後もmojiの変数を別の文字列定数で書き換えています。
こういったことはできなかったはずなんですがどうしてでしょうか?
自分の開発環境だとVS.2005 VC++です。
よろしくおねがいします。
No.2ベストアンサー
- 回答日時:
>char* moji;
mojiはchar*型の変数です。
>moji = "right Test \n";
メモリ上のどこかに配置されている「文字列定数」のアドレスを代入しています。
# コンパイラとリンカがよろしく確保しています。
>moji = "dot 255 left up down \n";
同じく、メモリ上の別の場所に配置されている「文字列定数」のアドレスを代入しています。
別に不思議なことではありません。
アドレスを格納するだけの変数の領域は
>char* moji;
で確保されているのですから。
ただし…moji経由で内容を書き換えようとすると、不正終了する可能性があります。
moji = "right Test \n";
*(moji+1) = 'I';
とか、
moji = "right Test \n";
strcat(moji, "dot 255 left up down \n");
とか。
不正終了しない場合は……
moji = "right Test \n";
*(moji+1) = 'I';
moji = "right Test \n";
で、2回目の代入した際に書き換わっている可能性があります。
なるほど
# コンパイラとリンカが文字列定数のアドレスを用意しているため
それを代入しているんですね。
昔のコンパイラならエラーだったはずなのですが。
No.6
- 回答日時:
「ポインタそのもの」と「ポインタが指している内容」とは明確に区別してください. その上で, 「こういったこと」が「どういったこと」であるのか説明できますか?
以下余談:
たしかに「文字列リテラルを char* で扱う」のはあまりいいことではないけど, これがきちんと動くことは環境によらない>#3 し, まして「明らかな間違い」と言い切っちゃうのはいかがなものかと>#1.
ついでに C では「(配列の初期化で用いられていない) 文字列リテラル」の個々の文字は (const char ではなく) 「ただの char」 (ただし変更不可) だったりします>#5. C++ だと const char (でも文字列リテラル全体は char* 変換可能) と, これはこれでややっこしかったりしますが.
char* を使って文字列リテラルを扱うことが環境によらないこと
なんですね。たとえばVC++6.0でもこうなると。
自分の感想なんですが、char* だけで文字列リテラルを扱う場
合、前の質問者さんが指摘した部分で変数に代入する場合は
注意が必要だということですね。
それに気を付けていれば扱いやすいかもしれないと思いました。
今までは、 malloc, newして代入してたんで、このやり方を知ら
なかったです。
No.5
- 回答日時:
C言語の変数には{名前、アドレス、属性、値}というものが付随しています。
例えば、 int abc = 123 ; という変数では abc という名前と int という属性と 123 という値を持ちます。
アドレスは、静的変数の場合はコンパイラが決定しますが、動的変数では実行時に決定されます。
名前、アドレス、属性は変更できませんが、値は変更できます。
(属性については一時的な変更は可能)
名前はコンパイラだけが使用し、プログラムから操作する事は出来ません。
char* moji; の場合、moji という名前で、char へのポインタという属性を持ちます。
この場合の moji は動的変数なので関数が呼び出された時にアドレスが決まります。
その値は関数が呼び出された時点では不定です。
char へのポインタという属性は、その変数の値が char という属性を持つ別の変数のアドレスを示すという事を意味します。
(この、ポインタ変数というのが分かりにくい原因ですね)
moji = "right Test \n"; の場合、"right Test \n"という文字列をコンパイラが用意します。
この文字列の名前とアドレスはコンパイラが自動的に決めます。
値は"right Test \n"という文字列で、属性は const char です。
moji = "right Test \n"; を実行すると moji の値を"right Test \n"という文字(列)のアドレスに置き換えます。
moji の値は正しく"right Test \n"という文字列を示しているので printf() で出力する事が出来ます。
moji = "dot 255 left up down \n";では、
moji の値が"dot 255 left up down \n"; のアドレスに置き換えられるます。
moji の値は正しく"dot 255 left up down \n"を示しているので printf() で出力する事が出来ます。
"right Test \n" という文字列は const char という属性を持ちます。
const という属性は書き換え不能、または書き換え禁止という意味を持ちます。
無理に書き換えた時の動作は環境に依存します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) VBA GetAttrについて教えてください 2 2022/12/22 15:25
- Visual Basic(VBA) VBA シート上にドロップダウンリストを作り、予め指定値をセットしたいのですが 1 2023/03/25 15:15
- Java Javaの問題なのですが、「3文字以上の英数字文字列を入力し、文字列の中に文字(9)が出てくるまでの 1 2023/06/06 18:55
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# Cのdoubleの浮動小数点表示について 3 2023/04/17 13:14
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ポインタを使って回文かどうか...
-
char*を初期化したいのですが
-
小数点入りの文字列をfloat型に...
-
C言語のintとcharの違いってな...
-
CStringからchar*への型変換に...
-
ポインタ配列
-
[C] 構造体メンバーのカンマ区...
-
char 文字列型 の表現範囲が-12...
-
C言語にて構造体のメンバがNULL...
-
c言語でポインタ変数を用いた配...
-
Run-Timeエラーの原因に関して...
-
strcat関数を自作したいです
-
C言語:小文字を大文字に変換す...
-
csvファイルをfscanfで読み込む...
-
ASCIIコードへの変換方法
-
wsprintf( ポインタ , "%d" , "...
-
const char* s1とただのchar s1...
-
strcat関数
-
char AA[]{"全角文字"};から"全...
-
C++Builder 2009 テキスト...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語のintとcharの違いってな...
-
char*を初期化したいのですが
-
C言語にて構造体のメンバがNULL...
-
CStringからchar*への型変換に...
-
strcat関数を自作したいです
-
new charとnew char[N]の違いは?
-
csvファイルをfscanfで読み込む...
-
char型にint型の数値を代入する。
-
動的メモリの初期化方法について。
-
C言語で文字列をかえす正しい書...
-
文字列str内の全ての数字を...
-
char 文字列型 の表現範囲が-12...
-
DWORDとcharの変換
-
fstream型オブジェクトを関数の...
-
小数点入りの文字列をfloat型に...
-
C言語のプログラムについてです
-
const char* s1とただのchar s1...
-
文字列内の数字削除
-
c言語でポインタ変数を用いた配...
-
szとlpszの違い
おすすめ情報