在 C 中使用数组的指针问题

Issue with pointers using arrays in C

在 C 中使用指针和数组我发现了一个奇怪的案例,我不明白它为什么会发生。

首先,我想描述一下正确的情况: 我定义了一个函数 void modifyArray(int *list),其中必须通过引用修改数组以将项目乘以 2 倍 (x2)。函数实现为:

void modifyArray(int *list, int arrLength){
    for(int i=0; i<arrLength; i++){
        *(list + i) = *(list + i) * 2; // x = x * 2
    }
}

int main(int nargs, char **args) {

    int list[] = {1,2,3,4,5};
    modifyArray(&list, 5);

    for(int i=0; i<5; i++){
        printf("%d\n", *(list + i));

    }
}

输出为:

2
4
6
8
10

现在我要解释不正确的情况:我定义了一个新的数据类型List并修改了函数以接受List而不是 int *int[] 作为第一个参数:

typedef int List[5];

void modifyArray(List *list, int arrLength){
    for(int i=0; i<arrLength; i++){
        *(list + i) = *(list + i) * 2; // x = x * 2
    }
}

修改后我的编译器构建失败,因为句子 *(list + i) = *(list + i) * 2; // x = x * 2 can't multiply bacause of the following error message:

Invalid operands to binary expression ('List' (aka 'int [5]') and 'int')

我知道我的编译器正在尝试将整个数组乘以 2,但不知道原因。

我找到的解决方案是用 *(*list + 1) 替换 *(list + 1)。我很困惑,因为在第二种情况下,当我打印 list*list 输出是一个内存地址(两者的内存地址相同)而不是 list 及其内容的内存地址*list.

你能解释为什么会这样吗?使用 int *List 定义的类型有什么区别?

list定义为int list[] = {1,2,3,4,5};时,&list是指向五个int的数组的指针。将此传递给 int * 类型的参数是不合适的,编译器应该在第一段代码中对此发出警告或错误。正确的参数是 list。虽然这是一个数组,但它会自动转换为指向其第一个元素的指针,并且该指针是 int *,这是参数的正确类型。

当参数声明为List *list时,它是一个指向数组的指针。然后,在 *(list + i) 中,加法是以这些数组为单位而不是以 int 为单位进行的。加法的结果是一个指向数组的指针,所以*(list + i) 中的*的结果是一个数组。然后乘法试图将一个数组乘以二,所以编译器会报错。

相反,将参数声明为 List list。这声明它是一个数组,但它会自动调整为指向 int 的指针。因为 C 不支持将数组作为参数传递,所以它会自动将参数声明调整为数组元素指针声明,而不是支持。

另外,不要写*(list + i)。使用 list[i]。它的意思相同,但更容易阅读。