C - Ошибка передачи ссылки на массив в аргумент указателя в функции - PullRequest
2 голосов
/ 19 апреля 2020

У меня проблемы с передачей целочисленного массива в качестве ссылки и последующим изменением исходного массива.

#include <stdio.h>

// sets the 2 element of i to 5
void setToFive(int *i[10]){
    *i[2] = 5;
    printf("hello\n");
}

int main(){
    int i[10];
    setToFive(&i);
    // confirm i[2] == 5
    printf("%d\n", i[2]);
}

Компилятор жалуется на недопустимый тип

[vinessa@komputilo ch1]$ gcc test.c
    test.c: In function ‘setToFive’:
    test.c:5:5: error: invalid type argument of unary ‘*’ (have ‘int’)
        5 |     *i[2] = 5;
          |     ^~~~~
    test.c: In function ‘main’:
    test.c:11:15: warning: passing argument 1 of ‘setToFive’ from incompatible pointer type [-Wincompatible-pointer-types]
       11 |     setToFive(&i);
          |               ^~
          |               |
          |               int (*)[10]
    test.c:4:21: note: expected ‘int *’ but argument is of type ‘int (*)[10]’
        4 | void setToFive(int *i){
          |                ~~~~~^

ошибка сегментации

[vinessa@komputilo ch1]$ ./a.out
Segmentation fault (core dumped)

Стучал в голову часами, пожалуйста, помогите.

Ответы [ 2 ]

3 голосов
/ 19 апреля 2020

Вот вам

#include <stdio.h>

// sets the 2 element of i to 5
void setToFive(int *i){
    i[2] = 5;
    printf("hello\n");
}

int main(){
    int i[10];
    setToFive(i);
    printf("%d\n", i[2]);
}

Если вы хотите изменить элементы массива, просто передайте его по значению. В этом случае указатель массива неявно преобразуется в указатель на его первый элемент. Используя указатель и арифметику указателя c, вы можете изменить любой элемент массива.

Фактически в этом случае вы передаете элементы массива по ссылке косвенно через указатель на них.

Обратите внимание на то, что эти объявления функций

void setToFive(int i[100]);
void setToFive(int i[10]);
void setToFive(int i[1]);
void setToFive(int i[]);

эквивалентны и объявляют одно и то же объявление функции, которое компилятор настраивает на следующее объявление

void setToFive(int *i);

То есть в результате функция имеет дело с указателем.

Что касается выражения, используемого в качестве аргумента в этом вызове функции

setToFive(&i);

, то оно имеет тип int ( * )[10], поскольку указанный массив объявлен как

int i[10];

Это не то же самое, что тип параметра int *i[10], который, как я уже писал, корректируется компилятором для типа int **.

1 голос
/ 19 апреля 2020

Вы передаете массив указателей на целые числа, а не массив целых чисел. Вы можете просто удалить различные * объявления и операторы и просто передать в качестве аргумента простой массив (аргумент массива будет затухать до указателя):

#include <stdio.h>

// sets the 2 element of i to 5
void setToFive(int i[10])
{
    i[2] = 5;
    printf("hello\n");
}

int main()
{
    int i[10];
    setToFive(i);
    // confirm i[2] == 5
    printf("%d\n", i[2]);
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...