質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

298閲覧

C言語 ポインタ移動による配列列挙を試みたが、配列に格納した値を正しく表示できない。

banana-and

総合スコア11

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2019/06/23 07:14

前提・実現したいこと

ポインタ移動による配列列挙を実現したい。
###C言語コード

//自作プログラム ポインタ理解用 #include <stdio.h> int main(void){ int *p,*p1; int i,n,x; int v[5]={1,2,3,4,5}; i=10; p=&i; /*ポインタ変数にiのアドレスを代入*/ printf("iのアドレスは%p,iは%dです\n",p,i); //iのアドレス,iは10 *p=15; /*ポインタ変数のアドレスを見て、その番地の値を15とする( pにiのアドレスが入ってるから*pは15になりiも15となる)*/ printf("pは%d,iは%dです\n",*p,i); //15,15 p1=v;//配列vの先頭アドレス代入 printf("vの先頭アドレスは%pです\n",p1); *p1=5; //v[0]を5に変更 for(n=1;n<6;n++){ printf("vの%d番目は%dです\n",n,(*p1)++);//v[0]の値しか表示していない,*p1は更新されている } printf("v[3]の値は%d\n",v[3]); putchar('\n'); for(n=1;n<6;n++){ //❶配列番号により配列列挙 printf("vの%d番目は%dです\n",n,*p1++);/* v[0]~v[4]を表示、                        これまでの処理でv[1]~v[4]は変更されていない*/ } printf("v[3]の値は%d\n",v[3]); putchar('\n'); for(n=1;n<6;n++){ printf("vの%d番目は%pです\n",n,p1++);/* v[0]~v[4]のアドレス表示,int型4bitごと*/ } printf("v[3]の値は%d\n",v[3]); putchar('\n'); while(*p!='\0'){ //ポインタ移動により❶のように配列列挙したい。うまくいかない printf("vの%d番目は%dです\n",x,*p1);/* v[0]~v[4]表示したいが、v[298]まで出る*/ x++; p1++; //次のアドレスを参照するために4bitずらす } return 0; } ``` ###知りたいこと ポインタが理解できなかったため、自分でプログラムを書き、配列番号を変えて配列を列挙するのではなくポインタをずらして配列を列挙しようとした際に配列の数[5]を超えて表示されてしまう。最後のfor文がいけないが、なぜいけないのかがわからないので教えて欲しいです。 ### 発生している問題・エラーメッセージ 実行結果の最後に”Segmentation fault: 11”が表示される。私はv[0]からv[4]の5つの要素を表示しようとプログラムを書いたがそれ以上に表示されてしまう上、v[0]~v[4]の値も予想外の結果になってしまった。 ### 実際の出力結果 iのアドレスは0x7ffee8762b14,iは10です pは15,iは15です vの先頭アドレスは0x7ffee8762b30です vの1番目は5です vの2番目は6です vの3番目は7です vの4番目は8です vの5番目は9です v[3]の値は4 vの1番目は10です vの2番目は2です vの3番目は3です vの4番目は4です vの5番目は5です v[3]の値は4 vの1番目は0x7ffee8762b44です vの2番目は0x7ffee8762b48です vの3番目は0x7ffee8762b4cです vの4番目は0x7ffee8762b50です vの5番目は0x7ffee8762b54です v[3]の値は4 vの1番目は1488765909です vの2番目は32767です vの3番目は1488765909です vの4番目は32767です vの5番目は0です vの6番目は0です vの7番目は1です vの8番目は0です vの9番目は-394908528です vの10番目は32766です vの11番目は0です vの12番目は0です vの13番目は-394908519です vの14番目は32766です vの15番目は-394908491です vの16番目は32766です vの17番目は-394908475です vの18番目は32766です vの19番目は-394908455です vの20番目は32766です vの21番目は-394908398です vの22番目は32766です     :     : vの296番目は2016422964です vの297番目は1650602289です vの298番目は3236146です Segmentation fault: 11

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pepperleaf

2019/06/23 08:46

コメントにある、 > //次のアドレスを参照するために4bitずらす はどういう意味でしょう? ... あ、もしかして、intのサイズ  4-byte?
banana-and

2019/06/23 09:04

4byteでした、ご指摘ありがとうございます。
guest

回答2

0

ベストアンサー

for(n=1;n<6;n++){ //❶配列番号により配列列挙

printf("vの%d番目は%dです\n",n,p1++);/ v[0]~v[4]を表示、
これまでの処理でv[1]~v[4]は変更されていない*/
}

このfor文が終わった時点で、p1の値は配列の範囲外にある、というのはいいですね?
なのに、

for(n=1;n<6;n++){

printf("vの%d番目は%pです\n",n,p1++);/* v[0]~v[4]のアドレス表示,int型4bitごと*/
}

でなおもp1をインクリメントし続けてるんだから、そりゃダメでしょ

投稿2019/06/23 07:21

y_waiwai

総合スコア87747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

banana-and

2019/06/23 08:59

回答をもとにプログラムを書き直した結果解決できました。ありがとうございます!
y_waiwai

2019/06/23 09:02

C言語で本格的なコードを書くのなら、VisualStudioとかEclipseとかのデバッグできる環境を整えましょう 1行づつ実行させて停止させ、変数の中身を見ることができるようになります
banana-and

2019/06/23 09:29

恥ずかしながらデバックという意味を知りませんでした。友人やこのサイトに尋ねる機会も減りそうです。自己解決できる方法を教えてくださり、ありがとうございます。
guest

0

C

while(*p!='\0'){ //ポインタ移動により❶のように配列列挙したい。うまくいかない
...
}

ヌル文字との比較が継続条件になり得るのはヌル終端している文字列だけであって、
一般の配列で同じように利用できるわけではありません。()

またポインタp1を操作しているのにpを参照するのもおかしいです。


註: 最終要素の値を決めておいて、番兵として利用するならば有効。

投稿2019/06/23 07:19

編集2019/06/23 07:21
LouiS0616

総合スコア35660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

banana-and

2019/06/23 09:01

ヌル文字との比較が継続条件になり得るのは文字列だけなのは知りませんでした! 説明ありがとうございます;;
LouiS0616

2019/06/23 09:06

char str[] = "moji"; は char str[] = {'m', 'o', 'j', 'i', '\0'}; と同意義ですので。 ただしうっかり char str[4] = "moji"; のようにヌル文字を受けられないように宣言した場合は除きます。
banana-and

2019/06/23 09:25

なるほど。。intの配列はヌル文字が最後に挿入されないから要素数ちょうどで宣言していいけど、文字列配列だとヌル文字が入るため要素数+1で宣言する必要があるのですね。追記ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問