2

私はCに比較的精通しており、Javaでのプログラミングに慣れているため、Cは配列に関するもので少し難しいと感じています。私はまだこのケースと混同しています:

int a [];
int* a;
int *a;

Javaでは、関数で配列を返すために次のようなことをします:

int [] returnArr(int [] a){
... modify a ...
return a;
}

int [] a = {...};
int [] b = returnArr(a); ##

C、特に ## の部分で同じことを行うにはどうすればよいですか。

編集:私はこの機能を持っています:

float *normalizeValues(float *v, float maxY){

    int size = sizeof(v) / sizeof(float);
    float max = findMax(v);
    float ratio = maxY / max;
    int i;
    for(i = 0; i < size ; ++i){
        v[i] = v[i] * ratio;
    }
    return v;
}

そして、私は次のことをしています:

float vert [] = {306, 319, 360, 357, 375, 374, 387, 391, 391, 70, 82, 94, 91, 108, 114, 125, 127, 131};
int i = 0;
float *vert2;
vert2 = normalizeValues(vert, 0.7);

for(i = 0; i < sizeof(vert2) / sizeof(float); ++i){
    fprintf(stdout,": %f\n",vert2[i]);
}

そして、出力は1要素のみです。

4

5 に答える 5

1

お役に立てれば

  #include<stdio.h>

    void change(int *c)/*Pointer c now has the first location of the array a[]*/
    {
      *(c+0) = 0;/*assign values to the array by adding step-size to the first array position*/
      *(c+1) = 1;
      *(c+2) = 2;
      *(c+3) = 3;
      *(c+4) = 4;
    }

    main()
    {
      int a[5]={10,20,30,40,50}; /* Declare and Assign an array a[] of size 5.*/
      int *b = a; /*Declare and assign a Pointer to the location of the array.*/
      change(b); /*pass the pointer(which is now pointing to first position of array) to the change() function.*/
      printf("%d,%d,%d,%d,%d,",a[0],a[1],a[2],a[3],a[4]);/*Print the changed value.*/
    }

出力: 0,1,2,3,4,

Java の観点からは、ポインターは (正確ではない) オブジェクト参照に単純に似ています。

Object O;

O = New SomeClassName();

オブジェクト参照 O が SomeClassName 型の実際のオブジェクトを指しているように、C のポインターも同様です。

int *b;
b = &a;

変数 b は単に a のアドレス位置を指しています。配列の概念を深く掘り下げる:

int a[5];
int *b = a;

ここでは、Mr.*bがグループaの最初の場所、つまりa[0]を指しているように言っています。

これで、C のパワー ポインターは次のようになります。

*b means a[0]
*(b+1) means a[1]
*(b+2) means a[2]
*(b+3) means a[3]
*(b+4) means a[4]

これは、*(b+4) を変更し、a[4] を変更していることを意味します。

于 2013-04-22T03:59:12.370 に答える
1

できません。関数が返されると、スタック フレームは (通常は) 消去され、生成された配列はそれによって破壊されます。ただし、関数プロトタイプを編集して、変更する配列へのポインターを受け入れることができます。この種の関数引数は「出力パラメーター」として知られています。例:

void function func(int a, int b, int[2] to_modify)
{
  to_modify[0] = a;
  to_modify[1] = b;
}
int main()
{
   int foo[2];
   func(1, 2, foo);
   printf("Result: foo[0] = %d, foo[1] = %d\n", foo[0], foo[1]);
   return 0; 
}

これにより、「結果: foo[0] = 1, foo[1] = 2」が出力されます。

于 2013-04-22T03:51:58.800 に答える
1

編集:更新された質問に直接答えるには:配列のサイズを渡す必要があります。C には、Java のように配列のサイズを格納するメカニズムがありません。配列がグローバル変数またはローカル変数であり、動的に割り当てられていないため、コンパイラが配列のサイズを認識している場合は、sizeof() 演算子を使用できます。それ以外の場合は、サイズを個別に把握するか、配列でセンチネル値を使用する必要があります (末尾の 0.0 や NULL など)。

一般的な配列、ポインター、および引数については、以下を参照してください。

「*」構文で示される配列へのポインターを返します。

int *returnArr(int[] a) {
    // modify a...
    return a;
}

int a[] = { ... };
int *b;
b = returnArr(a);

注意すべき点がいくつかあります。

  • 非定数式 (関数呼び出しなど) を含む変数宣言で代入を行うことはできません。ただし、これは C99 で変更された可能性があります。
  • ブラケットが型の一部である Java とは異なり、変数名の後にブラケットが続きます。Java の構文はより一貫性がありますが、変数宣言の括弧内に配列サイズを指定することが多い C では意味がありません。

    int a[3] = { ... };

  • 関数が通常のポインターではなく配列を返すように指定する方法はありません。C では、配列参照はポインターに減衰します (ただし、一般的に主張されているように、ポインターと配列は同じものではありません)。つまり、配列を渡すたびに、C は配列へのポインターを渡す手段しか提供しないということです。配列全体が実際にコピーされるわけではありません。たまたま、配列の名前は配列の最初の要素へのポインターでもあります。

また、user268396 が回答で言っていることにも注意してください。新しい配列を作成して返すことを計画している場合は、配列を動的に割り当てるか、既に割り当てられている配列へのポインターを渡す必要があります (これは、とにかくやっているようです) .

于 2013-04-22T03:52:38.740 に答える
0

C では、関数内で配列のポインターのみを返すことができます。たとえば、関数で文字列 (char の配列) を返したい場合は、null で終わる文字列へのポインターを返すことができます。他の型 (int、ユーザー定義の構造体など) の配列を返したい場合は、配列を格納するためにメモリを割り当て、配列のポインターを返し、パラメーターで配列のサイズを返すことができます。例:

int *function(int *size)
{
    *size = 10;
    int *intP = (int *)malloc((*size)*sizeof(int));

    return intP;
}
于 2013-04-22T03:59:07.713 に答える