web-dev-qa-db-ja.com

Cはint配列ポインタをパラメータとして関数に渡します

B int配列ポインターをfunc関数に渡し、そこから変更して、main関数の変更を表示したい

#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 ===|
27
fxuser

新しいコードでは、

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

Bintへのポインターです。したがって、B[0]intであり、intを逆参照することはできません。 *を削除するだけで、

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

そしてそれは動作します。

初期化で

int B[10] = {NULL};

an intvoid*NULL)で初期化しています。 void*からintへの有効な変換があるため、動作しますが、変換は実装定義であり、通常はプログラマーによる間違いを示すため、まったくコーシャーではありません。したがって、コンパイラーは警告しますそれについて。

int B[10] = {0};

int[10]を0で初期化する適切な方法です。

35
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

実際に配列ポインタを渡したい場合は、

_#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;
}
_

しかし、他の答えで述べたように、これを行うことはそれほど一般的ではありません。通常、配列へのポインタは、次のように2次元配列を渡すときにのみ渡されます。 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;
}
_
5
greggo

新しいコードの割り当てでは、

B[0] = 5

Func(B)では、配列Bを指しているポインターのアドレスを渡すだけです。func()でB [i]または*(B + i)として変更できます。ここで、iは配列のインデックスです。

最初のコードでは、宣言は言っています、

int *B[10]

bは10個の要素の配列であり、各要素はintへのポインタであると言います。つまり、B [i]はintポインターであり、* B [i]はi番目に保存されたテキスト行の最初の整数を指す整数です。

1
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;
}

Greggoの非常に優れた例を使用して、ポインターとして配列を渡し、単純な-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