バージョン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]
int
vals2[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)
vals
vals
vals2[1]
*(vals2 + 1)
vals
vals[1]
配列内にあるをバイトvals2[0]
のオフセットで変更したいので、または同等に必要です。1*sizeof(int)
vals2[0][1]
(*vals2)[1]