c char配列とポインタ

#include
int main(){

char a[6],*p;

a[0]='a';
a[1]='b';
a[2]='c';
a[3]='4';
a[4]='e';
a[5]='p';
a[6]='f';
a[7]='e';
printf("%s\n",a);
printf("printing address of each array element");
p=a;

printf("%u\n",&p[0]);
printf("%u\n",p+1);
printf("%u\n",a+2);
return 0;
}

出力は次のとおりです...

[email protected]:~/Desktop/prep$ ./a.out
abc4epfe
printing address of each array element3216565606
3216565607
3216565608

配列を char a [6] として宣言すると、 a [7] に値を割り当てることができます。最後の要素にヌル文字を追加する必要はありませんか?

Also p=a => p holds the address of first element of char array a. I don’t understand how it is correct to place an '&' in front of an address (p[0]). &p[0] means address of address of first element of a which doesn't make any sense, at least to me.

正しい出力が印刷されるのはなぜですか?

2
C langは配列の境界をチェックしません。配列のメモリは連続しています。あなたが[7]を割り当てることができる理由
追加された 著者 Nandkumar Tekale,

6 答え

定義されていない動作が呼び出されました。配列の境界を越えて書くことについての推論には、少しのポイントがあります。ただしないでください。

&p[0] means address of address of first element of a[] which is not sensible

No, that's perfectly sensible. Your description perfectly describes what is going on. &p[0] is the same as p which is the same as a. When you write p[0] you are dereferencing the pointer. When you then write &p[0] you are taking the address of that variable and thus return to what you started from, p.

9
追加された
いいえ、あなたはそれを正しく持っています。セスが言ったように、* pとp [0]は同じです。そして、p + 0は確かにポインタです。
追加された 著者 David Heffernan,
それは本当にあなたのところにあるエラーです。あなたは%cがポインタを渡すことから何か意味のあるものを期待できます。 %cは文字を必要とします。しかし、Cはプラグインしているだけなので、pの値を構成するバイトの1つを取得します。
追加された 著者 David Heffernan,
@AnushaPachunuri p [0]* p と同じですので、&p [0]p と同じです。
追加された 著者 Seth Carnegie,
確かに&p [0]はどうですか?
追加された 著者 Anusha Pachunuri,
ああ、p [0]とp + 0の両方がアドレスを保持していると思った。今、私はp [0]と*(p + 0)を見てプログラムを修正すると、どちらも逆参照のようである。 )アドレスを保持しています。間違っていれば私を訂正してください!
追加された 著者 Anusha Pachunuri,
私はprintf( "%u"、p + 0)と答えています。もしprintf( "%c"、p + 0)と答えたら、私はそれを聞いています私に住所の文字表現を教えてもらえますか?それは0 0 1 0を含むボックスのようなものを印刷したからです。これは別の質問として尋ねられるのですか?それともそれは何か私がやっている珍しいですか?
追加された 著者 Anusha Pachunuri,
そうそう!それは意図的ではありませんでした。説明がありがとう
追加された 著者 Anusha Pachunuri,

a の最も有効なインデックスは 5 なので、配列境界の外に2つ書くのですが、依然としてNULLターミネータが必要です。それがうまくいったという事実はただの偶然だった。配列境界の外側に書くことは未定義の振る舞いです。それは動作するかもしれない、あなたのコンピュータをクラッシュさせるかもしれない、あなたのクレジットカードでピザを買うか、まったく違うものを買うかもしれない。あなたはそれが何をするのか分からないので、ただしないでください。

5
追加された
+1。 Cは非常に低レベルの言語であり、あなたが涙で終わることのできるたくさんのことを "許可"します。ちょうどあなたがするべきではないことを意味することができます。一度、Cさんはクレジットカードでピザを買ってから、酔っ払って帰ってきて私の場所を捨てました。私は彼を追い出しました、そして今、私はより洗練された(定義された)言語で時間を過ごすことを切望します。
追加された 著者 Ben Zotto,
:-) 説明してくれてありがとう。
追加された 著者 Anusha Pachunuri,

配列をchar [6]と宣言したとき、なぜ[7]で値を割り当てることができますか?

あなたはそれをするように言ったからです。あなたは上司です。あなたが崖から飛び降りるように言えば、それは可能性があります。

最後の要素にヌル文字を追加する必要はありませんか?

それは文字列ではなく、文字の配列です。文字列として扱う場合を除き、最後にゼロは必要ありません。 %s 指定子を printf に渡すと、文字列として扱われますので、最後にゼロを追加する必要がありますそれ以外の場合は、文字列ではない文字列を、文字列を必要とする書式指定子に渡します。

Also p=a => p holds the address of first element of char array a. I don’t understand how it is correct to place an '&' in front of an address (p[0]). &p[0] means address of address of first element of a which doesn't make any sense, at least to me.

It works like this:
p is a pointer to the first element.
&p is the address of the pointer.
p[0] is the first element in the array the pointer points to.
&p[0] is the address of the first element in the array the pointer points to.

正しい出力を印刷するのはなぜですか?

まあまあ。おそらく、実装は32ビット(4バイト)で、6バイト配列の後の2バイトでは役に立たないものはありませんでした。そこで、それを8バイトに丸めて、それが次のものが偶数の32ビット境界で開始するようにしました。とにかく、実装で何も使用していなかった2バイトを使用しました。

2
追加された
@DavidHeffernanありがとう。訂正が行われました。
追加された 著者 David Schwartz,
"あなたはそれをやるように言ったので、あなたは上司です。崖から飛び降りるように言えば、それはできます。"いいえ、それはしません。かもしれない。ではないかもしれない。それはUBです。 「文字列として扱わない限り、最後にゼロは必要ありません。」 %sでprintfを呼び出すと、文字列として扱われます。 "pは配列です"。いいえ、pはポインタです。あなたがエラーを訂正できるなら、それは良いことでしょう。
追加された 著者 David Heffernan,

配列をchar [6]と宣言したとき、なぜ[7]で値を割り当てることができますか?

CとC ++は気にしないので、配列の境界チェックはありません。

最後の要素にヌル文字を追加する必要はありませんか?

いいえ。例えばあなたが配列を宣言するとき、char a [7];コンパイラに、7バイト以上、それ以下のものを求めます。配列の外側にアクセスしようとすると、それが問題になります。

I donot understand how it is correct to mark an '&' infront of an address(marked by p[0]). '&p[0]' means address of address of first element of a[] which is not sensible right?How come it is printing correct output?

if you write p[0] you are referencing the value of the array p e.g. if int p[2] = {1,2}; then p[0] is 1 if you write &p[0] you are getting the address of p[0] which is basically the same as p + 0

2
追加された
私はそれが配列であると仮定しました、それは実装された境界チェックを持っています。私はそれが言語概念であることを知っていませんでした。
追加された 著者 Anusha Pachunuri,

It allows you to allocate a value at a[7] because you're lucky. That's undefined behaviour. See here: http://ideone.com/ntjUn

セグメンテーションフォルト!

1
追加された

I hope this helps you a little with understanding the array&pointer relationship:

a[i] == *(a+i) == *(i+a) == i[a]
0
追加された
ちょうど短いステップと私たちは5 ["abcdef"]
追加された 著者 David Heffernan,