it-roy-ru.com

C передать указатель массива int в качестве параметра в функцию

Я хочу передать указатель массива B int в функцию func и иметь возможность изменить его оттуда, а затем просмотреть изменения в основной функции

#include <stdio.h>

int func(int *B[10]){

}

int main(void){

    int *B[10];

    func(&B);

    return 0;
}

приведенный выше код дает мне несколько ошибок:

In function 'main':|
warning: passing argument 1 of 'func' from incompatible pointer type [enabled by default]|
note: expected 'int **' but argument is of type 'int * (*)[10]'|

Правка: Новый код:

#include <stdio.h>

int func(int *B){
    *B[0] = 5;
}

int main(void){

    int B[10] = {NULL};
    printf("b[0] = %d\n\n", B[0]);
    func(B);
    printf("b[0] = %d\n\n", B[0]);

    return 0;
}

теперь я получаю эти ошибки:

||In function 'func':|
|4|error: invalid type argument of unary '*' (have 'int')|
||In function 'main':|
|9|warning: initialization makes integer from pointer without a cast [enabled by default]|
|9|warning: (near initialization for 'B[0]') [enabled by default]|
||=== Build finished: 1 errors, 2 warnings ===|
26
fxuser

В вашем новом коде

int func(int *B){
    *B[0] = 5;
}

B является указателем на int, поэтому B[0] является int, и вы не можете разыменовать int. Просто удалите *,

int func(int *B){
    B[0] = 5;
}

и это работает.

В инициализации

int B[10] = {NULL};

вы инициализируете int с помощью void* (NULL). Поскольку существует допустимое преобразование из void* в int, оно работает, но оно не совсем кошерное, потому что преобразование определяется реализацией и обычно указывает на ошибку программиста, поэтому компилятор предупреждает об этом.

int B[10] = {0};

это правильный способ инициализации 0 int[10].

34
Daniel Fischer

Может быть, вы пытались это сделать?

#include <stdio.h>

int func(int * B){

    /* B + OFFSET = 5 () You are pointing to the same region as B[OFFSET] */
    *(B + 2) = 5;
}

int main(void) {

    int B[10];

    func(B);

    /* Let's say you edited only 2 and you want to show it. */
    printf("b[0] = %d\n\n", B[2]);

    return 0;
}
11
Alberto Bonsanto

Если вы действительно хотите передать указатель массива, это

#include <stdio.h>

void func(int (*B)[10]){   // ptr to array of 10 ints.
        (*B)[0] = 5;   // note, *B[0] means *(B[0])
         //B[0][0] = 5;  // same, but could be misleading here; see below.
}

int main(void){

        int B[10] = {0};   // not NULL, which is for pointers.
        printf("b[0] = %d\n\n", B[0]);
        func(&B);            // &B is ptr to arry of 10 ints.
        printf("b[0] = %d\n\n", B[0]);

        return 0;
}

Но, как упоминалось в других ответах, это не так часто делать. Обычно указатель на массив передается только тогда, когда вы хотите передать двумерный массив, где он внезапно выглядит намного яснее, как показано ниже. 2D массив фактически передается как указатель на его первый ряд.

void func( int B[5][10] )  // this func is actually the same as the one above! 
{
         B[0][0] = 5;
}

int main(void){
    int Ar2D[5][10];
    func(Ar2D);   // same as func( &Ar2D[0] )
}

Параметр func может быть объявлен как int B[5][10], int B[][10], int (*B)[10], все они эквивалентны типам параметров. 

Приложение: вы можете вернуть указатель на массив из функции, но синтаксис для объявления функции очень неудобен, часть [10] типа должна идти после списка параметров:

int MyArr[5][10];
int MyRow[10];

int (*select_myarr_row( int i ))[10] { // yes, really
   return (i>=0 && i<5)? &MyArr[i] : &MyRow;
}

Обычно это делается, как показано ниже, чтобы избежать утомления глаз:

typedef int (*pa10int)[10];

pa10int select_myarr_row( int i ) {
   return (i>=0 && i<5)? &MyArr[i] : &MyRow;
}
4
greggo

В новом коде присвоение должно быть,

B[0] = 5

В func (B) вы просто передаете адрес указателя, который указывает на массив B. Вы можете изменить func () как B [i] или * (B + i). Где я - индекс массива.

В первом коде декларация гласит: 

int *B[10]

говорит, что B является массивом из 10 элементов, каждый элемент которого является указателем на int. Таким образом, B [i] является указателем на int, а * B [i] является целым числом, которое указывает на первое целое число i-й сохраненной текстовой строки. 

1
Sunil Bojanapally
main()
{
    int *arr[5];
    int i=31, j=5, k=19, l=71, m;

    arr[0]=&i;
    arr[1]=&j;
    arr[2]=&k;
    arr[3]=&l;
    arr[4]=&m;

    for(m=0; m<=4; m++)
    {
        printf("%d",*(arr[m]));
    }
    return 0;
}
0
Vaibhav Balkrishna Dhole

Используя действительно превосходный пример от Грегго, я получил это для работы в виде пузырьковой сортировки с передачей массива в качестве указателя и выполнением простой манипуляции -1.

#include<stdio.h>

void sub_one(int (*arr)[7])
{
     int i; 
     for(i=0;i<7;i++)
    {
        (*arr)[i] -= 1 ; // subtract 1 from each point
        printf("%i\n", (*arr)[i]);

    }

}   

int main()
{
    int a[]= { 180, 185, 190, 175, 200, 180, 181};
    int pos, j, i;
    int n=7;
    int temp;
    for (pos =0; pos < 7; pos ++){
        printf("\nPosition=%i Value=%i", pos, a[pos]);
    }
    for(i=1;i<=n-1;i++){
        temp=a[i];
        j=i-1;
        while((temp<a[j])&&(j>=0)) // while selected # less than a[j] and not j isn't 0
        {
            a[j+1]=a[j];    //moves element forward
            j=j-1;
        }
         a[j+1]=temp;    //insert element in proper place
    }

    printf("\nSorted list is as follows:\n");
    for(i=0;i<n;i++)
    {
        printf("%d\n",a[i]);
    }
    printf("\nmedian = %d\n", a[3]);
    sub_one(&a);

    return 0;
}

Мне нужно прочитать о том, как инкапсулировать указатели, потому что это отбросило меня.

0
G_L