char* str[10]={"a","b"};
char* str2="c";
としたときにstr=str2とすると
型が合わないといったエラーが出ます。
でもstrって結局はポインタの配列の先頭要素のアドレスですよね。
ポインタにポインタを入れているので通るのかなと思ったんですけど、
配列で宣言するとポインタにも型がつくのでしょうか?
この例だと strは char * を10個持つ配列をさすポインタ
で、
str2はchar *をさすポインタ
みたいなかんじです。
質問の意味がわかりにくいですが、ご指摘をいただければ補足しますので
よろしくお願いします。
No.9ベストアンサー
- 回答日時:
#8 さんへ
>strは左辺値ですが、配列型ですので代入できません。
代入できないのは「左辺値ではない」からです。
宣言のときの
char* str[10]={"a","b"};
str は、配列型ですが、式として参照されるとき、str はもはや配列型ではありません。
str は要素型へのポインタ、すなわち、 char のポインタへのポインタ(アドレス)です。
式として記述された str が配列型を持つのは、
・&演算子のオペランド
・sizeof演算子のオペランド
のときだけです。
int a[10];b=1;
a = &b;
a の型は int へのポインタ型であって配列型ではありません。代入できないのは、a が「左辺値ではない」からです。早い話、b のアドレスを格納するメモリがない(左辺値ではない)からです。
>str2=str;であれば、エラーになりません。
そうだったかもしれません。
何か、回答者の答えが、質問者をよけい混乱させているかもしれません(私も含め)。
何度も回答していただきありがとうございます。
他の回答者のミスを指摘してもらいどっちが正しいのか考えるとより理解が深まりました。
ポインタと先頭アドレスがごっちゃになってたみたいです。
&でっていうのがとてもわかりやすかったです。
本当にありがとうございました!
No.10
- 回答日時:
現在の C の規格に従えば配列は左辺値です. ただし左辺値にも「変更できる左
辺値」と「変更できない左辺値」の 2種類があり, 配列は後者の「変更できない
左辺値」であるとなっています.
また, 式中に表れた配列名が表すのはあくまで「配列」です.
・アドレスをとる単項演算子の &
・sizeof
のオペランドになっていないときには, 自動的に「当該配列の先頭をさすポイン
タ」に変換される, というだけです.
関数名も同様で, 単項 & と sizeof のオペランドになっていないときには自動
的に「当該関数の先頭アドレス」に変換されます.
あくまで「現在の C の規格にてらして正しい解釈」はこうなっている, という
だけですが.
No.8
- 回答日時:
strの型はchar*[10]、str2の型はchar*です。
strは左辺値ですが、配列型ですので代入できません。
これは、
int a[10];
a = 123;
とできないのと同じです。
str2=str;であれば、エラーになりません。
Cでは、オブジェクト型へのポインタどうしは暗黙的に型変換されます。
strは配列型ですが、代入演算子の右オペランドに指定した場合には先頭要素へのポインタ型に暗黙的に変換されます。
すなわち、strの型は、
char*[10] → char** → char*
の順に暗黙的に型変換されます。
ただし、C++ではエラーになります。
この辺の区別がついていない人が多いので要注意です。
回答ありがとうございます。
確認したところ確かにC++ではエラーになり、
Cでは警告が出るだけでコンパイルできました。
Cで出来てC++で出来ないこともあるんですね。
暗黙的に変換されるというのはまったく知りませんでした・・。
というより今までちゃんと理解できてなかったみたいです。
ありがとうございました。
No.7
- 回答日時:
#6 さんへ
>str = "ABC"; ○
本当?str は左辺値(l-value)ではないので代入できないと思うのだが?
*str = "ABC"; ○ ならばわかります。
>str これは配列の先頭アドレスです。
実際には同じアドレスですが、意味は微妙に違います
str => 配列の0番目の要素のアドレスです。
&str => 配列の先頭アドレスです。
>str=str2;とはまさに定数に変数を代入しようとする行為です。
そもそも、str には代入不可。というのが私の見解です。
No.6
- 回答日時:
変数に定数は代入できます。
str = "ABC"; ○
右辺は文字列へのアドレスで、リンク時に
確定する数値です。
定数に変数や他の定数を代入できません。
123 = str; ×
こんなことは理由の説明いらないですよね。
char *str[10];
これはポインタが10個あるということです。
>strは char * を10個持つ配列をさすポインタ
違います。str これは配列の先頭アドレスです。
つまり、定数です。str=str2;とはまさに定数に
変数を代入しようとする行為です。できなくて
当然ですよね。
char2がどんな型の変数であろうと定数であろうと
コンパイラがどんなに進化しようと代入できません。
>str2はchar *をさすポインタ
これをするなら以下のような定義です。
char **str2; または char *str2[];
そこで str2 = str; これならOKです。
とてもわかりやすく説明していただきありがとうございます。
ポインタと先頭アドレスがごっちゃになってたみたいですね・・。
すっきりしました。
本当にありがとうございました。
No.4
- 回答日時:
CコンパイラーがPCにインストールされていないので確かめられませんが、
str2 = str;
もエラーとなるのでは?
str2=(char *)str;
とするとコンパイルエラーは消えそうが、意図しないことが起こりそうです。
意味のある代入としては、
str2 = str[0];
str2 = str[9];
str2 = *str;
str2 = *(str+9);
など。
No.1
- 回答日時:
str : char へのポインタのポインタ
str[0] : charへのポインタ
str2 : charへのポインタ
str[0] = str2;
ならエラーは出ない。
それに、str は、左辺値(l-value)ではないので、代入不可。
遠い記憶なので違っていたらすいません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# c言語 コマンドライン引数 4 2023/02/09 18:47
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# C言語 少しの疑問 4 2022/11/08 02:48
- C言語・C++・C# str[j++]の意味 2 2022/08/30 16:20
- C言語・C++・C# C言語初心者 ポインタについて、お助けください、、 2 2023/03/15 23:50
- C言語・C++・C# ポインタの型変換、どうやるんでしたっけ? 2 2022/03/28 11:00
- C言語・C++・C# C言語 配列とポインタについて 2 2022/06/02 11:53
- C言語・C++・C# c言語 配列とポインタについて 3 2023/02/09 22:53
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
セグメントエラー
-
C言語のポインタに直接アドレス...
-
Run-Time Check Failure #3とい...
-
init関数の意味
-
連結リスト 要素の入れ替え
-
戻り値で構造体を返すことは可...
-
ハンドルはポインタか
-
メモリのアドレスからの値の取...
-
ExcelVBAでのkernel32(64bit)
-
C言語でのconstを返す関数
-
fopne で失敗する原因
-
トリプルポインタが必須!とな...
-
アプリを32bitから64bit移行
-
基本アルゴリズムの『返す』の...
-
SystemC言語の文法(関数の引数...
-
NULLとブランクの違い
-
CopyMemory()をmemcpy()に書き...
-
AESのC言語による実装
-
C言語の関数と配列に関する質問
-
構造体とfscanf
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
セグメントエラー
-
C言語のポインタに直接アドレス...
-
init関数の意味
-
戻り値で構造体を返すことは可...
-
fopne で失敗する原因
-
C言語の関数と配列に関する質問
-
Run-Time Check Failure #3とい...
-
LPSTR型の初期化について
-
ExcelVBAでのkernel32(64bit)
-
main(int argc,char **argv[])...
-
アプリを32bitから64bit移行
-
連結リスト 要素の入れ替え
-
ハンドルはポインタか
-
Cで作成したDLL関数をVBから呼...
-
C言語でのconstを返す関数
-
NULLとブランクの違い
-
エラーの意味
-
DLL<->VB間での受け渡し(文字...
-
ハンドル、アドレス、ポインタ...
-
【C言語】戻り値が構造体の関数
おすすめ情報