バージョン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は配列を指しますvals。int[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]