ここから本文です

c言語初心者です。配列の要素のアドレスを代入することはできますか?例えばchar s...

アバター

ID非公開さん

2020/6/2916:12:55

c言語初心者です。配列の要素のアドレスを代入することはできますか?例えばchar s[10]=“abcdef”などでchar *p=sはできますよね。char *p=s[3]で代入できますか?

また配列同士の代入ができない理由も教えてください
char a[10]=“abcde”; char b[10]; b=a;などです。(アドレスをコピーしてるだけのになぜできないのか)

閲覧数:
54
回答数:
5

違反報告

回答

1〜5件/5件中

並び替え:回答日時の
新しい順
|古い順

プロフィール画像

カテゴリマスター

n2q37_cppさん

2020/6/3000:02:17

皆さまお答えの通り &s[3] で s[3] のアドレスということになります。



char *p = s;
char *q = &s[0];
char *r = &s[3];

p には &s[0] が入ります。p と q は結局同じなんですね。つまり s とは、&s[0] のことです。&s[0] を s と略記できる。という風にお考えになると良いと思います。


【配列同士の代入ができない理由】

配列の全要素を代入するとなると負荷が発生します。負荷がかかる作業を代入で出来てしまっては困るだろう…という親心でしょう。

char 型の要素10個だけの場合、負荷と言っても僅かです。では100個?それとも1000個?どのくらいの要素数になったら代入禁止にすれば良いでしょうか…

決めかねますよね。そういうわけでたとえ1個でも、配列ということならば代入は禁止。そのように仕様で定めたということでしょう。



【アドレスをコピーしてるだけのになぜできないのか】

いや、そうではないのですよ。

nyosさん

編集あり2020/6/3015:08:33

ちょっとわかりにくいかもしれませんが、c言語やそれに似た言語、例えばc++やJava、C#等では型として存在するもののみが代入演算子で代入する事ができます。

そしてC言語には配列と言う”型”が存在しません。

でもint array[100];とかで宣言してるよ!、とか思うかもしれませんが、これは「int型の領域をスタックメモリ上に100連続して確保する」と言う宣言で、実際は確保されたスタックメモリ上へのポインタarrayが、「あたかも配列のように振る舞う表現」として表記出来る様になっているだけなのです。
その証拠にmalloc等でヒープメモリに確保した領域も「あたかも配列のように振る舞う」書き方が出来ますよね。
また、自分で宣言した構造体や共用体も型なので、代入できます。
ちなみに構造体内に配列がある場合でも構造体は代入演算子で内部の配列内容ごとコピーできます。
これは構造体の型が定義時に一つの構造体サイズが決定しており、どれだけのメモリ領域をコピーすれば良いか構造体の型として判別できるからです。これは構造体がインスタンス化したときメンバ変数がメモリ上で連続している事にも関わりがあります。
あと、C++でもclassも型なので代入可能ですし、こちらはoperator により演算子のカスタマイズまで可能です。

c言語では、確保されたメモリ領域について、十分考慮する必要が有るのはおわかりだと思いますが、関数内で宣言したスタックメモリ上の領域は解放の必要はありませんが十分注意する必要は有ります。

一定のメモリ領域範囲のコピーを行うには、標準関数のmemcpy 、strcpyなどを使うか、その型の境界領域毎にfor分等で繰り返して任意の対象領域全域を走査して一個づつ代入していくしか無いです。

※わからない用語的なところは自分で調べてみてくださいね

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

jjd********さん

2020/6/2916:41:15

>char *p=s[3]で代入できますか?

できますが、書き方がまずいです。&s[3] としてください。s[3]は中身を指すのでそのアドレスは&を付ける必要があります。



>また配列同士の代入ができない理由も教えてください
>char a[10]=“abcde”; char b[10]; b=a;などです。(アドレスをコピーしてるだけのになぜできないのか)

char b[10];
と配列を宣言した時点でbのアドレスが確定されてしまうので、その後b=aなどはできないと思われます。

プロフィール画像

カテゴリマスター

nan********さん

2020/6/2916:40:39

char *p = &a[3];

とします。
配列そのものには代入できません。アドレスのコピーではないからです。

配列ではない変数でたとえれば分かりやすいでしょう。

int i;
int j;

&i = &j;

変数i自体のアドレスは固定されたものなので、代入不可です。

char a[10];
char *b;
b = a;

なら可能。

プロフィール画像

カテゴリマスター

あみやさん

2020/6/2916:38:00

配列名は単体で書くとアドレスになるという仕様がありますが、
個別の要素はその値となりますので、アドレスにはなりません。

アドレスを得たい場合は普通の変数と同じように、&演算子を使ってアドレスに変換します。

char *p=&s[3]

また、配列名を単独で書くとアドレスを表すというだけであり、
配列名自体がポインタ変数になるわけではありません。
ですので、配列名にアドレスは代入できません。

この質問につけられたタグ

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる