4

我是 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
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])取消引用一个指针。Values您没有在那里分配可访问的内存,因此这是未定义的行为。在实践中,它与访问相同

arr[1][0]

int arr[2][MAX];

但你vals只是(相当于)一个int arr[1][MAX];,所以你访问越界。但是,如果没有更糟的情况发生,则*vals2[1] = 100;设置changeArrvals[MAX]100。main不过,它可能会覆盖一些重要的东西。

int changeArr(Values *vals2)您传递一个指向MAX ints 数组的指针时,分别是 .s 数组中的第一个这样的数组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

changeArr,指针vals2指向数组vals。因为它是指向 an 的指针,所以指向 aint[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 回答