はじめまして。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
栗鼠

はじめまして。

#1

投稿記事 by 栗鼠 » 11年前

下記のソースで、なぜ「Swap(x, i, j); 」の関数の処理が他の関数の配列に影響しているのかが判りません。
return や ポインタ で値を返している訳でなく、見る限りSwap関数内でのみ配列の中身を入れ替えている様に見えます。
判る方がいらっしゃいましたら、教えて頂けたら幸いです。


#include <stdio.h>

void QSort(int x[ ], int left, int right);
void Swap(int x[ ], int i, int j);
void ShowData(int x[ ], int n);
void main(void);

/* クイックソートを行う */
void QSort(int x[ ], int left, int right)
{
int i, j;
int pivot;

i = left; /* ソートする配列の一番小さい要素の添字 */
j = right; /* ソートする配列の一番大きい要素の添字 */

pivot = x[(left + right) / 2]; /* 基準値を配列の中央付近にとる */

while (1) { /* 無限ループ */

while (x < pivot) /* pivot より大きい値が */
i++; /* 出るまで i を増加させる */

while (pivot < x[j]) /* pivot より小さい値が */
j--; /* 出るまで j を減少させる */
if (i >= j) /* i >= j なら */
break; /* 無限ループから抜ける */

Swap(x, i, j); /* x と x[j]を交換 */
i++; /* 次のデータ */
j--;
}
ShowData(x, 10); /* 途中経過を表示 */

if (left < i - 1) /* 基準値の左に 2 以上要素があれば */
QSort(x, left, i - 1); /* 左の配列を Q ソートする */
if (j + 1 < right) /* 基準値の右に 2 以上要素があれば */
QSort(x, j + 1, right); /* 右の配列を Q ソートする */
}

/* 配列の要素を交換する */
void Swap(int x[ ], int i, int j)
{
int temp;

temp = x;
x = x[j];
x[j] = temp;
}


/* n 個のデータを表示する */
void ShowData(int x[ ], int n)
{
int i;

for (i = 0; i < n ; i++)
printf("%d ", x);
printf("\n");
}

void main(void)
{ /* ソートする配列 */
int x[ ] = {6, 3, 1, 7, 0, 4, 8, 5, 2, 9};
int n = 10;

printf("ソート前:\n");
ShowData(x, n);

printf("ソート中:\n");
QSort(x, 0, n - 1);

printf("ソート後:\n");
ShowData(x, n);
}

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: はじめまして。

#2

投稿記事 by softya(ソフト屋) » 11年前

中を見てませんが、配列の添字外をアクセスするとポインタと同じように他の変数を書き換える可能性が高いです。
配列添字外をアクセスしようとしたら、printfでエラー表示するように改良を加えてみてください。

ソースコードの投稿はcodeタグをご利用下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: はじめまして。

#3

投稿記事 by みけCAT » 11年前

・C言語の関数の引数の宣言において、int hoge[]とint *hogeはほぼ同じ意味になります。
・int x[10];という配列があるとき、xと書くことでxの先頭要素へのポインタを渡せます。
・Swap関数内でポインタが示す先の配列の要素を交換しているので、指されている配列の要素が直接書き変わります。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

box
記事: 2002
登録日時: 14年前

Re: はじめまして。

#4

投稿記事 by box » 11年前

参考になるかどうかは、わかりません。

コード:

#include <stdio.h>

void f(int *a)
{
    a[0] += 10;
    a[1] -= 20;
    a[2] *= 30;
    a[3] /= 40;
}

void g(int *a, int i, int j)
{
    int t;

    t = a[i], a[i] = a[j], a[j] = t;
}

void h(int a, int b)
{
    int t;

    t = a, a = b, b = t;
}

void j(int *a, int *b)
{
    int t;

    t = *a, *a = *b, *b = t;
}

int main(void)
{
    int arr[4] = { 10, 20, 30, 40 }, i;

    printf("関数fの実行前\n");
    for (i = 0; i < 4; i++) {
        printf("arr[%d]=%d\n", i, arr[i]);
    }
    f(arr);
    printf("関数fの実行後\n");
    for (i = 0; i < 4; i++) {
        printf("arr[%d]=%d\n", i, arr[i]);
    }

    printf("\n関数gの実行前\n");
    printf("arr[0]=%d, arr[2]=%d\n", arr[0], arr[2]);
    g(arr, 0, 2);
    printf("関数gの実行後\n");
    printf("arr[0]=%d, arr[2]=%d\n", arr[0], arr[2]);

    printf("\n関数hの実行前\n");
    printf("arr[0]=%d, arr[2]=%d\n", arr[0], arr[2]);
    h(arr[0], arr[2]);
    printf("関数hの実行後\n");
    printf("arr[0]=%d, arr[2]=%d\n", arr[0], arr[2]);

    printf("\n関数jの実行前\n");
    printf("arr[0]=%d, arr[2]=%d\n", arr[0], arr[2]);
    j(&arr[0], &arr[2]);
    printf("関数jの実行後\n");
    printf("arr[0]=%d, arr[2]=%d\n", arr[0], arr[2]);
    return 0;
}
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

栗鼠

Re: はじめまして。

#5

投稿記事 by 栗鼠 » 11年前

短時間の間に、ここまでお答え頂きありがとうございます。
皆様の意見を、参考にさせて頂き自分なりに検証してみます。

閉鎖

“C言語何でも質問掲示板” へ戻る