str[i] と*(str + i) および &str[i] と str + iと&*(str + i) は同じですか?
仮にiを+1していくとして、
iが+1されるとstr[i]のポインタのアドレス自体ではなく、
アドレスに入っているメモリの値が+1され、
iが+1されるとつぎのアドレスに移行すると聞いたのですが、それは上の5つのうちどれですか?
また、が+1されるとstr[i]のポインタのアドレス自体ではなく、
アドレスに入っているメモリの値が+1され、のは5つのうちどれですか?
str[i]はiが+1(4バイト)されるとstr[]がポインタのアドレス自体が上がり、次のアドレスに進む。
*(str + i)はiが+1されるとstrのアドレスが+1
上がり次のアドレスに進む
&str[i]は&がついているから上と同じ
str + iはが+1されたらstr自体がアドレス表すのでアドレス自体が次のアドレスに進む。
&(str + i) は左辺部の&より他と同じということでしょうか?
すなわちstr[i] と(str + i) および &str[i] と str + iと&*(str + i) は同じですか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/02/15 07:33
2021/02/15 07:39
2021/02/15 08:35
2021/02/15 22:18
回答6件
0
質問者より
言語はcです。今後はタグにcのみにします。strの型はcharです。
とのコメントを受けました。下記の回答は前提が間違っていますので、無視してください。
実際に同じか試してみました。
質問文に詳しいコードがなかったため、前提として、下記であると推測しました。
- 質問にはCとC++の二つの異なる言語のタグがついています。C++は(一部を除いた)Cの拡張であり、Cについて聞きたいのであれば、わざわざC++のタグを付けると言うことはない判断しました。よって、Cの話ではなくC++に限定した話である前提とします。
- 質問には
str
がどのような型であるかの情報がありません。strと言う名前からstring、つまり、文字列だと推測されます。C++で文字列を扱うのであればstd::string
がもっとも妥当とおもわれるため、std::string
であると判断しました。str
はstd::string
であることを前提とします。
質問での推測が正しいか確認するために、下記のコードを用意しました。
C++
1#include <iostream> 2#include <string> 3 4int main() 5{ 6 std::string str = "abcdef"; 7 std::size_t i = 1; 8 std::cout << str[i] << std::endl; 9 std::cout << &str[i] << std::endl; 10 return 0; 11}
C++
1#include <iostream> 2#include <string> 3 4int main() 5{ 6 std::string str = "abcdef"; 7 std::size_t i = 1; 8 std::cout << *(str + i) << std::endl; 9 std::cout << (str + i) << std::endl; 10 std::cout << &*(str + i) << std::endl; 11 return 0; 12}
それぞれの実行結果は下記にあるWandboxを確認してください。
見ればわかりますが、下のコードはコンパイルエラーになります。つまり、最初の前提で話を進めた場合、「同じであるという前にコンパイルエラーになる」が結論となります。
なお、前提が異なる、例えばCの話であったり、str
がchar
の配列であると言った場合は、また別の結論になります。もし、私の前提が間違っているのであれば、質問文に言語や型がわかるようコンパイル可能なコードを明記するようにしてください。そして、この回答は忘れて下さい。
投稿2021/02/15 12:48
編集2021/02/15 22:18総合スコア21737
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/02/15 15:33
2021/02/15 17:38
2021/02/15 18:21
2021/02/15 22:10
2021/02/15 22:14
2021/02/15 22:20
0
C
1#include <stdio.h> 2 3int main(void) 4{ 5 char str[8] = "abcdefg"; 6 int i = 3; 7 8 printf("str[i] = '%c'\n", str[i]); 9 printf("*(str + i) = '%c'\n", *(str + i)); 10 printf("&str[i] = %p\n", &str[i]); 11 printf("str + i = %p\n", str + i); 12 printf("&*(str + i) = %p\n", &*(str + i)); 13}
実行結果
text
1str[i] = 'd' 2*(str + i) = 'd' 3&str[i] = 00000045D00FFECB 4str + i = 00000045D00FFECB 5&*(str + i) = 00000045D00FFECB
質問する前に、このようなコードを書いて確かめようとしなかったのでしょうか?
str と i の型が知りたいという回答があったのに、なぜそれには対応しないのでしょうか?
str[i] と *(str + i) が等しくないこともあるという回答があった時、str の型を示せば
C でも C++ でも構わなかったのに、そうはせず、C++ のタグをはずしましたね。
char str[8] = "abcdefg";
という宣言があったら、
str は変数です。str は配列です。str は配列変数です。
str の型は、「char の配列」です。str の型は、「char [8]」です。
str の値は、{ 'a', 'b', 'c', 'd', 'e', 'f', 'g', '\0' } です。
配列の要素数は 8 です。
配列変数 str のサイズは sizeof(str) = 8 です。
str に入っている文字列 "abcdefg" の長さは strlen(str) = 7 です。
さらに int i = 3;
という宣言があったら
str[i] は、配列変数 str の i番目の要素です。str[i] は配列ではありません。
str[i] の型は char です。str[i] の型は、配列型ではありません。
str[i] の値は 'd' ですと言いたいところですが、ちょっと待ってください。
str[i] が 'd' なら、str[i] = 'x';
は 'd' = 'x';
となって
コンパイルエラーになるはずです。
str[i] の値は「左辺値」です。
左辺値というのは変数のようなものです。
代入演算子の右辺には、a = b + 7;
のように式が書けます。
式というのは演算子を使った式もありますが、
演算子を使わない定数や変数も式と言っていいのです。
式には評価結果の値があります。変数は値を持っています。定数は値です。
代入演算子の右辺には値が来ればよいのです。
ところが、代入演算子の左辺には値が来てはいけません。
5 = 9;
はエラーです。b + 7 = 9;
もエラーです。
左辺には定数も「演算子を使った式」も書けませんが、変数は書けます。
左辺に書けるものを示す式を「左辺値」と言います。
変数は左辺値です。
str[i] も左辺値です。
添字演算子 [] を使った式ですが、代入演算子の左辺に書けます。
左辺値は変数みたいなものであり、値を持っていて、その値を使うことができます。
だから、str[i] が代入演算子の右辺にあったり、関数の引数だったりする場合は
値を取り出すことができて、str[i] は 'd' となります。
ここまでの説明を全部理解できますか?
理解できない場合は、どこが分からないのかを書いてください。
理解できた場合は、次の *(str + i) の説明に進みます。
なぜ、str[i] を配列だと思ったんですか?
まだ str[i] は配列だと思っていますか?
投稿2021/02/20 12:53
編集2021/02/20 13:45総合スコア8224
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/02/20 16:15
2021/02/20 17:33 編集
2021/02/20 17:35
2021/02/21 00:32 編集
2021/02/21 00:37
2021/02/21 08:16
0
どうでもいい話ですが、
str[i] と*(str + i) は同じですか。に関して
str[i]と*(str + i)は同じです。さらにi[str]も同じです。
なぜならば、*(i + str)だからです。
嘘だと思う人もいますが、コンパイルしてみればわかります。
投稿2021/02/15 13:48
総合スコア24670
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/02/16 03:07 編集
2021/02/16 12:26
0
まずは型の情報が欲しいです。
多分charだとは思いますが。
投稿2021/02/15 06:54
総合スコア4830
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
str[i] と*(str + i) および &str[i] と str + iと&*(str + i) は同じですか?
はい。
また、が+1されるとstr[i]のポインタのアドレス自体ではなく、
アドレスに入っているメモリの値が+1され、のは5つのうちどれですか?
どれとも関係しません。いずれも、単体ではアクセスしたメモリを書き換える、という意味は持ちません。
投稿2021/02/15 06:49
編集2021/02/15 06:51総合スコア145965
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/02/15 11:27 編集
2021/02/15 11:27 編集
2021/02/15 11:28
2021/02/15 11:34
2021/02/15 11:40
2021/02/15 11:44
2021/02/15 11:45
2021/02/15 11:47
2021/02/15 11:48
2021/02/15 12:05 編集
2021/02/15 12:14 編集
2021/02/15 20:30
2021/02/15 22:46
2021/02/15 22:48 編集
2021/02/16 00:41 編集
2021/02/16 00:54
2021/02/16 03:05
2021/02/16 03:26
2021/02/16 04:50
2021/02/16 05:20
2021/02/16 06:04
2021/02/16 06:07
2021/02/16 06:09
2021/02/16 06:10
2021/02/16 06:18
2021/02/16 06:27
2021/02/16 07:28
2021/02/17 23:31
2021/02/18 00:06 編集
2021/02/18 00:20 編集
2021/02/18 00:54
2021/02/18 19:36
2021/02/18 19:50
2021/02/18 19:57
2021/02/18 20:04 編集
2021/02/18 20:19 編集
2021/02/18 20:28
2021/02/18 21:14 編集
2021/02/19 06:26
2021/02/19 11:48
2021/02/19 11:55
2021/02/20 04:17
2021/02/20 07:42
0
str[i] と*(str + i) および &str[i] と str + iと&*(str + i) は同じですか?
YES
それぞれを日本語で説明するとこんな感じ。
fanaさんの指摘を受け、修正
str[i] →str配列のi番目の要素の値
(str + i) →str配列の先頭アドレスにiを加算したアドレスの中身の値
&str[i] →str配列のi番地のアドレス
str + i →str配列の先頭アドレスにiを加算したアドレス
&(str + i) →str配列の先頭アドレスにiを加算したアドレスの中身の値のアドレス
サンプルも併せて記載
C
1#include <stdio.h> 2int main(void){ 3 // Your code here! 4 char str[5]={"abcde"}; 5 int i; 6 for(i = 0; i < 5; i++){ 7 printf("%c\n", str[i]); 8 printf("%c\n", *(str + i)); 9 printf("0p%x\n", &str[i]); 10 printf("0p%x\n", str + i); 11 printf("0p%x\n", &*(str + i)); 12 } 13} 14 15出力結果 16a 17a 180x7ffc155edf10 190x7ffc155edf10 200x7ffc155edf10 21b 22b 230x7ffc155edf11 240x7ffc155edf11 250x7ffc155edf11 26c 27c 280x7ffc155edf12 290x7ffc155edf12 300x7ffc155edf12 31d 32d 330x7ffc155edf13 340x7ffc155edf13 350x7ffc155edf13 36e 37e 380x7ffc155edf14 390x7ffc155edf14 400x7ffc155edf14
投稿2021/02/15 07:00
編集2021/02/15 07:57総合スコア418
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/02/15 07:17
2021/02/15 11:50
2021/02/15 11:57 編集
2021/02/15 12:00
2021/02/15 12:05
2021/02/15 21:27
2021/02/16 00:16
2021/02/16 00:35
2021/02/16 00:46
2021/02/16 01:06
2021/02/16 01:15
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。