我是c语言的新手,我在尝试使用其他功能更改主函数上的数组时遇到困难。除了看到解决方案之外,我还希望得到一个完整的解释,我的代码有什么问题以及解决方案的解释是什么。
好的,所以我做了太多的试用和错误实验,但没有成功解决我的问题。最终这是我目前的代码:
#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
答案 0 :(得分:11)
版本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])
,所以它在传递的指针之后取消引用一个Values
单位的指针。您没有分配可访问的内存,因此它是未定义的行为。实际上,它与访问
arr[1][0]
表示
int arr[2][MAX];
但是你的vals
只是(相当于)int arr[1][MAX];
,所以你正在访问越界。但是,如果没有更糟糕的情况发生,*vals2[1] = 100;
changeArr
将vals[MAX]
中的main
设置为100.它可能会覆盖一些至关重要的内容。
在int changeArr(Values *vals2)
中,您传递的指针指向MAX
int
的数组,并在Values
数组中重新生成第一个此类数组。然后vals2[1]
是该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
<{1>}中的指针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)
或等效{{1} }。