Экспериментируя с указателями массивов в C - PullRequest
3 голосов
/ 10 апреля 2011

У меня есть массив a, значения которого я хочу изменить с помощью другой функции. Вот код, который у меня есть:

#include "stdlib.h" 
#include "stdio.h"

void myfunc(int* );

int main() {

    int *a, i;

    a = (int*) calloc(10,sizeof(int));
    myfunc(&a);

    for (i=0; i<10; i++) printf("%d\n", a[i]);

    return 0;
}

void myfunc(int* a) {

    int i;

    for (i=0; i<10; i++) *a[i] = i;
}

Очевидно, что с моим синтаксисом что-то не так, и мне было интересно, может ли кто-нибудь мне помочь

Спасибо!

Ответы [ 5 ]

3 голосов
/ 10 апреля 2011

В основной функции у вас есть указатель на целое число, a.Затем вы передаете адрес этого указателя на myfunc, но myfunc ожидает указатель на int, а не указатель на указатель на int.Вам нужно изменить свой звонок на myfunc на это:

myfunc(a);

Но у вас также есть проблема внутри myfunc.Вам не нужно разыменовывать a[i], так как это индексирует в массив a.Это (эффективно) одно и то же:

a[i]

и

*(a+i)

(я думаю, что это не 100%, потому что в C указатели и массивы не полностью совпадаютчто-то, поэтому некоторые опытные программисты на Си могут меня поправить)

Вы, вероятно, просто немного запутались из-за набора синтаксиса вокруг указателей и массивов:

&a
*a
a[i]
*(a+i)

Первый - этоадрес a, второй разыменовывается a как указатель, третий - индекс в массиве, а четвертый - разыменование a как указатель со смещением.

Вы бы хотели толькосделайте это *(a[i]), если у вас есть массив указателей, а не указатель на int.

3 голосов
/ 10 апреля 2011

вы уже объявляете «a» в качестве указателя, когда говорите, что его тип «int *».Поэтому, когда вы пытаетесь вызвать свою функцию «myfunc», вам не нужно брать адрес «a».Это сделает его указателем на указатель или "int **".Если вы хотите изменить местоположение того, куда указывает указатель, вы можете использовать это, но в вашем случае, когда вы просто хотите изменить данные, на которые он указывает, ваш myfunc объявлен нормально, и вы должны просто изменить вызов вашегоФункция от:

myfunc(&a);

до

myfunc(a);

Также внутри вашей функции переменная «a» уже является указателем, поэтому для доступа к элементу в массиве, на который она указывает, выне нужно разыменовывать это сначала.Вы должны просто использовать [i] вместо * a [i].

1 голос
/ 10 апреля 2011

Можно вызвать myfunc(a) вместо myfunc(&a), тогда внутри функции вы используете [i] напрямую.Объявляя myfunc(&a), вы передаете int **, который позволяет вам выделить массив из * внутри функции и вернуться к вызывающей стороне, чтобы использовать его.

1 голос
/ 10 апреля 2011

Вам не нужно *a[i] = i;, вы можете просто поставить a[i] = i; (и изменить вызов функции, как указал Феличе).

0 голосов
/ 10 апреля 2011

Поскольку a равно int*, &a будет int**. Таким образом, вы должны изменить свою подпись функции на void myfunc(int** a);

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...