配列を逆順にするプログラムについて
配列を逆順にするプログラムについて
こんにちは!プログラミングの講義に苦戦している大学生です。
課題で、「 大きさが任意のint型の配列の名前一つとその大きさを引数にとり, 呼び出されると配列の要素の並び順を逆順に並び替える関数 a_int_rev2を定義しなさい.
さらに, 実際に値を入れた配列ひとつとその大きさを引数にしてこの関数を呼び出し, 任意の大きさの配列が逆順に並び替わることを確かめるプログラムを 課題2の後に追加し,実行して確かめなさい. 」
というのがでました。自分なりにプログラムを作ったのですが思うような結果が出ません;;
訂正をよろしくお願いします。
int
a_int_rev2(int *q, int n)
{
int k, kari_atai;
for (k = 0; k <= (n-1)/2; k++) {
kari_atai = q[k];
q[k] = q[n-k-1];
q[n-k-1] = kari_atai;
}
return ;
}
int
main(void)
{
int y[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int w;
w = a_int_rev2(y, 10);
printf("%d\n", w);
return 0;
}
課題で、「 大きさが任意のint型の配列の名前一つとその大きさを引数にとり, 呼び出されると配列の要素の並び順を逆順に並び替える関数 a_int_rev2を定義しなさい.
さらに, 実際に値を入れた配列ひとつとその大きさを引数にしてこの関数を呼び出し, 任意の大きさの配列が逆順に並び替わることを確かめるプログラムを 課題2の後に追加し,実行して確かめなさい. 」
というのがでました。自分なりにプログラムを作ったのですが思うような結果が出ません;;
訂正をよろしくお願いします。
int
a_int_rev2(int *q, int n)
{
int k, kari_atai;
for (k = 0; k <= (n-1)/2; k++) {
kari_atai = q[k];
q[k] = q[n-k-1];
q[n-k-1] = kari_atai;
}
return ;
}
int
main(void)
{
int y[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int w;
w = a_int_rev2(y, 10);
printf("%d\n", w);
return 0;
}
Re: 配列を逆順にするプログラムについて
フォーラムルール
http://dixq.net/board/board.html
をよんでない故に起きた悲劇かどうか分かりませんが
まず言えるのは、コードの書き方がまず酷いです。
メソッドの宣言は
ではなく、
です。変な改行をしないようにしましょう。
また、a_int_rev2メソッドは戻り値の指定をしているのに何の値も返していません。
[return (返したい値を直接指定するか、返したい値の格納された変数名); //返す値をちゃんと決めましょう]
http://dixq.net/board/board.html
をよんでない故に起きた悲劇かどうか分かりませんが
まず言えるのは、コードの書き方がまず酷いです。
int
a_int_rev2(int *q, int n)
{
int k, kari_atai;
for (k = 0; k <= (n-1)/2; k++) {
kari_atai = q[k];
q[k] = q[n-k-1];
q[n-k-1] = kari_atai;
}
return ;
}
int
main(void)
{
int y[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int w;
w = a_int_rev2(y, 10);
printf("%d\n", w);
return 0;
}
また、a_int_rev2メソッドは戻り値の指定をしているのに何の値も返していません。
[return (返したい値を直接指定するか、返したい値の格納された変数名); //返す値をちゃんと決めましょう]
Re: 配列を逆順にするプログラムについて
コードの書き方はおっしゃるとおりの書き方が正しいと思っております。
ただ学校の先生の指導上、そのように書けといわれておりまして;;
以後気をつけたいと思います。
戻り値のところはqに返した際にならなかったので消していました。
ご指摘ありがとうございます。
ただ学校の先生の指導上、そのように書けといわれておりまして;;
以後気をつけたいと思います。
戻り値のところはqに返した際にならなかったので消していました。
ご指摘ありがとうございます。
Re: 配列を逆順にするプログラムについて
コード通ったんで説明します
入れ替えの部分には問題ありませんでしたが、ポインタ引数で直接し入れたものをこねくり回すことはあまり感心しません。
大体は関数内に同じ型の物を用意してそっちにコピーをし、コピーしたもので演算を行い、(返り値)で結果を返します。
万が一演算に失敗すると引数の値が書き換わってしまうので大きいプログラムの場合(死ぬほど辛い)デバッグがまっています。(原因特定がややこしくなる)
詳しくはこのサイトを参考にしてください
http://sealsoft.jp/ptr_and_ref.html
#include<stdio.h> //printf使うならstdio.hを”インクルード”しましょう(http://www9.plala.or.jp/sgwr-t/c/sec05.html)
int a_int_rev2(int *q, int n)
{
int k, kari_atai;
//問題無し。だが、引数をバックアップもなしに直接こねくり回すことは感心できない
for (k = 0; k <= (n-1)/2; k++) {
kari_atai = q[k];
q[k] = q[n-k-1];
q[n-k-1] = kari_atai;
}
//戻り値を指定したのなら(ちゃんと値を)返しましょう
return kari_atai;
}
int main(void)
{
int y[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int w;
w = a_int_rev2(y, 10);
printf("%d\n",w); //標準入出力をつかうなら#include<stdio.h>
for(int i=0;i<10;i++){
//ちゃんと配列の中身が入れ替わったか確認の為のprintf
printf("%d",y[i]);
}
return 0;
大体は関数内に同じ型の物を用意してそっちにコピーをし、コピーしたもので演算を行い、(返り値)で結果を返します。
万が一演算に失敗すると引数の値が書き換わってしまうので大きいプログラムの場合(死ぬほど辛い)デバッグがまっています。(原因特定がややこしくなる)
詳しくはこのサイトを参考にしてください
http://sealsoft.jp/ptr_and_ref.html
Re: 配列を逆順にするプログラムについて
戻り値の型の後に改行をするスタイルも存在するので間違いではありません。LL さんが書きました:フォーラムルール
http://dixq.net/board/board.html
をよんでない故に起きた悲劇かどうか分かりませんが
まず言えるのは、コードの書き方がまず酷いです。メソッドの宣言は ではなく、 です。変な改行をしないようにしましょう。int a_int_rev2(int *q, int n) { int k, kari_atai; for (k = 0; k <= (n-1)/2; k++) { kari_atai = q[k]; q[k] = q[n-k-1]; q[n-k-1] = kari_atai; } return ; } int main(void) { int y[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int w; w = a_int_rev2(y, 10); printf("%d\n", w); return 0; }
このスタイルはIDEではメリットが少ないですが、Emacs系のエディタでは関数名をコピペするときにキー操作が少なくて済むメリットがあります。
https://github.com/mruby/mruby/blob/master/src/compar.c
http://git.savannah.gnu.org/cgit/emacs. ... c/buffer.c
Re: 配列を逆順にするプログラムについて
書いている間に返信が付いていますが,せっかく書いたので投稿してしまいます。
プログラムは書いたとおりに動くのですから,「思うような結果」は書かないと伝わらないです。
で,a_int_rev2で逆順にしたあと,それを確認するコードがないです。
a_int_rev2のコードは引数qが指す配列の要素を逆順に並び替えるものですから,
a_int_rev2の呼び出し前後で,yの各要素の値を出力すれば,「逆順に並び替わること」は確かめられます。
この関数定義のスタイルは,GNU Coding Standardsに則った,通常のスタイルだと思います。
「思うような結果」と,「実際の結果」を書いてください。Y.N さんが書きました:さらに, 実際に値を入れた配列ひとつとその大きさを引数にしてこの関数を呼び出し, 任意の大きさの配列が逆順に並び替わることを確かめるプログラムを 課題2の後に追加し,実行して確かめなさい. 」
というのがでました。自分なりにプログラムを作ったのですが思うような結果が出ません;;
プログラムは書いたとおりに動くのですから,「思うような結果」は書かないと伝わらないです。
で,a_int_rev2で逆順にしたあと,それを確認するコードがないです。
a_int_rev2のコードは引数qが指す配列の要素を逆順に並び替えるものですから,
a_int_rev2の呼び出し前後で,yの各要素の値を出力すれば,「逆順に並び替わること」は確かめられます。
オフトピック
「任意の大きさの配列が」は無茶な問題ですね。
語釈の問題でもありますが,任意の,というのはどんな値でも受け入れることを意味するので,
現実的に確認のしようがない大きさの配列についても調べる必要が出て来ます。
往々にして,そういう値においてエラーが出るのですが……。
語釈の問題でもありますが,任意の,というのはどんな値でも受け入れることを意味するので,
現実的に確認のしようがない大きさの配列についても調べる必要が出て来ます。
往々にして,そういう値においてエラーが出るのですが……。
何が問題なのでしょうか。
この関数定義のスタイルは,GNU Coding Standardsに則った,通常のスタイルだと思います。
オフトピック
私はこのスタイルが好きではないので使わないですが。
Re: 配列を逆順にするプログラムについて
ご指摘がありましたようにこのようにしてコンパイルしたのですが、出力結果が
4
9876543210
となりました。
なので、
このように書き直したら、9876543210となりました。
ちゃんと逆順になったのでよかったのですが、これではwがなぜ4になってしまったのかがわかりません。
そのところ教えてもらえないでしょうか;;?
4
9876543210
となりました。
なので、
このように書き直したら、9876543210となりました。
ちゃんと逆順になったのでよかったのですが、これではwがなぜ4になってしまったのかがわかりません。
そのところ教えてもらえないでしょうか;;?
Re: 配列を逆順にするプログラムについて
>return kari_atai;
これを返すことに何の意味があるのですか?
>ちゃんと逆順になったのでよかったのですが、これではwがなぜ4になってしまったのかがわかりません。
あなたが実行したコードでは,関数 a_int_rev2() は何をreturnする形になっているのですか?
(特段返すべき情報が無いのであれば,戻り値無しな関数にしてはいかがでしょう?)
あと,現状の出力結果だと
逆順になっているかどうかは コードと実行結果 の両方を見ないとわからないので,
逆にする前の(元の)内容も表示すると良いように思います.
これを返すことに何の意味があるのですか?
オフトピック
>ポインタ引数で直接し入れたものをこねくり回すことはあまり感心しません。
一般論として(?)そういう考え方はあるでしょうけど
この内容が講義の課題とされている背景状況というかを考えると,この点を突っ込むのはどうかな…と.
一般論として(?)そういう考え方はあるでしょうけど
この内容が講義の課題とされている背景状況というかを考えると,この点を突っ込むのはどうかな…と.
>ちゃんと逆順になったのでよかったのですが、これではwがなぜ4になってしまったのかがわかりません。
あなたが実行したコードでは,関数 a_int_rev2() は何をreturnする形になっているのですか?
(特段返すべき情報が無いのであれば,戻り値無しな関数にしてはいかがでしょう?)
あと,現状の出力結果だと
逆順になっているかどうかは コードと実行結果 の両方を見ないとわからないので,
逆にする前の(元の)内容も表示すると良いように思います.
Re: 配列を逆順にするプログラムについて
これに関してですが、答えは単純で、a_int_rev2メソッドのkari_ataiを返り値として返したからです。Y.N さんが書きました: ご指摘がありましたようにこのようにしてコンパイルしたのですが、出力結果が
4
9876543210
となりました。
なので、
このように書き直したら、9876543210となりました。
ちゃんと逆順になったのでよかったのですが、これではwがなぜ4になってしまったのかがわかりません。
そのところ教えてもらえないでしょうか;;?
この部分に関してはY.Nさん本人が考えて書いたであろう部分なので詳細は省きます。
最初にプログラムを提示されたとき、a_int_rev2メソッドの返り値が不明だった為にとりあえずkari_ataiを返り値として返したそれだけの理由です。
Re: 配列を逆順にするプログラムについて
YuOさんへ
私が考えていた関数a_int_rev2()は、y[]の中の配列を変えるだけのプログラムにしていたので戻り値は関係ないとは思っていました。
指摘を受けましたので、実際にreturn kari_atai;の部分を消してみて実行してみたら、ちゃんと「9876543210」となりました。
ありがうございます。
私が考えていた関数a_int_rev2()は、y[]の中の配列を変えるだけのプログラムにしていたので戻り値は関係ないとは思っていました。
指摘を受けましたので、実際にreturn kari_atai;の部分を消してみて実行してみたら、ちゃんと「9876543210」となりました。
ありがうございます。
Re: 配列を逆順にするプログラムについて
最初に提示されていたプログラムではint型の変数wの代入にint型の戻り値を返す関数a_int_rev2があったのでY.N さんが書きました:YuOさんへ
私が考えていた関数a_int_rev2()は、y[]の中の配列を変えるだけのプログラムにしていたので戻り値は関係ないとは思っていました。
指摘を受けましたので、実際にreturn kari_atai;の部分を消してみて実行してみたら、ちゃんと「9876543210」となりました。
ありがうございます。
これは何か理由があるだろうと思って変な値を返すように書いてしまいました。
これらの行為によって無駄な混乱を起こしてしまって申し訳ございません。
ですがされていたプログラムでは のコードが記載されていましたがこれはただのミスでしょうか?
Re: 配列を逆順にするプログラムについて
LLさんへ
改めてプログラムを見直していたら、LLさんのおっしゃる通り私のミスでした。
for文でy[]の要素を入れ替えた後に、kari_ataiが4になっているのを考えていませんでした。
なので要素の持たない整数型wに関数a_int_rev2()で入れ替えたyを代入しても「9876543210」とならずに、
kari_ataiの4が代入されることを見落としていました。
ご指摘ありがとうございます。
YuOさんとLLさんへ
たくさんのご指摘ありがとうございました!(^^)
改めてプログラムを見直していたら、LLさんのおっしゃる通り私のミスでした。
for文でy[]の要素を入れ替えた後に、kari_ataiが4になっているのを考えていませんでした。
なので要素の持たない整数型wに関数a_int_rev2()で入れ替えたyを代入しても「9876543210」とならずに、
kari_ataiの4が代入されることを見落としていました。
ご指摘ありがとうございます。
YuOさんとLLさんへ
たくさんのご指摘ありがとうございました!(^^)
Re: 配列を逆順にするプログラムについて
解決になっていますが、よく考えてみましたか?
n が 2 のとき、q[0] と q[[1] を交換しますが、
n が 3 のとき、q[0] と q[2] を交換し、さらに q[1] と q[1] を交換しますよ。
無駄ですね。次のように書いたほうがよいでしょう。
私なら、次のように書くでしょう。
でも、コンパイラによってはこっちの方が遅いコードが生成されたりするようで、
なかかな思うようにはいきません。
n が 2 のとき、q[0] と q[[1] を交換しますが、
n が 3 のとき、q[0] と q[2] を交換し、さらに q[1] と q[1] を交換しますよ。
無駄ですね。次のように書いたほうがよいでしょう。
void a_int_rev2(int *q, int n)
{
int k, kari_atai;
for (k = 0; k < n/2; k++) {
kari_atai = q[k];
q[k] = q[n-k-1];
q[n-k-1] = kari_atai;
}
}
私なら、次のように書くでしょう。
void a_int_rev2(int *q, int n)
{
int k, kari_atai;
for (k = 0; k < --n; k++) {
kari_atai = q[k];
q[k] = q[n];
q[n] = kari_atai;
}
}
でも、コンパイラによってはこっちの方が遅いコードが生成されたりするようで、
なかかな思うようにはいきません。
Re: 配列を逆順にするプログラムについて
YuO さんが書きました:何が問題なのでしょうか。
この関数定義のスタイルは,GNU Coding Standardsに則った,通常のスタイルだと思います。オフトピック私はこのスタイルが好きではないので使わないですが。
蛇足だとは思いますが、C++はフリーフォーマットなので、例えば と書いても文法上「正しい」です。LL さんが書きました:YuOさんへ。
申し訳ございません。そういう記述の方法もあることを知らなかったという己の無知の結果です。
あと、私個人が過剰なまでに改行して行数を増やす書き方を好まないという主観も入ってしまいました。
もちろん普通はこんな書き方はしないと思いますが。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)