前提・実現したいこと
char配列に直接= " ";で代入出来ない理由は何ででしょうか。
例)
char aaa[16];
aaa = "あいうえお";
// 変更不可能な左辺値
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
aaa = "あいうえお";
aaaというのは配列ですんでアドレスの代入はできません。
ってはなしだけど、言語仕様がそうなってるから、ということだと納得しときましょう
C言語で、
char aaa[16]="あいうえお";
がなんで行けるんだ!という方が説明しやすいです。
実はこれは代入という動作はしていません。コンパイル時に解釈を行い、aaaの領域に、文字データを割り当てている、ってことなんですね
つまりー、”あいうえお”のデータを持った領域を定義している、ということで、実行時にはコピー動作は行われてません。
#まあそりゃ実行時にコピー動作を行う処理系もないとは言えませんが
投稿2019/08/10 14:43
編集2019/08/10 14:52総合スコア87719
0
C言語の文法で、aaaは配列先頭へのポインタと決まっています。
char aaa[16]; と宣言されたとき、sizeof(aaa)は、
ポインタのサイズである 4 や 8 ではなく、16 です。
"あいうえお" という文字列リテラルに対して、sizeof("あいうえお") は、
文字コードが Shift-JIS だと 11、UTF-8 だと 16 となります。
4 または 8 ではないので、"あいうえお" がアドレスだと主張できません。
ISO/IEC 9899:1999(E)
6.3.2.1 Lvalues, arrays, and function designators
- An lvalue is an expression with an object type or an incomplete type other
than void; if an lvalue does not designate an object when it is evaluated,
the behavior is undefined. When an object is said to have a particular type,
the type is specified by the lvalue used to designate the object. A modifiable
lvalue is an lvalue that does not have array type, does not have an incomplete
type, does not have a const-qualified type, and if it is a structure or union,
does not have any member (including, recursively, any member or element of all
contained aggregates or unions) with a const-qualified type.
- Except when it is the operand of the sizeof operator, the unary & operator,
the ++ operator, the -- operator, or the left operand of the . operator or an
assignment operator, an lvalue that does not have array type is converted to
the value stored in the designated object (and is no longer an lvalue). If the
lvalue has qualified type, the value has the unqualified version of the type
of the lvalue; otherwise, the value has the type of the lvalue. If the lvalue
has an incomplete type and does not have array type, the behavior is undefined.
- Except when it is the operand of the sizeof operator or the unary & operator,
or is a string literal used to initialize an array, an expression that has
type "array of type" is converted to an expression with type "pointer to type"
that points to the initial element of the array object and is not an lvalue.
If the array object has register storage class, the behavior is undefined
JIS X3010:2003(ISO/IEC 9899:1999)
6.3.2.1 左辺値,配列及び関数指示子
- 左辺値(lvalue)は,オブジェクト型,又は void 以外の不完全型をもつ式とする。
左辺値が評価されたときにオブジェクトを指し示していなければ,動作は未定義とする。
オブジェクトがもつ型に言及する場合,その型とは,オブジェクトを指し示すために
用いる左辺値によって指定される型とする。変更可能な左辺値(modifiable lvalue)
とは,配列型をもたず,不完全型をもたず, const 修飾型をもたない左辺値とし,
それが構造体又は共用体の場合,const 修飾型のメンバ(再帰的に包含されている
すべての集成体又は共用体の任意のメンバ又は要素を含めて)をもたないものとする。
- 左辺値が sizeof演算子,単項&演算子,++演算子若しくは--演算子のオペランド,
又は,.演算子若しくは代入演算子の左側のオペランドである場合を除いて,配列型以
外の左辺値は,指し示されたオブジェクトが格納する値に変換する(そして,それは
もはや左辺値ではない。)。左辺値が修飾型をもつ場合,その値は左辺値の型の非修
飾版をもつ。そうでない場合,その値は左辺値の型をもつ。左辺値が不完全型をもち,
配列型以外の型をもつ場合,その動作は未定義とする。
- 左辺値が sizeof 演算子のオペランド,単項&演算子のオペランド,又は文字配列を
初期化するのに使われる文字列リテラルである場合を除いて,型“~型の配列”をもつ
式は,型“~型へのポインタ”の式に型変換する。それは配列オブジェクトの先頭の
要素を指し,左辺値ではない。配列オブジェクトがレジスタ記憶域クラスをもつ場合,
その動作は未定義とする。
char aaa[16]; と宣言された aaa は配列型であり、オブジェクト型です。
したがって、式の中では左辺値として扱われます。
しかし、配列型をもつので、「変更可能な左辺値」ではありません。
これが、aaa = "あいうえお"; がエラーになる理由です。
投稿2019/08/11 00:00
総合スコア8224
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
aaa = "あいうえお";
// 変更不可能な左辺値
コメントの通りです.aaa
は、配列の名称。 Cの仕様に詳しい人からは、正確な説明があるかもしれませんが、char aaa[16]
で宣言された 16byte領域の先頭アドレス(固定値)を示します。従って変更する事はできません。
まあ、似たもので char *bbb
の bbbはポインタ(アドレスを入れる変数)なので、中身(アドレス)の変更は可能。そして、bbb[2]
とかの表現も可能なので、紛らわしいですが。
投稿2019/08/10 14:46
総合スコア6383
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
こんにちは。
C言語の文法で、aaaは配列先頭へのポインタと決まっています。
しかも、この場合そのポイント先を変更すると元々の16要素の配列と違う領域を指すことになるので混乱しやすいと思います。だからと思いますが、この場合のaaaのポイント先は変更できないと決まっているようです。
したがって、変更しようとすると「変更不可能」というエラーになります。
投稿2019/08/10 14:48
総合スコア23272
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。