1

私のメイン関数は、値「m」の配列として行列を生成し、行「M」の開始点へのポインターの別の配列を生成します。この行列をサブルーチンに渡して、値を変更できず、行ポインターを変更できないようにしたいと考えています。つまり、サブルーチンは行列を変更してはなりません。そのため、定数値への定数ポインターへのポインターを渡します。これはうまくいきます。予想されるエラー メッセージは、次の例で生成されます。

#include<stdio.h>
#include<stdlib.h>

void fun(double const * V, double const * const * M)
{
        V = V; // allowed but pointless
        V[0] = V[0]; // not allowed

        M = M; // allowed but pointless
        M[0] = M[0]; // not allowed
        M[0][0] = M[0][0]; // not allowed
}

int main()
{
        double *V = (double *)malloc(2*sizeof(double));
        double *m = (double *)malloc(4*sizeof(double));
        double **M = (double **)malloc(2*sizeof(double *));

        M[0] = &m[0];
        M[1] = &m[2];

        fun(V,M);

        return 0;
}

エラー メッセージ:

test.c: In function ‘fun’:
test.c:7:2: error: assignment of read-only location ‘*V’
test.c:9:2: error: assignment of read-only location ‘*M’
test.c:10:2: error: assignment of read-only location ‘**M’

これらは予想通りです。これまでのところすべて順調です。

問題は、非定数行列を渡すと、次の警告も生成されることです。オプションなしで gcc v4.5 を使用しています。

test.c: In function ‘main’:
test.c:22:2: warning: passing argument 2 of ‘fun’ from incompatible pointer type
test.c:4:6: note: expected ‘const double * const*’ but argument is of type ‘double **’

ベクトル「V」を渡しても、そのような警告は生成されないことに注意してください。

私の質問は次のとおりです。完全に変更可能な行列を、キャストせずにコンパイラの警告なしに変更できないように、サブルーチンに渡すことはできますか?

4

1 に答える 1

0

これは役立ちます:

void fun(double const * const V, double const * const * const M)
....

あなたが直面している問題はdouble const *、それが double への const ポインターではなく、へのポインターであることconst doubleです。double const *== const double *

ただし、まだ 1 つのコメントがあります。序数型のconst場合、通常、指定子は使用されません。

void fun(double const * V, double const * const * M)
.... // this allows to change V or M, but relaxes caller side

編集:ポインタは完全に作成されましたconst...そのため、ポインタが指すデータは変更できません。

于 2013-03-13T15:52:21.943 に答える