はじめまして
学校でポインタの宿題が出ましたが、ポインタがまだ理解できず提出に間に合うか不安です。
どなたか説明つきで教えてください!
よろしくお願いします。
課題は、
「ソートプログラムにおいて、もとの配列を変更することなく、ソートした結果を出力するプログラムを作成せよ。(ポインタの配列を用いる)」
#include <stdio.h>
void swap(/*ここを作成*/)
{
/*ここを作成*/
}
void move(/*ここを作成*/)
{
/*ここを作成*/
}
#define NUM 10
int main(void)
{
int soten[NUM]={84,95,60,100,83,72,93,85,65,98};
int *pt[NUM];
int i,j;
for (i=0; i<NUM; i++){
/*ポインタの配列の初期値を代入*/
pt=&soten;
}
/*初期状態を出力*/
printf("original: ");
for (i=0; i<NUM; i++){
printf("%d ", soten);
}
printf("\n ");
for (i=0; i<NUM; i++){
printf("%d ", *pt);
}
printf("\n");
/*ソートする*/
for(i=NUM-1;i>=0;i--){
for (j=0;j<i;j++){
move(&pt[j],&pt[j+1]);
}
}
/*ソート終了後の状態を出力*/
printf("after sort: ");
for(i=0;i<NUM;i++){
printf("%d ", soten);
}
printf("\n ");
for(i=0;i<NUM;i++){
printf("%d ", *pt);
}
printf("\n");
return 0;
}
ポインタの宿題
Re:ポインタの宿題
すみません、1つ確認なのですが…
ポインタを使わずに配列の中身をソートして、表示する事はできますか?
もし、それが可能ならば、そのプログラムを提示してみてください。
ポインタを使わずに配列の中身をソートして、表示する事はできますか?
もし、それが可能ならば、そのプログラムを提示してみてください。
Re:ポインタの宿題
move(&pt[j],&pt[j+1]);
この部分なのですが、出題者の意図がよく分からないです…。
ポインタの勉強だとしても、ポインタのポインタを渡す必要があるのか…?(^_^;)
ひょっとして、ワザと難しく(というか、ややこしく)してるのかもしれません(-_-)
この部分なのですが、出題者の意図がよく分からないです…。
ポインタの勉強だとしても、ポインタのポインタを渡す必要があるのか…?(^_^;)
ひょっとして、ワザと難しく(というか、ややこしく)してるのかもしれません(-_-)
Re:ポインタの宿題
普通の配列のソートが、
1) soten[j] と soten[j + 1] の大小を比較する
2) 並びが反対なら、soten[j] と soten[j + 1] を入れ替える
という処理の流れですが、ポインタ経由でソートすることで、元の配列の位置は保持しようということですね。
でうので、普通のソートの上記の部分が、
1) *(pt[j]) と *(pt[j + 1]) を比較する
2) 並びが反対なら、pt[j] と pt[j + 1] を入れ替える
という流れになります。
入れ替えるものが、ポインタなので、入れ替え関数に渡すのは、ポインタのポインタである必要があります。
ということでしょう。
普通の配列のソートができていて、move() と swap() の引数の型がわかれば、普通の配列版を書き直せばいいのかなと思いますが。
1) soten[j] と soten[j + 1] の大小を比較する
2) 並びが反対なら、soten[j] と soten[j + 1] を入れ替える
という処理の流れですが、ポインタ経由でソートすることで、元の配列の位置は保持しようということですね。
でうので、普通のソートの上記の部分が、
1) *(pt[j]) と *(pt[j + 1]) を比較する
2) 並びが反対なら、pt[j] と pt[j + 1] を入れ替える
という流れになります。
入れ替えるものが、ポインタなので、入れ替え関数に渡すのは、ポインタのポインタである必要があります。
ということでしょう。
普通の配列のソートができていて、move() と swap() の引数の型がわかれば、普通の配列版を書き直せばいいのかなと思いますが。
Re:ポインタの宿題
今日、一日かけて考えましたが、ポインタ自体がまだ理解できずポインタのポインタまでたどり着けませんでした。
もう少しヒントをいただけないでしょうか?
よろしくお願いします。
もう少しヒントをいただけないでしょうか?
よろしくお願いします。
Re:ポインタの宿題
ポインタが理解できていないのか、そもそも、ソートのプログラムがわからないのかというところなのですが。
バグさんがお書きのように、「ポインタを使わない場合のソートのプログラムを示してみてください」
というところがスタートになります。
その上で、
1) soten[j] と soten[j + 1] の大小を比較する
2) 並びが反対なら、soten[j] と soten[j + 1] を入れ替える
という部分があれば、
1) *(pt[j]) と *(pt[j + 1]) を比較する
2) 並びが反対なら、pt[j] と pt[j + 1] を入れ替える
にかきなおしてみます。
というところなのですが。
※ただ、変数の型の問題があるので、このあと、もうひとつかふたつステップが必要になるかも知れませんが。
バグさんがお書きのように、「ポインタを使わない場合のソートのプログラムを示してみてください」
というところがスタートになります。
その上で、
1) soten[j] と soten[j + 1] の大小を比較する
2) 並びが反対なら、soten[j] と soten[j + 1] を入れ替える
という部分があれば、
1) *(pt[j]) と *(pt[j + 1]) を比較する
2) 並びが反対なら、pt[j] と pt[j + 1] を入れ替える
にかきなおしてみます。
というところなのですが。
※ただ、変数の型の問題があるので、このあと、もうひとつかふたつステップが必要になるかも知れませんが。
Re:ポインタの宿題
ソートについて調べてみました。
今日わかった事は、バブルソートを使っているのではないかということです。
サブ関数のひとつはこんなような感じでしょうか?
引数とかはわかりません。
void move( ){
int tmp,j;
if(pt[j]>pt[j+1){
tmp=pt[j];
pt[j]=pt[j+1];
pt[j+1]=tmp;
}
}
また、main関数の中にswap()の関数呼び出しが無いのもわかりません。
アドバイスよろしくお願いします!
今日わかった事は、バブルソートを使っているのではないかということです。
サブ関数のひとつはこんなような感じでしょうか?
引数とかはわかりません。
void move( ){
int tmp,j;
if(pt[j]>pt[j+1){
tmp=pt[j];
pt[j]=pt[j+1];
pt[j+1]=tmp;
}
}
また、main関数の中にswap()の関数呼び出しが無いのもわかりません。
アドバイスよろしくお願いします!
Re:ポインタの宿題
swap と ソートが別になっている例をみつけました。
ただ、課題のmain関数にswap()の呼び出しがありませんでした。
move()関数の中にswap()関数の呼び出しを入れるのでしょうか?
void bubble_sort(int *ptr, int n)
{
int i, j;
for(i=0; i<n-1; i++){
for(j=n-1; j>i; j--){
if(*(ptr+j-1) > *(ptr+j)){
swap((ptr+j-1), (ptr+j));
}
}
}
}
void swap(int *ptr1, int *ptr2)
{
int w;
w = *ptr1;
*ptr1 = *ptr2;
*ptr2 = w;
}
ただ、課題のmain関数にswap()の呼び出しがありませんでした。
move()関数の中にswap()関数の呼び出しを入れるのでしょうか?
void bubble_sort(int *ptr, int n)
{
int i, j;
for(i=0; i<n-1; i++){
for(j=n-1; j>i; j--){
if(*(ptr+j-1) > *(ptr+j)){
swap((ptr+j-1), (ptr+j));
}
}
}
}
void swap(int *ptr1, int *ptr2)
{
int w;
w = *ptr1;
*ptr1 = *ptr2;
*ptr2 = w;
}
Re:ポインタの宿題
>main関数の中にswap()の関数呼び出しが無いのもわかりません。
ということですが、コードを見て、そのコードの意味を理解すればそのような疑問も消えるはずです。
main関数で呼ぶのではないかという疑問をお持ちになるのはちょっとよくわかりませんけど、以下のようなプログラムが上記に出てきますよね。
tmp=pt[j];
pt[j]=pt[j+1];
pt[j+1]=tmp;
ここの処理一体何をやっています?
そしてswap関数内では何をやっています?
結局同じことをやっていますよね。
swap関数というのはその名前からわかるとおり、引数にした2つの数をいれかえる関数です。
ptr1とptr2を受け取っていますね。いったんwに変数の中身を保存していれかえています。
bubble_sort内で数値の比較をしたとき、値を交換すべきときになったらこの関数を呼び出して交換しているのです。
swap関数が無いのは、関数をよばなくてもそれと同じことをしているからです。
処理をわけたのが後に投稿されたものです。
上記プログラムではbubble_sortがmoveにあたるわけです。
swap関数はmoveから呼ぶならswap関数をmoveより上に書いてくださいね。
もし下に書くなら宣言が必要です。
コードの意味を一つ一つおって何をしているのか理解しなければプログラムは組めませんから1行ずつ何をしているのか意味を理解するようにしてみてください。
ということですが、コードを見て、そのコードの意味を理解すればそのような疑問も消えるはずです。
main関数で呼ぶのではないかという疑問をお持ちになるのはちょっとよくわかりませんけど、以下のようなプログラムが上記に出てきますよね。
tmp=pt[j];
pt[j]=pt[j+1];
pt[j+1]=tmp;
ここの処理一体何をやっています?
そしてswap関数内では何をやっています?
結局同じことをやっていますよね。
swap関数というのはその名前からわかるとおり、引数にした2つの数をいれかえる関数です。
ptr1とptr2を受け取っていますね。いったんwに変数の中身を保存していれかえています。
bubble_sort内で数値の比較をしたとき、値を交換すべきときになったらこの関数を呼び出して交換しているのです。
swap関数が無いのは、関数をよばなくてもそれと同じことをしているからです。
処理をわけたのが後に投稿されたものです。
上記プログラムではbubble_sortがmoveにあたるわけです。
swap関数はmoveから呼ぶならswap関数をmoveより上に書いてくださいね。
もし下に書くなら宣言が必要です。
コードの意味を一つ一つおって何をしているのか理解しなければプログラムは組めませんから1行ずつ何をしているのか意味を理解するようにしてみてください。