4

C言語を初めて使用し、別の関数を使用してメイン関数の配列を変更しようとすると問題が発生します。ソリューションを確認するだけでなく、コードの何が問題になっているのか、ソリューションの説明は何なのかを完全に説明したいと思います。

OK、それで私はあまりにも多くの試行とエラー実験をしましたが、私の問題を解決するのに成功しませんでした。最終的にこれは私の現在のコードです:

#include <stdio.h>
#define MAX 20
typedef int Values[MAX];

int changeArr(Values *vals2) 
{
    *vals2[0] = 200;
    *vals2[1] = 100;
    printf("%d and ", *vals2[0]);
    printf("%d\n", *vals2[1]);
    return 0;
}   

int main (int argc, char *argv[]) 
{
    Values vals;
    changeArr(&vals);
    printf("%d and ", vals[0]);
    printf("%d\n", vals[1]);
    return 0;
}

出力は次のとおりです。

200 and 100
200 and 0

それ以外の:

200 and 100
200 and 100
4

1 に答える 1

12

バージョン1:

#include <stdio.h>
#define MAX 20
typedef int Values[MAX];

int changeArr(int vals2[]) {
    vals2[0] = 200;
    vals2[1] = 100;
    printf("%d and ", vals2[0]);
    printf("%d\n", vals2[1]);
    return 0;
}   

int main (int argc, char *argv[]) {

    Values vals;
    changeArr(vals);
    printf("%d and ", vals[0]);
    printf("%d\n", vals[1]);
    return 0;

}

配列へのポインターを渡す代わりに、配列の最初の要素へのポインターを渡します。

バージョン2:

#include <stdio.h>
#define MAX 20
typedef int Values[MAX];

int changeArr(Values *vals2) {
    (*vals2)[0] = 200;
    (*vals2)[1] = 100;
    printf("%d and ", (*vals2)[0]);
    printf("%d\n", (*vals2)[1]);
    return 0;
}   

int main (int argc, char *argv[]) {

    Values vals;
    changeArr(&vals);
    printf("%d and ", vals[0]);
    printf("%d\n", vals[1]);
    return 0;

}

括弧を使用して優先順位を補正します。

あなたのコードの問題はそれです

*vals2[1]

であるため、渡され*(vals2[1])たポインタの1単位後のポインタを逆参照します。Valuesアクセス可能なメモリが割り当てられていないため、未定義の動作です。実際には、アクセスするのと同じです

arr[1][0]

のために

int arr[2][MAX];

しかし、あなたvalsは(と同等の)だけなint arr[1][MAX];ので、範囲外にアクセスしています。しかし、何も悪いことが起こらなければ、 100*vals2[1] = 100;changeArr設定vals[MAX]mainます。ただし、重要なものを上書きする可能性があります。

int changeArr(Values *vals2)sの配列へのポインタを渡す場合は、の配列のMAX int最初のそのような配列を応答しValuesます。次に、 (ここには存在しない)vals2[1]のその配列の2番目の配列であり、その2番目の配列の最初の配列です。ポイントされたメモリブロックの最初の(そして唯一の)配列の要素を変更したいので、にアクセスしたい、または同等に。Values*vals2[1] == vals2[1][0]intvals2[0][1](*vals2)[1]

絵:

vals2                          vals2[1]
 |                               |
 v                               v
|vals[0]|vals[1]|...|vals[MAX-1]|x

changeArr、ポインタvals2は配列を指しますvalsint[MAX]これは、へのポインタであるため、 (の終わりのすぐ後ろにある)の開始後のバイトのオフセットでをvals2+1指します。、または同等に、 (存在しない)直後の配列です。int[MAX]MAX*sizeof(int)valsvalsvals2[1]*(vals2 + 1)vals

vals[1]配列内にあるをバイトvals2[0]のオフセットで変更したいので、または同等に必要です。1*sizeof(int)vals2[0][1](*vals2)[1]

于 2012-12-22T14:29:57.783 に答える