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

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

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

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

ポインタ

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

Q&A

4回答

1651閲覧

c言語のポインタを用いた出力から入力を求める

offn

総合スコア14

C

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

ポインタ

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

0グッド

2クリップ

投稿2017/05/24 05:50

編集2017/05/24 08:29

出力結果からプログラムの?部分を埋めたいのですがどのように考えればよいのかわかりません。

#include<stdio.h> int main(void){ int ai[2]={?,?}; short *ai2 = (short *)(&ai[sizeof(ai)/sizeof(short)-2])-4; short *ai3 = (short *)((char *)((short *)(ai+2)-3)-1); int n; for(n=0;n<7;n += 2) printf("%d, %d\n",*(short *)((char *)ai2+n),n); for(n=0;n<3;n++) printf("%d, %d\n",*(ai3+n),n); }

実行して出力を
100, 0
?, 2
?, 4
511, 6
0, 0
256, 1
-100, 2
となるように?の部分を埋めたいのですがやり方がわかりません。
aiの要素をどのようにして考えて求めれば良いのでしょうか?
%pでそれぞれのアドレスを表示させて考えるのかなと思ったのですがそれだと結局aiの要素を求めていないとわからず手が付きません。

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

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

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

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

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

Chironian

2017/05/24 06:05

ai[2]の内容がなんだろうが、そのプログラムでその出力はでません。?の部分に適当に(123とか456とか)値をいれて実際にもう一度やってみて下さい。
offn

2017/05/24 08:23

aiのアドレスを求める部分は自分の確認用で足し加えていたので出力と異なるものになってしまいました;;
guest

回答4

0

こんにちは。

なるほど、なかなかハードな問題ですね。一旦具体的な値を想定するのが良いです。

short *ai2 = (short *)(&ai[sizeof(ai)/sizeof(short)-2])-4;

について、やってみます。
まず、比較的メジャーなケースで考えましょう。int型が4バイト、short型を2バイトの処理系とします。
すると、sizeof(ai)はint型2の配列のサイズのなで8、sizeof(short)は2ですね。
すると、sizeof(ai)/sizeof(short)-28/2-2=2です。
すると、ai[sizeof(ai)/sizeof(short)-2]ai[2]であることが分かります。

ここはいきなりハードですね。(初心者に出す問題としては「無し」のレベルかも)
aiは要素数が2の配列なので、ai[0]とai[1]は存在しますがai[2]は存在しません。
では、そのアドレスを計算できないかと言うと、アドレスは計算できます。
配列は必ずアドレスが連続しますから、ai[2]はメモリは割り当てられてなくてもアドレスは計算でき、ai[1]のアドレスにその要素のサイズを加えた値となります。
今、ai先頭のアドレスをxと置くとint型は4バイトですから、&ai[0]はx, &ai[1]はx+4, &ai[2]はx+8となります。

&ai[2]はx+8です。そして、(short*)へキャストして4引いてます。
x+8から、short型4つ分のバイト数を引くのでx+8-2*4=xとなります。
(なんか泣きたくなりますね。でも、勉強のためですから我慢しましょう。)
つまり、ai2に入っている値とはaiと同じ値です。

確かめてみましょう。

C

1#include<stdio.h> 2 3int main(void){ 4 int ai[2]={123,456}; 5 6 short *ai2 = (short *)(&ai[sizeof(ai)/sizeof(short)-2])-4; 7 short *ai3 = (short *)((char *)((short *)(ai+2)-3)-1); 8printf("ai=%p, ai2=%p\n", ai, ai2); 9 10 int n; 11 12 for(n=0;n<7;n += 2) 13 printf("%d, %d\n",*(short *)((char *)ai2+n),n); 14 15 for(n=0;n<3;n++) 16 printf("%d, %d\n",*(ai3+n),n); 17}

Wandboxでやってみました

txt

1ai=0x7ffdfceae780, ai2=0x7ffdfceae780 2123, 0 30, 2 4456, 4 50, 6 60, 0 7-14336, 1 81, 2

確かに同じ値になってますね。

これと同様の考え方をすれば解けるのではないかと思います。
後は頑張って下さい。(いや、なかなかハードでした。)

投稿2017/05/24 10:16

Chironian

総合スコア23272

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

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

offn

2017/05/24 12:06

回答ありがとうございます。 ポイント演算も大変分かりやすくaiとai2の先頭アドレスが同じことはわかったのですが、回答をいただいてから考えていたのですがaiの要素を求めるやり方とどのように関連付ければわかりませんでした。 よろしければ詳細を教えてくれませんでしょうか?
Chironian

2017/05/24 13:23

int型やshort 型の変数がメモリの中にどのように仕舞われているのか、習っていると思います。 それを図にしておき、各printf()文の最初の%dが、そのメモリの「どこ」を表示しているのか見当をつけましょう。回答に記載したような考え方で出来るはずです。残りは「手間」の問題だけです。
guest

0

無理です。できません。
希望している出力結果の1行目が、
printf("%p, %d\n",&ai[j],ai[j]);の出力で、
100, 0
となっています。
100はai[0]の番地、0はai[0]の値になりますが、
ai[0]が格納される番地はユーザーが決められるものではありません。

投稿2017/05/24 06:41

ttyp03

総合スコア16998

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

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

offn

2017/05/24 08:25

考えるためにいろいろプログラムを変えていたらオリジナルのものではなくなっていましたので修正しました。 よろしければ回答よろしくお願いします。
guest

0

本来は、ポインタを理解してプログラム実行せず求める課題だと思います。

答えだけ求めるなら
ポインタ演算を理解せずとも結果を代入してaiを求め表示すればいいんです。
//int n;の後

n=0;*(short *)((char *)ai2+n)=100; n=6;*(short *)((char *)ai2+n)=511; n=0;*(ai3+n)=0; n=1;*(ai3+n)=256; n=2;*(ai3+n)=-100;

を追加

//最後に表示

printf("%d,%d\n",ai[0],ai[1]);

//最初のai配列の初期値はなくてもいい

投稿2017/05/25 03:35

tmp

総合スコア277

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

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

0

for 内の最初に ai の内容を出力しています。

投稿2017/05/24 06:01

Zuishin

総合スコア28660

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

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

offn

2017/05/24 08:26

考えるためにいろいろプログラムを変えていたらオリジナルのものではなくなっていましたので修正しました。 よろしければ回答よろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問